SDL.cxx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "SDL.hxx"
  2. #include <cassert>
  3. #include <sstream>
  4. #include <SDL_image.h>
  5. #include <SDL_ttf.h>
  6. namespace {
  7. std::string build_error_message(std::string_view const message, std::source_location const location)
  8. {
  9. std::ostringstream strm;
  10. strm << location.file_name() << ":" << location.line() << ":" << location.column();
  11. strm << " - ";
  12. strm << message << " (" << SDL_GetError() << ")";
  13. return strm.str();
  14. }
  15. }
  16. SDLError::SDLError(std::string_view const message, std::source_location const location)
  17. :std::runtime_error{::build_error_message(message, location)}
  18. {
  19. }
  20. SDL* SDL::instance_ = nullptr;
  21. SDL::SDL(std::uint32_t const flags)
  22. {
  23. assert(instance_==nullptr);
  24. if (SDL_Init(flags)!=0) {
  25. throw SDLError{"Failed to initialize SDL."};
  26. }
  27. SDL_Log("Initialized SDL successfully.");
  28. auto const img_flags = IMG_INIT_PNG | IMG_INIT_JPG;
  29. if (IMG_Init(img_flags)!=img_flags) {
  30. throw SDLError{"Failed to initialize SDL_image."};
  31. }
  32. SDL_Log("Initialized SDL_image successfully.");
  33. if (TTF_Init()!=0) {
  34. throw SDLError{"Failed to initialize SDL_ttf."};
  35. }
  36. SDL_Log("Initialized SDL_ttf successfully.");
  37. auto const num_joysticks = SDL_NumJoysticks();
  38. for (int n = 0; n<num_joysticks; ++n) {
  39. add_controller(n);
  40. }
  41. instance_ = this;
  42. }
  43. SDL::~SDL() noexcept
  44. {
  45. assert(instance_!=nullptr);
  46. for (auto const controller: controllers_) {
  47. SDL_Log("Closing controller %s.", SDL_GameControllerName(controller));
  48. SDL_GameControllerClose(controller);
  49. }
  50. TTF_Quit();
  51. SDL_Log("Shut down SDL_ttf successfully.");
  52. IMG_Quit();
  53. SDL_Log("Shut down SDL_image successfully.");
  54. SDL_Quit();
  55. SDL_Log("Shut down SDL successfully.");
  56. instance_ = nullptr;
  57. }
  58. SDL& SDL::instance() noexcept
  59. {
  60. assert(instance_!=nullptr);
  61. return *instance_;
  62. }
  63. SDL& SDL::require(std::uint32_t const flags) noexcept
  64. {
  65. assert((SDL_WasInit(flags) | SDL_INIT_NOPARACHUTE)==(flags | SDL_INIT_NOPARACHUTE));
  66. return instance();
  67. }
  68. void SDL::add_controller(int const which)
  69. {
  70. controllers_.push_back(SDL_GameControllerOpen(which));
  71. SDL_Log("Opened controller %s.", SDL_GameControllerNameForIndex(which));
  72. }
  73. void SDL::remove_controller(int which)
  74. {
  75. auto const controller = SDL_GameControllerFromInstanceID(which);
  76. SDL_Log("Closing controller %s.", SDL_GameControllerName(controller));
  77. SDL_GameControllerClose(controller);
  78. auto const it = std::find(controllers_.begin(), controllers_.end(), controller);
  79. if (it!=controllers_.end()) {
  80. controllers_.erase(it);
  81. }
  82. }
  83. std::vector<SDL_GameController*> const& SDL::get_controllers() const
  84. {
  85. return controllers_;
  86. }