aboutsummaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..409e66b
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,184 @@
+#include <chrono>
+#include <cstdlib>
+#include <iostream>
+#include <string_view>
+#include <thread>
+
+#include <entt/entt.hpp>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+
+static constexpr auto WINDOW_WIDTH = 640;
+static constexpr auto WINDOW_HEIGHT = 480;
+
+static SDL_Window *window = nullptr;
+static SDL_Renderer *renderer = nullptr;
+
+static int sdl2Initialize();
+static SDL_Texture *sdl2LoadTexture(const char *path);
+
+struct Player {
+ char unused = 0;
+};
+
+struct Vec2 {
+ float x, y;
+
+ auto& operator+=(const Vec2& o) noexcept {
+ x += o.x;
+ y += o.y;
+ return *this;
+ }
+};
+
+struct Point : public Vec2 {};
+struct Velocity : public Vec2 {};
+
+class Texture
+{
+public:
+ Texture(const char *path) {
+ tex = sdl2LoadTexture(path);
+ }
+
+ ~Texture() {
+ if (tex != nullptr)
+ SDL_DestroyTexture(tex);
+ }
+
+ void operator()(SDL_Renderer *rend, Point p) const noexcept {
+ const int x = static_cast<int>(p.x);
+ const int y = static_cast<int>(p.y);
+ SDL_Rect rect {x, y, 0, 0};
+
+ /* TODO err check */
+ SDL_QueryTexture(tex, nullptr, nullptr, &rect.w, &rect.h);
+ SDL_RenderCopy(rend, tex, nullptr, &rect);
+ }
+
+private:
+ SDL_Texture *tex;
+};
+
+int main()
+{
+ if (auto err = sdl2Initialize(); err)
+ return err;
+
+ entt::registry registry;
+
+ const auto ent = registry.create();
+ registry.emplace<Player>(ent);
+ registry.emplace<Point>(ent, 0.f, WINDOW_HEIGHT - 100.f);
+ registry.emplace<Velocity>(ent, 0.f, 0.f);
+ registry.emplace<Texture>(ent, "img/player.png");
+
+ SDL_Event e;
+ bool quit = false;
+ while (!quit) {
+ const auto nextFrame = std::chrono::high_resolution_clock::now() +
+ std::chrono::microseconds(1'000'000 / 60);
+
+ SDL_RenderClear(renderer);
+ registry.view<Texture, Point>().each(
+ [](Texture& tex, Point& p) { tex(renderer, p); });
+ SDL_RenderPresent(renderer);
+
+ registry.view<Velocity, Point>().each(
+ [](Velocity& v, Point& p) { p += v; });
+
+ while (SDL_PollEvent(&e)) {
+ if (e.type == SDL_QUIT) {
+ quit = true;
+ } else if (e.type == SDL_KEYDOWN) {
+ auto view = registry.view<Player, Velocity>();
+
+ if (e.key.repeat) {
+ // do nothing
+ } else if (e.key.keysym.sym == SDLK_d) {
+ view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
+ } else if (e.key.keysym.sym == SDLK_a) {
+ view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
+ }
+ } else if (e.type == SDL_KEYUP) {
+ auto view = registry.view<Player, Velocity>();
+
+ if (e.key.repeat) {
+ // do nothing
+ } else if (e.key.keysym.sym == SDLK_d) {
+ view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
+ } else if (e.key.keysym.sym == SDLK_a) {
+ view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
+ }
+ }
+ }
+
+ std::this_thread::sleep_until(nextFrame);
+ }
+
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+}
+
+int sdl2Initialize()
+{
+ if (auto err = SDL_Init(SDL_INIT_VIDEO); err < 0) {
+ std::cerr << "SDL error: " << SDL_GetError() << std::endl;
+ return EXIT_FAILURE;
+ } else {
+ atexit(SDL_Quit);
+ }
+
+ if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
+ std::cerr << "IMG error: " << IMG_GetError() << std::endl;
+ return EXIT_FAILURE;
+ } else {
+ atexit(IMG_Quit);
+ }
+
+ window = SDL_CreateWindow("game",
+ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+ WINDOW_WIDTH, WINDOW_HEIGHT,
+ SDL_WINDOW_SHOWN);
+
+ if (window == nullptr) {
+ std::cerr << "SDL error: " << SDL_GetError() << std::endl;
+ return EXIT_FAILURE;
+ } else {
+ atexit([] { SDL_DestroyWindow(window); });
+ }
+
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+
+ if (renderer == nullptr) {
+ std::cerr << "SDL error: " << SDL_GetError() << std::endl;
+ return EXIT_FAILURE;
+ } else {
+ atexit([] { SDL_DestroyRenderer(renderer); });
+ }
+
+ return 0;
+}
+
+SDL_Texture *sdl2LoadTexture(const char *path)
+{
+ SDL_Texture *tex = nullptr;
+
+ auto surface = IMG_Load(path);
+ if (surface == nullptr) {
+ std::cerr << "Unable to load image " << path << '!' << std::endl;
+ std::cerr << "SDL error: " << IMG_GetError() << std::endl;
+ } else {
+ tex = SDL_CreateTextureFromSurface(renderer, surface);
+
+ if (tex == nullptr) {
+ std::cerr << "Unable to create texture for " << path << '!' << std::endl;
+ std::cerr << "SDL error: " << SDL_GetError() << std::endl;
+ } else {
+ SDL_FreeSurface(surface);
+ }
+ }
+
+ return tex;
+}
+