chore: Initial commit

This commit is contained in:
2026-04-16 21:30:35 +01:00
commit 1d12a23e15
13 changed files with 430 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
**.vscode/
build/

BIN
i3bgwin Executable file

Binary file not shown.

46
makefile Normal file
View File

@@ -0,0 +1,46 @@
CC=g++
C_FLAGS=-g -Wall -Wextra -O0 -Wno-unused-function
#C_FLAGS=-Wall -Wextra -O3 -Wno-unused-function
VAL_FLAGS=--leak-check=full --show-leak-kinds=all --track-origins=yes -s
DIR_SRC=src
DIR_INC=include
DIR_BUILD=build
DEPS=SDL3
OUTBIN=$(DIR_BUILD)/bin/main
SRCS=$(shell find $(DIR_SRC)/ -type f -name '*.cpp')
OBJS=$(patsubst $(DIR_SRC)/%.cpp,$(DIR_BUILD)/obj/%.o,$(SRCS))
DEPS_EXT=$(patsubst %,-l%,$(DEPS))
INCS_EXT=$(patsubst %,-I%,$(DIR_INC))
.PHONY: all build run dbg val clean test clean-tests
all: build
build: $(OUTBIN)
rebuild: clean .WAIT build
run: $(OUTBIN)
./i3bgwin $(OUTBIN) {windowid}
$(OUTBIN): $(OBJS)
@mkdir -p $(@D)
$(CC) $(OBJS) $(DEPS_EXT) -o $@
$(DIR_BUILD)/obj/%.o: $(DIR_SRC)/%.cpp
@mkdir -p $(@D)
$(CC) $(C_FLAGS) $(INCS_EXT) -c $< -o $@
dbg: $(DBG_BIN)
gdb $(GDB_FLAGS) ./$(OUTBIN)
val: $(DBG_BIN)
valgrind $(VAL_FLAGS) ./$(OUTBIN)
clean:
$(RM) -r $(DIR_BUILD)

67
src/main.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL3/SDL.h>
#include "renderer.hpp"
#include "sim/world.hpp"
#include "sim/aircraft.hpp"
static SDL_Window *window;
static SDL_Renderer *sdl_renderer;
static int width, height;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <WID>\n", argv[0]);
exit(1);
}
int wid = 0;
sscanf(argv[1], "%d", &wid);
SDL_Init(SDL_INIT_VIDEO);
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X11_WINDOW_NUMBER, wid);
window = SDL_CreateWindowWithProperties(props);
sdl_renderer = SDL_CreateRenderer(window, NULL);
SDL_GetWindowSize(window, &width, &height);
dxd::Renderer renderer = dxd::Renderer(sdl_renderer, width, height);
// World init
dxd::sim::World world = dxd::sim::World({ .x = 10, .y = 10 });
dxd::sim::Aircraft *ac = new dxd::sim::Aircraft({ 0, 0 }, 1, 0.1);
world.add_obj(ac);
SDL_Event event;
bool running = true;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_QUIT) running = false;
}
// Clear
renderer.color(0, 0, 0, 255);
SDL_RenderClear(sdl_renderer);
// World draw
renderer.color(255, 255, 255, 255);
world.draw(&renderer);
world.tick(1.0f / 60.0f);
// Usual test
renderer.color(127, 0, 0, 255);
renderer.line(-vec2_one, vec2_one);
SDL_RenderPresent(sdl_renderer);
SDL_Delay(1000 / 60);
}
}

102
src/math.hpp Normal file
View File

@@ -0,0 +1,102 @@
#pragma once
#include <float.h>
#include <math.h>
//#define epsilon 0.0000001
typedef struct vec2 { float x, y; } vec2;
typedef struct vec2i { int x, y; } vec2i;
static const vec2 vec2_zero = { 0, 0 };
static const vec2 vec2_one = { 1, 1 };
static const vec2 vec2_max = { FLT_MAX, FLT_MAX };
static const vec2 vec2_min = { -FLT_MAX, -FLT_MAX };
static const vec2i vec2i_zero = { 0, 0 };
static const vec2i vec2i_one = { 1, 1 };
static vec2 operator-(vec2 const &v)
{
return { .x = -v.x, .y = -v.y };
}
static vec2 operator+(vec2 const &a, vec2 const &b)
{
return { .x = a.x + b.x, .y = a.y + b.y };
}
static vec2 operator-(vec2 const &a, vec2 const &b)
{
return { .x = a.x - b.x, .y = a.y - b.y };
}
static vec2 operator*(vec2 const &a, float const &b)
{
return { .x = a.x * b, .y = a.y * b };
}
static vec2 operator/(vec2 const &a, float const &b)
{
return { .x = a.x / b, .y = a.y / b };
}
static bool operator<(vec2 const &a, vec2 const &b)
{
return a.x < b.x && a.y < b.y;
}
static bool operator>(vec2 const &a, vec2 const &b)
{
return a.x > b.x && a.y > b.y;
}
static float dot(vec2 const &a, vec2 const &b)
{
return a.x * b.x + a.y * b.y;
}
static float norm2(vec2 const &v)
{
return v.x * v.x + v.y * v.y;
}
static float norm(vec2 const &v)
{
return std::sqrtf(v.x * v.x + v.y * v.y);
}
static vec2 normalize(vec2 const &v)
{
return v / norm(v);
}
static inline vec2 normalize_h(vec2 const &v)
{
return v / std::sqrt(v.x * v.x + v.y * v.y);
}
static vec2 min2(vec2 const &a, vec2 const &b)
{
return {
.x = a.x < b.x ? a.x : b.x,
.y = a.y < b.y ? a.y : b.y,
};
}
static vec2 max2(vec2 const &a, vec2 const &b)
{
return {
.x = a.x > b.x ? a.x : b.x,
.y = a.y > b.y ? a.y : b.y,
};
}
static vec2 polar_to_vec2(const float angle, const float len)
{
return {
.x = len * sinf(angle),
.y = len * cosf(angle)
};
}

79
src/renderer.hpp Normal file
View File

@@ -0,0 +1,79 @@
#pragma once
#include <stdio.h>
#include <SDL3/SDL.h>
#include "math.hpp"
namespace dxd
{
class Renderer
{
private:
SDL_Renderer *_sdl;
int _width, _height;
vec2 _center;
float _scale;
float to_screenf(float f)
{
//FIXME: Aspect ratio
return (f/2) * _height;
}
vec2 to_screenv2(vec2 p)
{
//TODO: Handle aspect ratio
return {
.x = ((p.x/2) + .5f) * _height,
.y = (.5f - (p.y/2)) * _height,
};
}
float to_viewf(float f)
{
return f * _scale;
}
vec2 to_viewv2(vec2 p)
{
return {
.x = (p.x - _center.x) * _scale,
.y = (p.y - _center.y) * _scale,
};
}
public:
Renderer(SDL_Renderer *sdl, int width, int height) : _sdl(sdl), _width(width), _height(height)
{
_center = { 0, 0 };
_scale = 1;
}
void color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
SDL_SetRenderDrawColor(_sdl, r, g, b, a);
}
void line(vec2 a, vec2 b)
{
vec2 as = to_screenv2(to_viewv2(a)), bs = to_screenv2(to_viewv2(b));
SDL_RenderLine(_sdl, as.x, as.y, bs.x, bs.y);
}
void dot(vec2 center, float size)
{
vec2 view = to_viewv2(center - vec2_one * (size/2));
vec2 screen = to_screenv2(view);
float scr_size = to_screenf(to_viewf(size));
SDL_FRect rect = {
.x = screen.x,
.y = screen.y - scr_size, //HACK: Do this somewhere else? Rect function?
.w = scr_size,
.h = scr_size,
};
SDL_RenderFillRect(_sdl, &rect);
}
};
} // namespace dxd

12
src/sim/aircraft.cpp Normal file
View File

@@ -0,0 +1,12 @@
#include "aircraft.hpp"
void dxd::sim::Aircraft::tick(float timestep, vec2 bounds)
{
_position = _position + polar_to_vec2(_direction, _speed) * timestep;
}
void dxd::sim::Aircraft::draw(Renderer *rend)
{
rend->dot(_position, 0.02);
rend->line(_position, _position + polar_to_vec2(_direction, 0.05));
}

24
src/sim/aircraft.hpp Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include "../math.hpp"
#include "world_object.hpp"
namespace dxd::sim
{
class Aircraft : public WorldObject
{
private:
vec2 _position;
float _direction;
float _speed;
public:
Aircraft(vec2 position, float direction, float speed)
: _position(position), _direction(direction), _speed(speed) {}
void tick(float timestep, vec2 bounds) override;
void draw(Renderer *rend) override;
};
} // namespace dxd::sim

11
src/sim/airfield.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "airfield.hpp"
void dxd::sim::Airfield::tick(float timestep, vec2 bounds)
{
}
void dxd::sim::Airfield::draw(Renderer *rend)
{
}

23
src/sim/airfield.hpp Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
#include <vector>
#include "../math.hpp"
#include "world_object.hpp"
namespace dxd::sim
{
class Airfield : public WorldObject
{
private:
vec2 _position;
public:
Airfield(vec2 position) : _position(position) {}
void tick(float timestep, vec2 bounds) override;
void draw(Renderer *rend) override;
};
} // namespace dxd::sim

17
src/sim/world.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include "world.hpp"
void dxd::sim::World::tick(float timestep)
{
for (auto obj : _objs)
{
obj->tick(timestep, _size);
}
}
void dxd::sim::World::draw(Renderer *rend)
{
for (auto obj : _objs)
{
obj->draw(rend);
}
}

29
src/sim/world.hpp Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <vector>
#include "../math.hpp"
#include "world_object.hpp"
namespace dxd::sim
{
class World
{
private:
vec2 _size;
std::vector<WorldObject*> _objs;
public:
World(vec2 size) : _size(size)
{
_objs = std::vector<WorldObject*>();
}
void add_obj(WorldObject *obj) { _objs.push_back(obj); }
void tick(float timestep);
void draw(Renderer *rend);
};
} // namespace dxd::sim

18
src/sim/world_object.hpp Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include "../math.hpp"
#include "../renderer.hpp"
namespace dxd::sim
{
class WorldObject
{
public:
WorldObject() {}
virtual void tick(float timestep, vec2 bounds) = 0;
virtual void draw(Renderer *rend) = 0;
};
} // namespace dxd::sim