SDL.cxx 2.6 KB

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