🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
8.7 KiB

  1. #include "config.h"
  2. #include "al/eax_eax_call.h"
  3. #include "al/eax_exception.h"
  4. namespace {
  5. constexpr auto deferred_flag = 0x80000000U;
  6. class EaxEaxCallException :
  7. public EaxException
  8. {
  9. public:
  10. explicit EaxEaxCallException(
  11. const char* message)
  12. :
  13. EaxException{"EAX_EAX_CALL", message}
  14. {
  15. }
  16. }; // EaxEaxCallException
  17. } // namespace
  18. EaxEaxCall::EaxEaxCall(
  19. bool is_get,
  20. const GUID& property_set_guid,
  21. ALuint property_id,
  22. ALuint property_source_id,
  23. ALvoid* property_buffer,
  24. ALuint property_size)
  25. : is_get_{is_get}, version_{0}, property_set_id_{EaxEaxCallPropertySetId::none}
  26. , property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
  27. , property_buffer_{property_buffer}, property_size_{property_size}
  28. {
  29. if (false)
  30. {
  31. }
  32. else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
  33. {
  34. version_ = 4;
  35. property_set_id_ = EaxEaxCallPropertySetId::context;
  36. }
  37. else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
  38. {
  39. version_ = 5;
  40. property_set_id_ = EaxEaxCallPropertySetId::context;
  41. }
  42. else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
  43. {
  44. version_ = 2;
  45. fx_slot_index_ = 0u;
  46. property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
  47. property_id_ = convert_eax_v2_0_listener_property_id(property_id_);
  48. }
  49. else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
  50. {
  51. version_ = 3;
  52. fx_slot_index_ = 0u;
  53. property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
  54. }
  55. else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
  56. {
  57. version_ = 4;
  58. fx_slot_index_ = 0u;
  59. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  60. }
  61. else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
  62. {
  63. version_ = 5;
  64. fx_slot_index_ = 0u;
  65. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  66. }
  67. else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
  68. {
  69. version_ = 4;
  70. fx_slot_index_ = 1u;
  71. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  72. }
  73. else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
  74. {
  75. version_ = 5;
  76. fx_slot_index_ = 1u;
  77. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  78. }
  79. else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
  80. {
  81. version_ = 4;
  82. fx_slot_index_ = 2u;
  83. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  84. }
  85. else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
  86. {
  87. version_ = 5;
  88. fx_slot_index_ = 2u;
  89. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  90. }
  91. else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
  92. {
  93. version_ = 4;
  94. fx_slot_index_ = 3u;
  95. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  96. }
  97. else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
  98. {
  99. version_ = 5;
  100. fx_slot_index_ = 3u;
  101. property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
  102. }
  103. else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
  104. {
  105. version_ = 2;
  106. property_set_id_ = EaxEaxCallPropertySetId::source;
  107. property_id_ = convert_eax_v2_0_buffer_property_id(property_id_);
  108. }
  109. else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
  110. {
  111. version_ = 3;
  112. property_set_id_ = EaxEaxCallPropertySetId::source;
  113. }
  114. else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
  115. {
  116. version_ = 4;
  117. property_set_id_ = EaxEaxCallPropertySetId::source;
  118. }
  119. else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
  120. {
  121. version_ = 5;
  122. property_set_id_ = EaxEaxCallPropertySetId::source;
  123. }
  124. else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
  125. {
  126. version_ = 1;
  127. fx_slot_index_ = 0u;
  128. property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
  129. }
  130. else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
  131. {
  132. version_ = 1;
  133. property_set_id_ = EaxEaxCallPropertySetId::source;
  134. }
  135. else
  136. {
  137. fail("Unsupported property set id.");
  138. }
  139. if (version_ < 1 || version_ > 5)
  140. {
  141. fail("EAX version out of range.");
  142. }
  143. if(!(property_id&deferred_flag))
  144. {
  145. if(property_set_id_ != EaxEaxCallPropertySetId::fx_slot && property_id_ != 0)
  146. {
  147. if (!property_buffer)
  148. {
  149. fail("Null property buffer.");
  150. }
  151. if (property_size == 0)
  152. {
  153. fail("Empty property.");
  154. }
  155. }
  156. }
  157. if(property_set_id_ == EaxEaxCallPropertySetId::source && property_source_id_ == 0)
  158. {
  159. fail("Null AL source id.");
  160. }
  161. if (property_set_id_ == EaxEaxCallPropertySetId::fx_slot)
  162. {
  163. if (property_id_ < EAXFXSLOT_NONE)
  164. {
  165. property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
  166. }
  167. }
  168. }
  169. [[noreturn]]
  170. void EaxEaxCall::fail(
  171. const char* message)
  172. {
  173. throw EaxEaxCallException{message};
  174. }
  175. ALuint EaxEaxCall::convert_eax_v2_0_listener_property_id(
  176. ALuint property_id)
  177. {
  178. switch (property_id)
  179. {
  180. case DSPROPERTY_EAX20LISTENER_NONE:
  181. return EAXREVERB_NONE;
  182. case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
  183. return EAXREVERB_ALLPARAMETERS;
  184. case DSPROPERTY_EAX20LISTENER_ROOM:
  185. return EAXREVERB_ROOM;
  186. case DSPROPERTY_EAX20LISTENER_ROOMHF:
  187. return EAXREVERB_ROOMHF;
  188. case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
  189. return EAXREVERB_ROOMROLLOFFFACTOR;
  190. case DSPROPERTY_EAX20LISTENER_DECAYTIME:
  191. return EAXREVERB_DECAYTIME;
  192. case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
  193. return EAXREVERB_DECAYHFRATIO;
  194. case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
  195. return EAXREVERB_REFLECTIONS;
  196. case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
  197. return EAXREVERB_REFLECTIONSDELAY;
  198. case DSPROPERTY_EAX20LISTENER_REVERB:
  199. return EAXREVERB_REVERB;
  200. case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
  201. return EAXREVERB_REVERBDELAY;
  202. case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
  203. return EAXREVERB_ENVIRONMENT;
  204. case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
  205. return EAXREVERB_ENVIRONMENTSIZE;
  206. case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
  207. return EAXREVERB_ENVIRONMENTDIFFUSION;
  208. case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
  209. return EAXREVERB_AIRABSORPTIONHF;
  210. case DSPROPERTY_EAX20LISTENER_FLAGS:
  211. return EAXREVERB_FLAGS;
  212. default:
  213. fail("Unsupported EAX 2.0 listener property id.");
  214. }
  215. }
  216. ALuint EaxEaxCall::convert_eax_v2_0_buffer_property_id(
  217. ALuint property_id)
  218. {
  219. switch (property_id)
  220. {
  221. case DSPROPERTY_EAX20BUFFER_NONE:
  222. return EAXSOURCE_NONE;
  223. case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
  224. return EAXSOURCE_ALLPARAMETERS;
  225. case DSPROPERTY_EAX20BUFFER_DIRECT:
  226. return EAXSOURCE_DIRECT;
  227. case DSPROPERTY_EAX20BUFFER_DIRECTHF:
  228. return EAXSOURCE_DIRECTHF;
  229. case DSPROPERTY_EAX20BUFFER_ROOM:
  230. return EAXSOURCE_ROOM;
  231. case DSPROPERTY_EAX20BUFFER_ROOMHF:
  232. return EAXSOURCE_ROOMHF;
  233. case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
  234. return EAXSOURCE_ROOMROLLOFFFACTOR;
  235. case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
  236. return EAXSOURCE_OBSTRUCTION;
  237. case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
  238. return EAXSOURCE_OBSTRUCTIONLFRATIO;
  239. case DSPROPERTY_EAX20BUFFER_OCCLUSION:
  240. return EAXSOURCE_OCCLUSION;
  241. case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
  242. return EAXSOURCE_OCCLUSIONLFRATIO;
  243. case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
  244. return EAXSOURCE_OCCLUSIONROOMRATIO;
  245. case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
  246. return EAXSOURCE_OUTSIDEVOLUMEHF;
  247. case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
  248. return EAXSOURCE_AIRABSORPTIONFACTOR;
  249. case DSPROPERTY_EAX20BUFFER_FLAGS:
  250. return EAXSOURCE_FLAGS;
  251. default:
  252. fail("Unsupported EAX 2.0 buffer property id.");
  253. }
  254. }
  255. EaxEaxCall create_eax_call(
  256. bool is_get,
  257. const GUID* property_set_id,
  258. ALuint property_id,
  259. ALuint property_source_id,
  260. ALvoid* property_buffer,
  261. ALuint property_size)
  262. {
  263. if(!property_set_id)
  264. throw EaxEaxCallException{"Null property set ID."};
  265. return EaxEaxCall{
  266. is_get,
  267. *property_set_id,
  268. property_id,
  269. property_source_id,
  270. property_buffer,
  271. property_size
  272. };
  273. }