add time based vector and DRM support

This commit is contained in:
2026-08-06 13:05:32 +02:00
parent 45a4431b53
commit 19de2840c5
6 changed files with 239 additions and 60 deletions
+4
View File
@@ -2,4 +2,8 @@
template<typename T>
static inline T feet_to_meters(T ft) {
return static_cast<T>(ft * 0.3048);
}
template<typename T>
static inline T knot_to_km(T kn) {
return static_cast<T>(kn * 0.5399568);
}
+1
View File
@@ -19,4 +19,5 @@ struct rect_t {
void filled_rect(const rect_t* rect, const color_t color);
void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color);
void rhombus(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color);
void line(const uint16_t x1,const uint16_t y1,const uint16_t x2,const uint16_t y2, const color_t color);
}
+131 -59
View File
@@ -1,6 +1,8 @@
#include "../core/const.hpp"
#include <SDL3/SDL.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_hints.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_rect.h>
@@ -14,6 +16,8 @@
#include <cstddef>
#include <cstdint>
#include "../core/color.h"
#include "core/config.hpp"
#include "draw.hpp"
#include "hal/hal.hpp"
#include <curl/curl.h>
@@ -22,7 +26,7 @@
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
#include <tuple>
#include "../core/color.h"
struct sdl_session {
SDL_Window *window;
SDL_Renderer *renderer;
@@ -34,16 +38,53 @@ CURL *curl;
namespace hal {
int init() {
SDL_Init(SDL_INIT_VIDEO);
#ifdef CONFIG_SDL_TARGET_KMSDRM
if (!SDL_SetHint(SDL_HINT_KMSDRM_DEVICE_INDEX, "-1")) {
SDL_Log("hint failed: %s", SDL_GetError());
}
if (!SDL_SetHint(SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER, "1")) {
SDL_Log("hint failed: %s", SDL_GetError());
}
if (!SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "kmsdrm")) {
SDL_Log("hint failed: %s", SDL_GetError());
}
if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, CONFIG_SDL_DRIVERS)) {
SDL_Log("hint failed: %s", SDL_GetError());
}
#endif
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("init failed: %s", SDL_GetError());
return 1;
}
// DEBUG
std::clog << "active driver: " << SDL_GetCurrentVideoDriver() << "\n";
mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());
if (!mode) {
SDL_Log("failed to get display mode: %s", SDL_GetError());
return 1;
}
main_sdl_session.window =
SDL_CreateWindow(program_name, mode->w, mode->h, SDL_WINDOW_FULLSCREEN);
main_sdl_session.renderer =
SDL_CreateRenderer(main_sdl_session.window, "gpu,vulcan");
if (!main_sdl_session.window) {
SDL_Log("window failed: %s", SDL_GetError());
return 1;
}
main_sdl_session.renderer = SDL_CreateRenderer(main_sdl_session.window,
#ifndef CONFIG_SDL_TARGET_KMSDRM
CONFIG_SDL_DRIVERS
#else
NULL
#endif
);
if (!main_sdl_session.renderer) {
SDL_Log("renderer failed: %s", SDL_GetError());
return 1;
}
curl = curl_easy_init();
return 0;
}
std::tuple<uint16_t, uint16_t> get_screen_size() { return {mode->w, mode->h}; }
@@ -56,6 +97,26 @@ void start_frame() {
const Uint64 frame_delay_ns = 1000000000ULL / 1;
void end_frame() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
// Handles Window close (the 'X' button), Alt+F4, or SIGINT (Ctrl+C)
// Handles keyboard key presses
case SDL_EVENT_KEY_DOWN:
// Check if the pressed key is 'Q'
if (event.key.key != SDLK_Q) {
break;
}
case SDL_EVENT_QUIT:
SDL_Quit();
std::exit(0);
break;
default:
break;
}
}
SDL_RenderPresent(main_sdl_session.renderer);
@@ -83,72 +144,83 @@ void filled_rect(const rect_t *rect, const color_t color) {
SDL_RenderFillRect(main_sdl_session.renderer, &frect);
}
void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color) {
void circle(const uint16_t x_center, const uint16_t y_center,
const uint16_t radius, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
// based on https://www.geeksforgeeks.org/dsa/mid-point-circle-drawing-algorithm/
// based on
// https://www.geeksforgeeks.org/dsa/mid-point-circle-drawing-algorithm/
int x = radius, y = 0;
// Printing the initial point on the axes
// after translation
// Printing the initial point on the axes
// after translation
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, y + y_center);
// When radius is zero only a single
// point will be printed
if (radius > 0) {
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
std::cout << "\n";
}
// Initialising the value of P
int P = 1 - radius;
while (x > y) {
y++;
// Mid-point is inside or on the perimeter
if (P <= 0)
P = P + 2 * y + 1;
// Mid-point is outside the perimeter
else {
x--;
P = P + 2 * y - 2 * x + 1;
}
// All the perimeter points have already been printed
if (x < y)
break;
// Printing the generated point and its reflection
// in the other octants after translation
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, -y + y_center);
// When radius is zero only a single
// point will be printed
if (radius > 0)
{
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
std::cout << "\n";
}
// Initialising the value of P
int P = 1 - radius;
while (x > y)
{
y++;
// Mid-point is inside or on the perimeter
if (P <= 0)
P = P + 2*y + 1;
// Mid-point is outside the perimeter
else
{
x--;
P = P + 2*y - 2*x + 1;
}
// All the perimeter points have already been printed
if (x < y)
break;
// Printing the generated point and its reflection
// in the other octants after translation
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, -y + y_center);
// If the generated point is on the line x = y then
// the perimeter points have already been printed
if (x != y)
{
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, -x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, -x + y_center);
}
// If the generated point is on the line x = y then
// the perimeter points have already been printed
if (x != y) {
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, -x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, -x + y_center);
}
}
}
void rhombus(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color) {
void rhombus(const uint16_t x_center, const uint16_t y_center,
const uint16_t radius, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
const SDL_FPoint points[] = {{static_cast<float>(x_center+radius),static_cast<float>(y_center)},{static_cast<float>(x_center),static_cast<float>(y_center+radius)},{static_cast<float>(x_center-radius),static_cast<float>(y_center)},{static_cast<float>(x_center),static_cast<float>(y_center-radius)},{static_cast<float>(x_center+radius),static_cast<float>(y_center)}};
const SDL_FPoint points[] = {
{static_cast<float>(x_center + radius), static_cast<float>(y_center)},
{static_cast<float>(x_center), static_cast<float>(y_center + radius)},
{static_cast<float>(x_center - radius), static_cast<float>(y_center)},
{static_cast<float>(x_center), static_cast<float>(y_center - radius)},
{static_cast<float>(x_center + radius), static_cast<float>(y_center)}};
SDL_RenderLines(main_sdl_session.renderer, points, ARRAY_LENGHT(points));
}
void line(const uint16_t x1, const uint16_t y1, const uint16_t x2,
const uint16_t y2, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
SDL_RenderLine(main_sdl_session.renderer, x1, y1, x2, y2);
}
} // namespace draw
namespace net {
@@ -190,4 +262,4 @@ nlohmann::json http_get_json(const std::string &url) {
}
return nullptr;
}
} // namespace net
} // namespace net
+2
View File
@@ -52,6 +52,8 @@ void filled_rect(const rect_t *rect, const color_t color) {}
void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color) {
}
void rhombus(const uint16_t x_center, const uint16_t y_center, const uint16_t radius, const color_t color) {}
void line(const uint16_t x1, const uint16_t y1, const uint16_t x2, const uint16_t y2, const color_t color) {}
} // namespace draw
namespace net {
+26 -1
View File
@@ -8,8 +8,10 @@
#include "nlohmann/json_fwd.hpp"
#include <cstdint>
#include <cstdlib>
#include <cmath>
#include <format>
#include <iostream>
#include <numbers>
#include "core/global.hpp"
#include "core/geo.hpp"
#include "core/gfx.hpp"
@@ -106,6 +108,18 @@ int main() {
std::clog << YELLOW"[WARNING]" RESET " aircraft with no alt data detected!\n";
altitude = 0;
}
// aircraft gorund speed in km/h
float speed;
// aircraft track in degreees
float track;
try {
speed = knot_to_km(craft["gs"].get<float>());
track = craft["track"].get<float>();
} catch(...) {
std::clog << YELLOW"[WARNING]" RESET " aircraft with no ground speed or track data detected!\n";
speed = 0;
}
draw::color_t color= get_altitude_color(altitude);
try {
const auto [x_offset,y_offset] = get_offset_from_station(craft["lat"].get<double>(), craft["lon"].get<double>());
@@ -119,7 +133,18 @@ int main() {
#endif
const uint16_t x_center = middle_x+((x_offset/1000)*pixels_per_km);
const uint16_t y_center = middle_y+((y_offset/1000)*pixels_per_km);
draw::pixel(x_center, y_center, color);
// draw::pixel(x_center, y_center, color);
//speed in pixels per hour
const float speed_pph = speed* pixels_per_km;
// lenght of Time-Based Vector
const float vector_lenght = (speed_pph/60) * CONFIG_TIME_BASED_VECTOR_LENGHT;
// track in radians
const float track_rad = std::fmod((track-90),365.0f) * (static_cast<float>(std::numbers::pi)/180.0f);
draw::line(x_center, y_center,x_center + (vector_lenght*std::cos(track_rad)), y_center + (vector_lenght*std::sin(track_rad)), color);
draw::rhombus(x_center, y_center, 8/*TODO: remove magic*/,color);
} catch(...) {
std::clog << YELLOW"[WARNING]" RESET " aircraft with no lat/lon data detected!\n";