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,
|
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.
|
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"
|
comment "Receiver configuration"
|
||||||
|
|
||||||
config FALLBACK_LAT
|
config FALLBACK_LAT
|
||||||
@@ -76,3 +84,70 @@ config METRIC
|
|||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Show altitudes in meters instead of feet.
|
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) {
|
static inline T feet_to_meters(T ft) {
|
||||||
return static_cast<T>(ft * 0.3048);
|
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 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 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 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);
|
||||||
}
|
}
|
||||||
+91
-19
@@ -1,6 +1,8 @@
|
|||||||
#include "../core/const.hpp"
|
#include "../core/const.hpp"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
#include <SDL3/SDL_hints.h>
|
||||||
|
#include <SDL3/SDL_init.h>
|
||||||
#include <SDL3/SDL_iostream.h>
|
#include <SDL3/SDL_iostream.h>
|
||||||
#include <SDL3/SDL_mouse.h>
|
#include <SDL3/SDL_mouse.h>
|
||||||
#include <SDL3/SDL_rect.h>
|
#include <SDL3/SDL_rect.h>
|
||||||
@@ -14,6 +16,8 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../core/color.h"
|
||||||
|
#include "core/config.hpp"
|
||||||
#include "draw.hpp"
|
#include "draw.hpp"
|
||||||
#include "hal/hal.hpp"
|
#include "hal/hal.hpp"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
@@ -22,7 +26,7 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "../core/color.h"
|
|
||||||
struct sdl_session {
|
struct sdl_session {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
@@ -34,16 +38,53 @@ CURL *curl;
|
|||||||
|
|
||||||
namespace hal {
|
namespace hal {
|
||||||
int init() {
|
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());
|
mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());
|
||||||
|
if (!mode) {
|
||||||
|
SDL_Log("failed to get display mode: %s", SDL_GetError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
main_sdl_session.window =
|
main_sdl_session.window =
|
||||||
SDL_CreateWindow(program_name, mode->w, mode->h, SDL_WINDOW_FULLSCREEN);
|
SDL_CreateWindow(program_name, mode->w, mode->h, SDL_WINDOW_FULLSCREEN);
|
||||||
main_sdl_session.renderer =
|
if (!main_sdl_session.window) {
|
||||||
SDL_CreateRenderer(main_sdl_session.window, "gpu,vulcan");
|
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();
|
curl = curl_easy_init();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<uint16_t, uint16_t> get_screen_size() { return {mode->w, mode->h}; }
|
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;
|
const Uint64 frame_delay_ns = 1000000000ULL / 1;
|
||||||
void end_frame() {
|
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);
|
SDL_RenderPresent(main_sdl_session.renderer);
|
||||||
|
|
||||||
@@ -83,11 +144,13 @@ void filled_rect(const rect_t *rect, const color_t color) {
|
|||||||
SDL_RenderFillRect(main_sdl_session.renderer, &frect);
|
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,
|
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
|
||||||
0xff);
|
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;
|
int x = radius, y = 0;
|
||||||
|
|
||||||
// Printing the initial point on the axes
|
// Printing the initial point on the axes
|
||||||
@@ -96,8 +159,7 @@ void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radi
|
|||||||
|
|
||||||
// When radius is zero only a single
|
// When radius is zero only a single
|
||||||
// point will be printed
|
// point will be printed
|
||||||
if (radius > 0)
|
if (radius > 0) {
|
||||||
{
|
|
||||||
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, 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);
|
||||||
@@ -106,18 +168,16 @@ void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radi
|
|||||||
|
|
||||||
// Initialising the value of P
|
// Initialising the value of P
|
||||||
int P = 1 - radius;
|
int P = 1 - radius;
|
||||||
while (x > y)
|
while (x > y) {
|
||||||
{
|
|
||||||
y++;
|
y++;
|
||||||
|
|
||||||
// Mid-point is inside or on the perimeter
|
// Mid-point is inside or on the perimeter
|
||||||
if (P <= 0)
|
if (P <= 0)
|
||||||
P = P + 2*y + 1;
|
P = P + 2 * y + 1;
|
||||||
// Mid-point is outside the perimeter
|
// Mid-point is outside the perimeter
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
x--;
|
x--;
|
||||||
P = P + 2*y - 2*x + 1;
|
P = P + 2 * y - 2 * x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All the perimeter points have already been printed
|
// All the perimeter points have already been printed
|
||||||
@@ -133,8 +193,7 @@ void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radi
|
|||||||
|
|
||||||
// If the generated point is on the line x = y then
|
// If the generated point is on the line x = y then
|
||||||
// the perimeter points have already been printed
|
// the perimeter points have already been printed
|
||||||
if (x != y)
|
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);
|
||||||
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, -x + y_center);
|
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, -x + y_center);
|
||||||
@@ -143,12 +202,25 @@ void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
|
||||||
0xff);
|
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));
|
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 draw
|
||||||
|
|
||||||
namespace net {
|
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 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 draw
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|||||||
+26
-1
@@ -8,8 +8,10 @@
|
|||||||
#include "nlohmann/json_fwd.hpp"
|
#include "nlohmann/json_fwd.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cmath>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <numbers>
|
||||||
#include "core/global.hpp"
|
#include "core/global.hpp"
|
||||||
#include "core/geo.hpp"
|
#include "core/geo.hpp"
|
||||||
#include "core/gfx.hpp"
|
#include "core/gfx.hpp"
|
||||||
@@ -106,6 +108,18 @@ int main() {
|
|||||||
std::clog << YELLOW"[WARNING]" RESET " aircraft with no alt data detected!\n";
|
std::clog << YELLOW"[WARNING]" RESET " aircraft with no alt data detected!\n";
|
||||||
altitude = 0;
|
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);
|
draw::color_t color= get_altitude_color(altitude);
|
||||||
try {
|
try {
|
||||||
const auto [x_offset,y_offset] = get_offset_from_station(craft["lat"].get<double>(), craft["lon"].get<double>());
|
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
|
#endif
|
||||||
const uint16_t x_center = middle_x+((x_offset/1000)*pixels_per_km);
|
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);
|
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);
|
draw::rhombus(x_center, y_center, 8/*TODO: remove magic*/,color);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
std::clog << YELLOW"[WARNING]" RESET " aircraft with no lat/lon data detected!\n";
|
std::clog << YELLOW"[WARNING]" RESET " aircraft with no lat/lon data detected!\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user