From 2017732c1ce06108ebf3c6518b1da5adae095846 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Sat, 20 Jun 2026 22:42:02 -0700 Subject: [PATCH] make shure that all changes were reflected in the .md file --- 01_classes.md | 38 ++++++++++++ 02_text_description.md | 54 +++++++++++++++++ 03_setup_and_radar_selection.md | 62 ++++++++++++++++++++ README.md | 101 +++++++++++++++++++++++++++++++- 4 files changed, 253 insertions(+), 2 deletions(-) diff --git a/01_classes.md b/01_classes.md index 6068329..4259130 100644 --- a/01_classes.md +++ b/01_classes.md @@ -167,3 +167,41 @@ struct target_data_to_thread_1_structure { uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft }; +=============================================================================== + +CURRENT IMPLEMENTATION STATUS (stub phase) + +Files: include/01_classes.h, src/01_classes.cpp + +What is built: + + RadarBase — abstract base class with three pure virtual methods: + render_left_panel() — renders radar description and keyboard control list + render_scope() — renders scope content (stub: radar name + "stub" label) + render_status_bar() — renders current control uniform values + + Four stub subclasses, each overriding all three methods: + ChainHomeRadar (Ventnor, Isle of Wight) + MarineAScopeRadar (Community Boating Center, Bellingham Bay) + MarineTrafficRadar (center of Bellingham Bay) + PoliceboatRadar (Taylor Dock / Boulevard Park, Bellingham Bay) + + One global instance of each subclass is declared in 01_classes.h and defined + in 01_classes.cpp: g_chain_home, g_marine_ascope, g_marine_traffic, g_police_boat. + +What is NOT yet built (future components): + - Real scope rendering (radar sweep, target blips, graticule, range rings/ticks, + north indicator, P7 persistence layer, land/terrain background) + - Target data ingestion from Traffic Cop + - The Keyboard controls class (keyboard handling currently lives in the + static key_callback() function in src/main.cpp) + - The Traffic Cop class (Thread 2) — not yet started + - The Simulator class (Thread 3) — not yet started + - Per-frame update() method — the 30 Hz render loop in main.cpp calls + render_left_panel(), render_scope(), and render_status_bar() directly + +Both target data structures (target_data_structure and +target_data_to_thread_1_structure) are defined in +include/data_structure_and_constants.h and will be used when the +Traffic Cop and Simulator components are built. + diff --git a/02_text_description.md b/02_text_description.md index 653a79d..40ba9e2 100644 --- a/02_text_description.md +++ b/02_text_description.md @@ -69,3 +69,57 @@ field: instructs the user to use the 1 and 2 keyboard keys to select the radar. The 1 key steps forward in a circle and the 2 key steps backward and the enter key makes the selection + +=============================================================================== + +CURRENT IMPLEMENTATION STATUS + +This spec covers two related but distinct pieces of the 02_text_description component: + +A. Text renderer engine + Files: include/02_text_description.h, src/02_text_description.cpp + Status: COMPLETE + + Implements the TextRenderer class using FreeType. Loads printable ASCII glyphs + (codes 32-126) from a TTF font into individual GL_RED textures and renders them + as textured quads into whichever viewport is currently active. + + Public methods: + initialize_shaders() — compiles/links shaders/02_text_description_{vert,frag}.glsl + initialize_font(path, size) — loads a TTF font at a given pixel height + render_text() — renders a string at a viewport-local pixel coordinate + render_text_wrapped() — renders with automatic word-wrapping at a max pixel width + get_text_width() — returns the pixel width of a string at a given scale + set_projection(w, h) — sets the orthographic projection for a viewport + cleanup() — releases all GL resources and glyph textures + + Two global instances are defined in src/02_text_description.cpp and declared + extern in the header: + g_text_renderer — loaded at FONT_SIZE_NORMAL (body text, controls, status bar) + g_text_renderer_large — loaded at FONT_SIZE_TITLE (panel titles, scope headings) + + Font path and sizes are defined in include/settings.h: + FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" + FONT_SIZE_NORMAL 18 px + FONT_SIZE_TITLE 26 px + +B. Left-panel text content for each radar + File: src/01_classes.cpp (render_left_panel() methods in each radar subclass) + Status: STUB — text content implemented; actual scope rendering is not yet done. + + Each radar subclass in 01_classes renders: + - Radar title (large renderer, white) + - Location sub-header (small scale, white) + - 3-4 lines of description text (white) + - "--- CONTROLS ---" header (red) followed by per-control entries + (label in red, keystroke(s) in pink, on the same line) + - "1 - Return to Radar Selection" (yellow) + + The intro scene (item 5 above) is rendered by render_intro_left_panel() in + src/main.cpp, which shows a welcome paragraph on the left panel and the + radar selection list centred in the scope viewport. + + Status bar content for each radar is rendered by render_status_bar() in + src/01_classes.cpp, displaying current uniform values (intensity, sensitivity, + STC sensitivity/range, and radar-specific values such as max range, cursor + positions, radiogoniometer, or antenna bearing) in yellow. diff --git a/03_setup_and_radar_selection.md b/03_setup_and_radar_selection.md index a235f95..1223474 100644 --- a/03_setup_and_radar_selection.md +++ b/03_setup_and_radar_selection.md @@ -33,3 +33,65 @@ The following is suggested. 5. Run in a loop where every 30th of a second, update the selected radar. ====================================================================== + +CURRENT IMPLEMENTATION STATUS + +File: src/main.cpp +Status: COMPLETE (stub phase) + +The five-step flow described above is fully implemented in main(): + + Step 1 — parse_args() + Parses argv[] for radar names (chain_home, marine_ascope, marine_traffic, + police_boat). Sets radar_management[].available for each named radar. + With no arguments, all radars are made available. + + STUB NOTE: The current build unconditionally sets operatable=1 for all four + radars before checking availability. When real radar components are built, + only the ones that are fully implemented should have operatable set to 1. + The check "available only if operatable" already works correctly in the code; + only the stub's operatable override needs to be updated. + + Step 2 — GLFW / GLAD / OpenGL initialization + Creates a 1920x1080 window (WINDOW_WIDTH x WINDOW_HEIGHT from settings.h), + initialises GLAD, enables GL_DEBUG_OUTPUT (controlled by ENABLE_GL_DEBUG_OUTPUT + in settings.h), and sets global GL state (blending, no depth test). + + Step 3 — Intro / selection screen + Renders the welcome text on the left panel (render_intro_left_panel()) and + the radar selection list centred in the scope viewport (render_radar_list()). + The status bar shows keyboard instructions (render_selection_status_bar()). + + Step 4 — Selection loop + The GLFW key callback (key_callback) handles: + - Key 1: step selection forward + - Key 2: step selection backward + - ENTER: activate the highlighted radar; call reset_radar_controls() + - ESC: close the window + If exactly one radar is available, the application auto-activates it after + 5 seconds (shows the selection screen during the countdown; breaks early + if ENTER is pressed). + + Step 5 — Main render loop (~30 Hz) + Uses std::chrono::steady_clock to target a 1/30 s frame period. + Each frame: + - Polls GLFW events + - If SELECTION state: calls render_selection_screen() + - If OPERATING state: calls render_operating_screen(), which delegates + to g_active_radar->render_left_panel(), render_status_bar(), + render_scope() through the RadarBase virtual interface. + + Additional features implemented: + - GL debug callback (gl_debug_callback) enabled via ENABLE_GL_DEBUG_OUTPUT + - Debug border-box renderer (draw_border_box) enabled via DEBUG_DRAW_WINDOW_BORDERS + in settings.h — draws white outlines around each panel for layout verification + - reset_radar_controls(): resets uniform_max_range, uniform_range_cursor, + uniform_bearing_cursor to defaults for the selected radar when it is activated + - Keyboard controls for all scope uniforms (intensity, sensitivity, STC, noise + filter, radiogoniometer, max range, range cursor, bearing cursor, antenna + rotation) are implemented in key_callback(); the controls are appropriately + restricted by radar type (e.g. noise filter only for PPI scopes) + + Application state is tracked by AppState enum (SELECTION, OPERATING) in main.cpp. + The active radar object is pointed to by g_active_radar (a RadarBase*). + current_radar (global in global_data.cpp) holds the RADAR_* index of the active radar. diff --git a/README.md b/README.md index 45f9e02..9b5200a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,100 @@ -# radar-simulation +# radar-simulator -Source code for possible radar exhibit \ No newline at end of file +Museum exhibit software simulating 1940s–1960s vintage radar systems. + +## Project overview + +This application runs as a full-screen interactive exhibit on a Geekom A8 Max +(AMD Ryzen 9 8945HS, Radeon 780M GPU, Ubuntu 25.10). Visitors can explore four +historical radar types by cycling through a selection screen and interacting with +keyboard controls. + +**Four radar displays:** + +| # | Name | Type | Location | +|---|------|------|----------| +| 1 | Chain Home | A-scope (WWII, 1940s) | RAF Ventnor, Isle of Wight | +| 2 | Marine A-Scope | A-scope (pre-PPI, manually steered dish) | Community Boating Center, Bellingham Bay WA | +| 3 | Marine Traffic Control | PPI scope | Center of Bellingham Bay WA | +| 4 | Police Boat | PPI scope (moving platform) | Taylor Dock / Boulevard Park, Bellingham Bay WA | + +## Tech stack + +- **Language:** C++20 +- **Graphics:** OpenGL 4.3 Core, GLFW, GLAD +- **Text:** FreeType 2 +- **Maps/LIDAR:** GDAL (libgdal-dev) +- **Database:** PostgreSQL (database: radar, user: radar) +- **Build:** CMake + +## Build + +```bash +mkdir -p build && cd build +cmake .. +make -j$(nproc) +``` + +The executable is `build/radar_simulator`. + +## Running + +```bash +# All four radars available +./radar_simulator + +# Specific radars only +./radar_simulator chain_home marine_ascope +./radar_simulator marine_traffic police_boat +``` + +If only one radar is specified, it auto-activates after 5 seconds. + +## Screen layout + +The window is 1920×1080 and is divided into three areas: + +- **Left text panel** (upper-left, 500 px wide): radar description and keyboard controls +- **Status bar** (lower-left, 500×250 px): current control values in yellow +- **Scope** (right side, square, full height): radar display + +## Keyboard controls + +| Key | Action | +|-----|--------| +| **1** | Step forward in radar selection (or return to selection when operating) | +| **2** | Step backward in radar selection | +| **ENTER** | Activate selected radar | +| **ESC** | Exit | +| **3 / 4** | Intensity lower / higher | +| **5 / 6** | Receiver sensitivity lower / higher | +| **Q / W** | STC sensitivity lower / higher | +| **E / R** | STC range lower / higher | +| **T / Y** | Rain noise filter lower / higher (PPI scopes only) | +| **U / I** | Radiogoniometer left / right (Chain Home only) | +| **O / P** | Max range step down / up (all except Chain Home) | +| **A / S** | Range cursor lower / higher (PPI scopes only) | +| **D / F** | Bearing cursor CCW / CW (PPI scopes only) | +| **G / H** | Antenna rotation CCW / CW (Marine A-Scope only) | + +## Component .md files + +Each component has a specification and status file: + +- `01_classes.md` — class hierarchy (RadarBase + 4 subclasses; stubs built) +- `02_text_description.md` — text renderer and left-panel text content (complete) +- `03_setup_and_radar_selection.md` — startup, selection loop, main render loop (complete) + +## Current build state + +The initialization and radar-management infrastructure is complete: + +- Four stub radar subclasses render description text, keyboard control lists, + and current control values in the status bar. +- The scope area shows the radar name with a `[stub]` label — no actual radar + simulation is drawn yet. +- All keyboard controls update CPU globals; uniforms will be pushed to shaders + as each scope component is built. + +Real radar scope rendering (sweep, targets, graticule, range rings/ticks, +terrain, P7 phosphor persistence) will be added one radar at a time.