add time based vector and DRM support
This commit is contained in:
@@ -55,6 +55,14 @@ config TIME_BASED_VECTOR_LENGHT
|
||||
For example if set to 2 minutes the line will end where the plane be in 2 minutes,
|
||||
if direction and speed does not change.
|
||||
|
||||
config VECTOR_FOLLOW_TRACK_RATE
|
||||
bool "Time based vector follows change of track"
|
||||
default 1
|
||||
help
|
||||
Make Time based vector follows change of track of aircraft.
|
||||
This option will turn the vector from line into curve.
|
||||
This is of course be more computationaly expensive.
|
||||
|
||||
comment "Receiver configuration"
|
||||
|
||||
config FALLBACK_LAT
|
||||
@@ -76,3 +84,70 @@ config METRIC
|
||||
default y
|
||||
help
|
||||
Show altitudes in meters instead of feet.
|
||||
|
||||
comment "Platform dependent options"
|
||||
|
||||
choice
|
||||
prompt "Build target"
|
||||
default BUILD_LINUX
|
||||
help
|
||||
Select platform you want p-rad to be compiled for.
|
||||
|
||||
config BUILD_LINUX
|
||||
bool "Linux"
|
||||
|
||||
config BUILD_PICO
|
||||
bool "PI pico W"
|
||||
|
||||
config BUILD_OTHER_UNIX
|
||||
bool "Other Unix/Posix compatable system (NOT IMPLEMENTED)"
|
||||
endchoice
|
||||
|
||||
|
||||
|
||||
if BUILD_LINUX
|
||||
|
||||
|
||||
choice
|
||||
prompt "SDL render target"
|
||||
default SDL_TARGET_WINDOW
|
||||
help
|
||||
Select where you want SDL3 to render to.
|
||||
|
||||
config SDL_TARGET_WINDOW
|
||||
bool "Full-Screen Window"
|
||||
help
|
||||
Render to Full-Screen Window using window system like X11 or wayland.
|
||||
|
||||
config SDL_TARGET_KMSDRM
|
||||
bool "Direct to DRM"
|
||||
help
|
||||
Render directly to GPU using kmsdrm
|
||||
endchoice
|
||||
|
||||
|
||||
|
||||
endif
|
||||
|
||||
if BUILD_LINUX || BUILD_OTHER_UNIX
|
||||
|
||||
config SDL_DRIVERS
|
||||
string "Enabled SDL3 render drivers"
|
||||
default "gpu,vulkan,opengl"
|
||||
help
|
||||
Comma-speparated list of drivers,
|
||||
SDL will try each name, in the order listed, until one succeeds or all of them fail.
|
||||
leave empty and SDL will attempt to choose the best option for you,
|
||||
based on what is available on the your system.
|
||||
(I dont recommend leaving this option empty.)
|
||||
Available drivers can be listed by running this code:
|
||||
#include <SDL3/SDL.h>
|
||||
int main() {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Log("Available renderer drivers:");
|
||||
for (int i = 0; i < SDL_GetNumRenderDrivers(); i++) {
|
||||
SDL_Log("%d. %s", i + 1, SDL_GetRenderDriver(i));
|
||||
}
|
||||
}
|
||||
|
||||
endif
|
||||
|
||||
@@ -3,3 +3,7 @@ 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
+129
-57
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user