🛠️🐜 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.

105 lines
3.2 KiB

  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2000 by authors.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <csignal>
  22. #include <cstdarg>
  23. #include <cstdio>
  24. #ifdef HAVE_WINDOWS_H
  25. #define WIN32_LEAN_AND_MEAN
  26. #include <windows.h>
  27. #endif
  28. #include "alMain.h"
  29. #include "alcontext.h"
  30. #include "alError.h"
  31. #include "alexcpt.h"
  32. ALboolean TrapALError = AL_FALSE;
  33. void alSetError(ALCcontext *context, ALenum errorCode, const char *msg, ...)
  34. {
  35. auto message = al::vector<char>(256);
  36. va_list args, args2;
  37. va_start(args, msg);
  38. va_copy(args2, args);
  39. int msglen{std::vsnprintf(message.data(), message.size(), msg, args)};
  40. if(msglen >= 0 && static_cast<size_t>(msglen) >= message.size())
  41. {
  42. message.resize(static_cast<size_t>(msglen) + 1u);
  43. msglen = std::vsnprintf(message.data(), message.size(), msg, args2);
  44. }
  45. va_end(args2);
  46. va_end(args);
  47. if(msglen >= 0) msg = message.data();
  48. else msg = "<internal error constructing message>";
  49. msglen = static_cast<int>(strlen(msg));
  50. WARN("Error generated on context %p, code 0x%04x, \"%s\"\n", context, errorCode, msg);
  51. if(TrapALError)
  52. {
  53. #ifdef _WIN32
  54. /* DebugBreak will cause an exception if there is no debugger */
  55. if(IsDebuggerPresent())
  56. DebugBreak();
  57. #elif defined(SIGTRAP)
  58. raise(SIGTRAP);
  59. #endif
  60. }
  61. ALenum curerr{AL_NO_ERROR};
  62. context->LastError.compare_exchange_strong(curerr, errorCode);
  63. if((context->EnabledEvts.load(std::memory_order_relaxed)&EventType_Error))
  64. {
  65. std::lock_guard<std::mutex> _{context->EventCbLock};
  66. ALbitfieldSOFT enabledevts{context->EnabledEvts.load(std::memory_order_relaxed)};
  67. if((enabledevts&EventType_Error) && context->EventCb)
  68. (*context->EventCb)(AL_EVENT_TYPE_ERROR_SOFT, 0, errorCode, msglen, msg,
  69. context->EventParam);
  70. }
  71. }
  72. AL_API ALenum AL_APIENTRY alGetError(void)
  73. START_API_FUNC
  74. {
  75. ContextRef context{GetContextRef()};
  76. if(UNLIKELY(!context))
  77. {
  78. constexpr ALenum deferror{AL_INVALID_OPERATION};
  79. WARN("Querying error state on null context (implicitly 0x%04x)\n", deferror);
  80. if(TrapALError)
  81. {
  82. #ifdef _WIN32
  83. if(IsDebuggerPresent())
  84. DebugBreak();
  85. #elif defined(SIGTRAP)
  86. raise(SIGTRAP);
  87. #endif
  88. }
  89. return deferror;
  90. }
  91. return context->LastError.exchange(AL_NO_ERROR);
  92. }
  93. END_API_FUNC