summaryrefslogtreecommitdiffhomepage
path: root/main/main-impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/main-impl.cpp')
-rw-r--r--main/main-impl.cpp250
1 files changed, 0 insertions, 250 deletions
diff --git a/main/main-impl.cpp b/main/main-impl.cpp
index 1552c980..dec3948f 100644
--- a/main/main-impl.cpp
+++ b/main/main-impl.cpp
@@ -1,15 +1,5 @@
#include "main-impl.hpp"
-#include "floormat/app.hpp"
#include "compat/assert.hpp"
-#include "compat/fpu.hpp"
-#include "src/chunk.hpp"
-#include "src/world.hpp"
-#include "src/camera-offset.hpp"
-#include <Magnum/GL/DefaultFramebuffer.h>
-#include <chrono>
-#include <thread>
-
-//#define FM_SKIP_MSAA
namespace floormat {
@@ -17,246 +7,6 @@ floormat_main::floormat_main() noexcept = default;
floormat_main::~floormat_main() noexcept = default;
main_impl::~main_impl() noexcept = default;
-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);
-}
-
-void main_impl::recalc_viewport(Vector2i size) noexcept
-{
- update_window_state();
- GL::defaultFramebuffer.setViewport({{}, size });
- _msaa_framebuffer.detach(GL::Framebuffer::ColorAttachment{0});
- _msaa_renderbuffer = Magnum::GL::Renderbuffer{};
- _msaa_renderbuffer.setStorageMultisample(s.msaa_samples, GL::RenderbufferFormat::RGBA8, size);
- _msaa_framebuffer.setViewport({{}, size });
- _msaa_framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _msaa_renderbuffer);
- _shader.set_scale(Vector2{size});
- app.on_viewport_event(size);
-}
-
-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();
-}
-
-global_coords main_impl::pixel_to_tile(Vector2d position) const noexcept
-{
- constexpr Vector2d pixel_size{dTILE_SIZE[0], dTILE_SIZE[1]};
- constexpr Vector2d half{.5, .5};
- const Vector2d px = position - Vector2d{windowSize()}*.5 - _shader.camera_offset()*.5;
- const Vector2d vec = tile_shader::unproject(px) / pixel_size + half;
- const auto x = (std::int32_t)std::floor(vec[0]), y = (std::int32_t)std::floor(vec[1]);
- return { x, y };
-}
-
-auto main_impl::get_draw_bounds() const noexcept -> draw_bounds
-{
-
- using limits = std::numeric_limits<std::int16_t>;
- auto x0 = limits::max(), x1 = limits::min(), y0 = limits::max(), y1 = limits::min();
-
- for (const auto win = Vector2d(windowSize());
- auto p : {pixel_to_tile(Vector2d{0, 0}).chunk(),
- pixel_to_tile(Vector2d{win[0]-1, 0}).chunk(),
- pixel_to_tile(Vector2d{0, win[1]-1}).chunk(),
- pixel_to_tile(Vector2d{win[0]-1, win[1]-1}).chunk()})
- {
- x0 = std::min(x0, p.x);
- x1 = std::max(x1, p.x);
- y0 = std::min(y0, p.y);
- y1 = std::max(y1, p.y);
- }
- return {x0, x1, y0, y1};
-}
-
-void main_impl::draw_world() noexcept
-{
- auto [minx, maxx, miny, maxy] = get_draw_bounds();
-
- for (std::int16_t y = miny; y <= maxy; y++)
- for (std::int16_t x = minx; x <= maxx; x++)
- {
- if (const chunk_coords c = {x, y}; !_world.contains(c))
- app.maybe_initialize_chunk(c, _world[c]);
- const chunk_coords c{x, y};
- const with_shifted_camera_offset o{_shader, c};
- _floor_mesh.draw(_shader, _world[c]);
- }
-
- for (std::int16_t y = miny; y <= maxy; y++)
- for (std::int16_t x = minx; x <= maxx; x++)
- {
- const chunk_coords c{x, y};
- const with_shifted_camera_offset o{_shader, c};
- _wall_mesh.draw(_shader, _world[c]);
- }
-}
-
-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;
- }
-}
-
-void main_impl::drawEvent()
-{
- float dt = timeline.previousFrameDuration();
- if (dt > 0)
- {
- const float RC1 = dt_expected.do_sleep ? 1.f : 1.f/15,
- RC2 = dt_expected.do_sleep ? 1.f/15 : 1.f/60;
- const float alpha1 = dt/(dt + RC1);
- const float alpha2 = dt/(dt + RC2);
-
- _frame_time1 = _frame_time1*(1-alpha1) + alpha1*dt;
- _frame_time2 = _frame_time1*(1-alpha2) + alpha2*dt;
- constexpr float max_deviation = 5 * 1e-3f;
- if (std::fabs(_frame_time1 - _frame_time2) > max_deviation)
- _frame_time1 = _frame_time2;
- }
- else
- {
- swapBuffers();
- timeline.nextFrame();
- }
-
- dt = std::clamp(dt, 1e-5f, std::fmaxf(1e-1f, dt_expected.value));
-
- app.update(dt);
- _shader.set_tint({1, 1, 1, 1});
-
- {
- GL::defaultFramebuffer.clear(GL::FramebufferClear::Color);
-#ifndef FM_SKIP_MSAA
- _msaa_framebuffer.clear(GL::FramebufferClear::Color);
- _msaa_framebuffer.bind();
-#endif
- draw_world();
- app.draw_msaa();
-#ifndef FM_SKIP_MSAA
- GL::defaultFramebuffer.bind();
- GL::Framebuffer::blit(_msaa_framebuffer, GL::defaultFramebuffer, {{}, windowSize()}, GL::FramebufferBlit::Color);
-#endif
- }
-
- app.draw();
-
- swapBuffers();
- redraw();
-
- if (dt_expected.do_sleep)
- {
- constexpr float eps = 1e-3f;
- const float Δt൦ = timeline.currentFrameDuration(), sleep_secs = dt_expected.value - Δt൦ - dt_expected.jitter;
- if (sleep_secs > eps)
- std::this_thread::sleep_for(std::chrono::nanoseconds((long long)(sleep_secs * 1e9f)));
- //fm_debug("jitter:%.1f sleep:%.0f", dt_expected.jitter*1000, sleep_secs*1000);
- const float Δt = timeline.currentFrameDuration() - dt_expected.value;
- constexpr float α = .1f;
- dt_expected.jitter = std::fmax(dt_expected.jitter + Δt * α,
- dt_expected.jitter * (1-α) + Δt * α);
- dt_expected.jitter = std::copysignf(std::fminf(dt_expected.value, std::fabsf(dt_expected.jitter)), dt_expected.jitter);
- }
- else
- dt_expected.jitter = 0;
- timeline.nextFrame();
-}
-
void main_impl::quit(int status) { Platform::Sdl2Application::exit(status); }
struct world& main_impl::world() noexcept { return _world; }
SDL_Window* main_impl::window() noexcept { return Sdl2Application::window(); }