os.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "os.hpp"
  2. #include <SDL3/SDL.h>
  3. #include <SDL3/SDL_oldnames.h>
  4. #include <SDL3/SDL_video.h>
  5. #include <imgui.h>
  6. #include <imgui_impl_sdl3.h>
  7. #include <imgui_impl_sdlrenderer3.h>
  8. #include <filesystem>
  9. #include <locale>
  10. #include <string>
  11. namespace saura {
  12. OS::OS() {
  13. root_window_ctx = std::make_unique<Window_Context>();
  14. root_window_ctx->title = "(Saura Studios) [Dev]";
  15. root_window_ctx->w = 1280;
  16. root_window_ctx->h = 720;
  17. std::locale::global(std::locale("en_US.UTF-8"));
  18. if (!SDL_Init(SDL_INIT_VIDEO)) {
  19. throw std::runtime_error("Failed SDL_Init!");
  20. }
  21. SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
  22. root_window_ctx->handle =
  23. SDL_CreateWindow(root_window_ctx->title.c_str(), root_window_ctx->w,
  24. root_window_ctx->h, window_flags);
  25. if (root_window_ctx->handle == nullptr) {
  26. throw std::runtime_error("Failed SDL_CreateWindow!");
  27. }
  28. root_window_ctx->renderer =
  29. SDL_CreateRenderer(root_window_ctx->handle, nullptr);
  30. if (root_window_ctx->renderer == nullptr) {
  31. throw std::runtime_error("Failed SDL_CreateRenderer!");
  32. }
  33. SDL_SetRenderVSync(root_window_ctx->renderer, SDL_RENDERER_VSYNC_DISABLED);
  34. SDL_SetWindowPosition(root_window_ctx->handle, SDL_WINDOWPOS_CENTERED,
  35. SDL_WINDOWPOS_CENTERED);
  36. SDL_ShowWindow(root_window_ctx->handle);
  37. // Setup imgui
  38. IMGUI_CHECKVERSION();
  39. ImGui::CreateContext();
  40. ImGuiIO &io = ImGui::GetIO();
  41. (void)io;
  42. io.ConfigFlags |=
  43. ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
  44. io.ConfigFlags |=
  45. ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
  46. // Setup Dear ImGui style
  47. ImGui::StyleColorsDark();
  48. // Setup Platform/Renderer backends
  49. ImGui_ImplSDL3_InitForSDLRenderer(root_window_ctx->handle,
  50. root_window_ctx->renderer);
  51. ImGui_ImplSDLRenderer3_Init(root_window_ctx->renderer);
  52. }
  53. OS::~OS() {
  54. ImGui_ImplSDLRenderer3_Shutdown();
  55. ImGui_ImplSDL3_Shutdown();
  56. ImGui::DestroyContext();
  57. SDL_DestroyRenderer(root_window_ctx->renderer);
  58. SDL_DestroyWindow(root_window_ctx->handle);
  59. SDL_Quit();
  60. }
  61. void OS::draw_begin() {
  62. ImGui_ImplSDLRenderer3_NewFrame();
  63. ImGui_ImplSDL3_NewFrame();
  64. ImGui::NewFrame();
  65. }
  66. void OS::draw_end() {
  67. ImVec4 clear_color = {0.15f, 0.15f, 0.15f, 0.0f};
  68. ImGuiIO &io = ImGui::GetIO();
  69. (void)io;
  70. ImGui::Render();
  71. SDL_SetRenderScale(root_window_ctx->renderer, io.DisplayFramebufferScale.x,
  72. io.DisplayFramebufferScale.y);
  73. SDL_SetRenderDrawColorFloat(root_window_ctx->renderer, clear_color.x,
  74. clear_color.y, clear_color.z, clear_color.w);
  75. SDL_RenderClear(root_window_ctx->renderer);
  76. ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(),
  77. root_window_ctx->renderer);
  78. SDL_RenderPresent(root_window_ctx->renderer);
  79. }
  80. void OS::update() {
  81. int w, h = 0;
  82. SDL_GetWindowSize(root_window_ctx->handle, &w, &h);
  83. root_window_ctx->w = w;
  84. root_window_ctx->h = h;
  85. }
  86. bool OS::update_events() {
  87. SDL_Event event = {};
  88. while (SDL_PollEvent(&event)) {
  89. ImGui_ImplSDL3_ProcessEvent(&event);
  90. switch (event.type) {
  91. case SDL_EVENT_KEY_UP: {
  92. if (event.key.key == SDLK_ESCAPE) {
  93. return false;
  94. }
  95. break;
  96. }
  97. case SDL_EVENT_QUIT: {
  98. return false;
  99. }
  100. case SDL_EVENT_WINDOW_CLOSE_REQUESTED: {
  101. if (event.window.windowID == SDL_GetWindowID(root_window_ctx->handle)) {
  102. return false;
  103. }
  104. break;
  105. }
  106. }
  107. }
  108. return true;
  109. }
  110. void OS::sleep(double ms) { SDL_Delay((Uint32)ms * 1000); }
  111. int OS::get_root_window_width() { return root_window_ctx->w; }
  112. int OS::get_root_window_height() { return root_window_ctx->h; }
  113. void OS::set_root_window_title(std::string title) {
  114. SDL_SetWindowTitle(root_window_ctx.get()->handle, title.c_str());
  115. }
  116. double OS::get_performance_frequency() {
  117. return (double)SDL_GetPerformanceFrequency();
  118. }
  119. double OS::get_performance_counter() {
  120. return (double)SDL_GetPerformanceCounter();
  121. }
  122. std::string OS::get_safe_getenv(const std::string key) {
  123. return SDL_getenv(key.c_str());
  124. }
  125. fs::path OS::get_home_config_path() {
  126. fs::path res = {};
  127. #if defined(_WIN32)
  128. auto config = get_safe_getenv("APPDATA");
  129. if (config.empty()) {
  130. throw std::runtime_error("APPDATA environment variable not found");
  131. }
  132. res = fs::path(config);
  133. #elif defined(__linux__)
  134. auto config = get_safe_getenv("HOME");
  135. if (config.empty()) {
  136. throw std::runtime_error("HOME environment variable not found");
  137. }
  138. res = fs::path(config) / ".config";
  139. #endif
  140. return res;
  141. }
  142. std::string OS::get_user_name() { return get_safe_getenv("USERNAME"); }
  143. } // namespace saura