summaryrefslogtreecommitdiffhomepage
path: root/main/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/main.cpp')
-rw-r--r--main/main.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/main/main.cpp b/main/main.cpp
new file mode 100644
index 00000000..f58228c6
--- /dev/null
+++ b/main/main.cpp
@@ -0,0 +1,222 @@
+#include "tile-atlas.hpp"
+#include "loader.hpp"
+#include "shaders/tile-shader.hpp"
+#include "tile.hpp"
+#include "chunk.hpp"
+#include "floor-mesh.hpp"
+#include "wall-mesh.hpp"
+
+#include <bitset>
+
+#include <Magnum/Magnum.h>
+#include <Magnum/Math/Vector.h>
+#include <Magnum/GL/DefaultFramebuffer.h>
+#include <Magnum/GL/Renderer.h>
+#include <Magnum/Platform/Sdl2Application.h>
+#include <Magnum/Trade/AbstractImporter.h>
+#include <Magnum/Timeline.h>
+
+namespace Magnum::Examples {
+
+template<typename enum_type>
+struct enum_bitset : std::bitset<(std::size_t)enum_type::MAX> {
+ static_assert(std::is_same_v<std::size_t, std::common_type_t<std::size_t, std::underlying_type_t<enum_type>>>);
+ static_assert(std::is_same_v<enum_type, std::decay_t<enum_type>>);
+ using std::bitset<(std::size_t)enum_type::MAX>::bitset;
+ constexpr bool operator[](enum_type x) const { return operator[]((std::size_t)x); }
+ constexpr decltype(auto) operator[](enum_type x) {
+ return std::bitset<(std::size_t)enum_type::MAX>::operator[]((std::size_t)x);
+ }
+};
+
+struct app final : Platform::Application
+{
+ using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy;
+ using tile_atlas_ = std::shared_ptr<tile_atlas>;
+
+ explicit app(const Arguments& arguments);
+ virtual ~app();
+ void drawEvent() override;
+ void update(float dt);
+ void do_camera(float dt);
+ void reset_camera_offset();
+ void keyPressEvent(KeyEvent& event) override;
+ void keyReleaseEvent(KeyEvent& event) override;
+ void do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated);
+ void draw_chunk(chunk& c);
+ void update_window_scale();
+
+ enum class key : int {
+ camera_up, camera_left, camera_right, camera_down, camera_reset,
+ quit,
+ MAX
+ };
+ chunk make_test_chunk();
+
+ tile_shader _shader;
+ tile_atlas_ floor1 = loader.tile_atlas("../share/game/images/metal1.tga", {2, 2});
+ tile_atlas_ floor2 = loader.tile_atlas("../share/game/images/floor1.tga", {4, 4});
+ tile_atlas_ wall1 = loader.tile_atlas("../share/game/images/metal2.tga", {2, 2});
+ tile_atlas_ wall2 = loader.tile_atlas("../share/game/images/wood1.tga", {2, 2});
+ chunk _chunk = make_test_chunk();
+ floor_mesh _floor_mesh;
+ wall_mesh _wall_mesh;
+
+ Vector2 camera_offset;
+ enum_bitset<key> keys;
+ Magnum::Timeline timeline;
+};
+
+using namespace Math::Literals;
+
+chunk app::make_test_chunk()
+{
+ constexpr auto N = TILE_MAX_DIM;
+ chunk c;
+ c.foreach_tile([&, this](tile& x, std::size_t k, local_coords pt) {
+ const auto& atlas = pt.x > N/2 && pt.y >= N/2 ? floor2 : floor1;
+ x.ground_image = { atlas, (std::uint8_t)(k % atlas->size()) };
+ });
+ constexpr auto K = N/2;
+ c[{K, K }].wall_north = { wall1, 0 };
+ c[{K, K }].wall_west = { wall2, 0 };
+ c[{K, K+1}].wall_north = { wall1, 0 };
+ c[{K+1, K }].wall_west = { wall2, 0 };
+ return c;
+}
+
+void app::update_window_scale()
+{
+ auto sz = windowSize();
+ _shader.set_scale({ (float)sz[0], (float)sz[1] });
+}
+
+void app::draw_chunk(chunk& c)
+{
+ _floor_mesh.draw(_shader, c);
+ _wall_mesh.draw(_shader, c);
+}
+
+app::app(const Arguments& arguments):
+ Platform::Application{
+ arguments,
+ Configuration{}
+ .setTitle("Test")
+ .setSize({1024, 768}, dpi_policy::Physical),
+ GLConfiguration{}
+ //.setSampleCount(16)
+ }
+{
+ reset_camera_offset();
+ timeline.start();
+}
+
+void app::drawEvent() {
+#if 0
+ GL::defaultFramebuffer.clear(GL::FramebufferClear::Color | GL::FramebufferClear::Depth);
+ GL::Renderer::setDepthMask(true);
+ GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::LessOrEqual);
+ GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
+#else
+ GL::defaultFramebuffer.clear(GL::FramebufferClear::Color);
+ GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::Never);
+#endif
+
+ update_window_scale();
+ {
+ float dt = timeline.previousFrameDuration();
+ update(dt);
+ }
+
+ draw_chunk(_chunk);
+
+ swapBuffers();
+ redraw();
+ timeline.nextFrame();
+}
+
+void app::do_camera(float dt)
+{
+ constexpr float pixels_per_second = 512;
+ if (keys[key::camera_up])
+ camera_offset += Vector2(0, 1) * dt * pixels_per_second;
+ else if (keys[key::camera_down])
+ camera_offset += Vector2(0, -1) * dt * pixels_per_second;
+ if (keys[key::camera_left])
+ camera_offset += Vector2(1, 0) * dt * pixels_per_second;
+ else if (keys[key::camera_right])
+ camera_offset += Vector2(-1, 0) * dt * pixels_per_second;
+
+ _shader.set_camera_offset(camera_offset);
+
+ if (keys[key::camera_reset])
+ reset_camera_offset();
+}
+
+void app::reset_camera_offset()
+{
+ camera_offset = _shader.project({TILE_MAX_DIM*TILE_SIZE[0]/2.f, TILE_MAX_DIM*TILE_SIZE[1]/2.f, 0});
+ //camera_offset = {};
+}
+
+void app::update(float dt)
+{
+ do_camera(dt);
+ if (keys[key::quit])
+ Platform::Sdl2Application::exit(0);
+}
+
+void app::do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated)
+{
+ //using Mods = KeyEvent::Modifiers;
+
+ (void)m;
+ (void)repeated;
+
+ const key x = progn(switch (k) {
+ using enum KeyEvent::Key;
+ using enum key;
+
+ case W: return camera_up;
+ case A: return camera_left;
+ case S: return camera_down;
+ case D: return camera_right;
+ case Home: return camera_reset;
+ case Esc: return quit;
+ default: return MAX;
+ });
+
+ if (x != key::MAX)
+ keys[x] = pressed;
+}
+
+app::~app()
+{
+ loader_::destroy();
+}
+
+void app::keyPressEvent(Platform::Sdl2Application::KeyEvent& event)
+{
+ do_key(event.key(), event.modifiers(), true, event.isRepeated());
+}
+
+void app::keyReleaseEvent(Platform::Sdl2Application::KeyEvent& event)
+{
+ do_key(event.key(), event.modifiers(), false, false);
+}
+
+} // namespace Magnum::Examples
+
+MAGNUM_APPLICATION_MAIN(Magnum::Examples::app)
+
+#ifdef _MSC_VER
+# include <cstdlib>
+# ifdef __clang__
+# pragma clang diagnostic ignored "-Wmissing-prototypes"
+# pragma clang diagnostic ignored "-Wmain"
+# endif
+
+extern "C" int __stdcall WinMain(void*, void*, void*, int /* nCmdShow */) {
+ return main(__argc, __argv);
+}
+#endif