summaryrefslogtreecommitdiffhomepage
path: root/main/setup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/setup.cpp')
-rw-r--r--main/setup.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/main/setup.cpp b/main/setup.cpp
new file mode 100644
index 00000000..428a797b
--- /dev/null
+++ b/main/setup.cpp
@@ -0,0 +1,116 @@
+#include "main-impl.hpp"
+#include "compat/fpu.hpp"
+
+namespace floormat {
+
+main_impl::main_impl(floormat_app& app, fm_settings&& s, int& fake_argc) noexcept :
+ Platform::Sdl2Application{Arguments{fake_argc, nullptr},
+ make_conf(s), make_gl_conf(s)},
+ s{std::move(s)}, app{app}
+{
+ switch (s.vsync) // NOLINT(bugprone-use-after-move)
+ {
+ case fm_tristate::on:
+ (void)setSwapInterval(1);
+ if (const auto list = GL::Context::current().extensionStrings();
+ std::find(list.cbegin(), list.cend(), "EXT_swap_control_tear") != list.cbegin())
+ (void)setSwapInterval(-1);
+ break;
+ case fm_tristate::off:
+ setSwapInterval(0);
+ break;
+ default:
+ break;
+ }
+ set_fp_mask();
+ fm_assert(framebufferSize() == windowSize());
+ timeline.start();
+}
+
+auto main_impl::make_window_flags(const fm_settings& s) -> Configuration::WindowFlags
+{
+ using flag = Configuration::WindowFlag;
+ Configuration::WindowFlags flags{};
+ if (s.resizable)
+ flags |= flag::Resizable;
+ if (s.fullscreen)
+ flags |= flag::Fullscreen;
+ if (s.fullscreen_desktop)
+ flags |= flag::FullscreenDesktop;
+ if (s.borderless)
+ flags |= flag::Borderless;
+ if (s.maximized)
+ flags |= flag::Maximized;
+ return flags;
+}
+
+auto main_impl::make_conf(const fm_settings& s) -> Configuration
+{
+ switch (s.log_level)
+ {
+ default:
+ SDL_setenv("MAGNUM_LOG_LEVEL", "normal", 1);
+ break;
+ case fm_log_level::quiet:
+ SDL_setenv("MAGNUM_LOG_LEVEL", "quiet", 1);
+ break;
+ case fm_log_level::verbose:
+ SDL_setenv("MAGNUM_LOG_LEVEL", "verbose", 1);
+ break;
+ }
+ return Configuration{}
+ .setTitle(s.title)
+ .setSize(s.resolution)
+ .setWindowFlags(make_window_flags(s));
+}
+
+auto main_impl::make_gl_conf(const fm_settings& s) -> GLConfiguration
+{
+ GLConfiguration::Flags flags{};
+ using f = GLConfiguration::Flag;
+ if (s.gpu_debug >= fm_gpu_debug::on)
+ flags |= f::Debug | f::GpuValidation;
+ if (s.gpu_debug >= fm_gpu_debug::robust)
+ flags |= f::RobustAccess;
+ else if (s.gpu_debug <= fm_gpu_debug::no_error)
+ flags |= f::NoError;
+ return GLConfiguration{}.setFlags(flags);
+}
+
+static int get_window_refresh_rate(SDL_Window* window)
+{
+ fm_assert(window != nullptr);
+ if (int index = SDL_GetWindowDisplayIndex(window); index < 0)
+ fm_warn_once("SDL_GetWindowDisplayIndex: %s", SDL_GetError());
+ else if (SDL_DisplayMode dpymode; SDL_GetCurrentDisplayMode(index, &dpymode) < 0)
+ fm_warn_once("SDL_GetCurrentDisplayMode: %s", SDL_GetError());
+ else
+ return std::max(30, dpymode.refresh_rate);
+ return 30;
+}
+
+void main_impl::update_window_state()
+{
+ const auto flags = (SDL_WindowFlags)SDL_GetWindowFlags(window());
+
+ dt_expected.do_sleep = true;
+ dt_expected.jitter = 0;
+ if (flags & SDL_WINDOW_HIDDEN)
+ dt_expected.value = 1;
+ else if (!(flags & SDL_WINDOW_INPUT_FOCUS))
+ dt_expected.value = 1.f / 30;
+ else if (int interval = std::abs(SDL_GL_GetSwapInterval());
+ s.vsync >= fm_tristate::maybe && interval > 0)
+ dt_expected.value = 0.5f / (get_window_refresh_rate(window()));
+#if 1
+ else if (!(flags & SDL_WINDOW_MOUSE_FOCUS))
+ dt_expected.value = 1.f / 60;
+#endif
+ else
+ {
+ dt_expected.do_sleep = false;
+ dt_expected.value = 1e-1f;
+ }
+}
+
+} // namespace floormat