chore: Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
**.vscode/
|
||||
build/
|
||||
46
makefile
Normal file
46
makefile
Normal 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
67
src/main.cpp
Normal 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
102
src/math.hpp
Normal 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
79
src/renderer.hpp
Normal 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
12
src/sim/aircraft.cpp
Normal 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
24
src/sim/aircraft.hpp
Normal 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
11
src/sim/airfield.cpp
Normal 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
23
src/sim/airfield.hpp
Normal 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
17
src/sim/world.cpp
Normal 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
29
src/sim/world.hpp
Normal 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
18
src/sim/world_object.hpp
Normal 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
|
||||
Reference in New Issue
Block a user