refactor and split into headers

main
Clyne 5 months ago
parent b2eb646979
commit 66991ce9b8
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -1,5 +1,5 @@
CXXFLAGS := -std=c++23 -O0 -g3 -ggdb \
-Ientt/single_include
-Iinclude -Ientt/single_include
LDFLAGS := -lSDL2 -lSDL2_image
OBJS := $(subst .cpp,.o,$(wildcard *.cpp))

@ -0,0 +1,9 @@
#ifndef COMPONENTS_PLAYER_HPP
#define COMPONENTS_PLAYER_HPP
struct Player {
char unused = 0;
};
#endif // COMPONENTS_PLAYER_HPP

@ -0,0 +1,9 @@
#ifndef COMPONENTS_POINT_HPP
#define COMPONENTS_POINT_HPP
#include "vec2.hpp"
struct Point : public Vec2 {};
#endif // COMPONENTS_POINT_HPP

@ -0,0 +1,33 @@
#ifndef COMPONENTS_TEXTURE_HPP
#define COMPONENTS_TEXTURE_HPP
#include "window.hpp"
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;
};
#endif // COMPONENTS_TEXTURE_HPP

@ -0,0 +1,10 @@
#ifndef COMPONENTS_VELOCITY_HPP
#define COMPONENTS_VELOCITY_HPP
#include "vec2.hpp"
struct Velocity : public Vec2 {};
#endif // COMPONENTS_VELOCITY_HPP

@ -0,0 +1,15 @@
#ifndef VEC2_HPP
#define VEC2_HPP
struct Vec2 {
float x, y;
auto& operator+=(const Vec2& o) noexcept {
x += o.x;
y += o.y;
return *this;
}
};
#endif // VEC2_HPP

@ -0,0 +1,16 @@
#ifndef WINDOW_HPP
#define WINDOW_HPP
#include <SDL2/SDL.h>
constexpr auto WINDOW_WIDTH = 640;
constexpr auto WINDOW_HEIGHT = 480;
extern SDL_Window *window;
extern SDL_Renderer *renderer;
int sdl2Initialize();
SDL_Texture *sdl2LoadTexture(const char *path);
#endif // WINDOW_HPP

@ -1,64 +1,18 @@
#include "components/point.hpp"
#include "components/player.hpp"
#include "components/texture.hpp"
#include "components/velocity.hpp"
#include "window.hpp"
#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);
}
constexpr std::chrono::microseconds FRAME_TIME (1'000'000 / 60);
~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;
};
static bool handleInputs(entt::registry& registry);
int main()
{
@ -73,112 +27,51 @@ int main()
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);
do {
const auto now = std::chrono::high_resolution_clock::now();
SDL_RenderClear(renderer);
registry.view<Texture, Point>().each(
[](Texture& tex, Point& p) { tex(renderer, p); });
registry.view<Texture, Point>().each([](auto& tex, auto& 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);
}
registry.view<Velocity, Point>().each([](auto& v, auto& p) { p += v; });
SDL_DestroyWindow(window);
SDL_Quit();
std::this_thread::sleep_until(now + FRAME_TIME);
} while (handleInputs(registry));
}
int sdl2Initialize()
bool handleInputs(entt::registry& registry)
{
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;
}
bool quit = false;
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);
for (SDL_Event e; SDL_PollEvent(&e);) {
if (e.type == SDL_QUIT) {
quit = true;
} else if (e.type == SDL_KEYDOWN && !e.key.repeat) {
auto view = registry.view<Player, Velocity>();
switch (e.key.keysym.sym) {
case SDLK_d:
view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
break;
case SDLK_a:
view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
break;
}
} else if (e.type == SDL_KEYUP && !e.key.repeat) {
auto view = registry.view<Player, Velocity>();
switch (e.key.keysym.sym) {
case SDLK_d:
view.each([](Player& p, Velocity& v) { v.x -= 1.5f; });
break;
case SDLK_a:
view.each([](Player& p, Velocity& v) { v.x += 1.5f; });
break;
}
}
}
return tex;
return !quit;
}

@ -0,0 +1,72 @@
#include "window.hpp"
#include <cstdlib>
#include <iostream>
#include <SDL2/SDL_image.h>
SDL_Window *window;
SDL_Renderer *renderer;
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;
}
Loading…
Cancel
Save