From 12418abf5128febfcc8127de2eb829eec204203e Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Mon, 8 Jun 2026 20:23:37 -0700 Subject: [PATCH] Initial setup for project, preparing for first component --- CLAUDE.md | 382 +++++++++++++++++++++++++ global_data.cpp | 112 ++++++++ include/data_structure_and_constants.h | 178 ++++++++++++ include/settings.h | 128 +++++++++ 4 files changed, 800 insertions(+) create mode 100644 CLAUDE.md create mode 100644 global_data.cpp create mode 100644 include/data_structure_and_constants.h create mode 100644 include/settings.h diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b35e699 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,382 @@ +This is a project for a museum to demonstrate a simulation of a 1940's to 1960's +vintage radar, including the Chain Home radar from early World War 2, marine radar +at a marine traffic control station, and marine radar on a boat. + +The project will be implemented on a Geekom A8 Max +32 GB RAM +AMD Ryzen 9 8945HS w/ Radeon 780M Graphics +We need to render to the Radeon 780M Graphics GPU + +Tech Stack: We are using C++20, OpenGL 4.3 Core, GLFW, GLAD, FreeType, GDAL (libgdal-dev) +Compiler: is g++ (Ubuntu 15.2.0-4ubuntu4) 15.2.0 + +Coding will be done using the c++ language for the CPU + +GPU coding will be GLSL (as required by OpenGL) + +FreeType is the text type we use +GDAL is used for reading the LIDAR/ENC chart files +GLFW (graphics library framework) open-source, multi-platform library used to manage windows +GLAD (Multi-Language GL/GLES/WGL/GLX Loader-Generator) Loads the pointers to + OpenGL functions (like glDrawArrays or glCompileShader) + +PostgreSQL is installed. Database: radar. User: radar. Password: radar. +User has full privileges on database radar. Table is target_data. + +Operating system details: + +Distributor ID: Ubuntu +Description: Ubuntu 25.10 +Release: 25.10 +Codename: questing + +Use cmake for building. + +[DIRECTIVE: GPU ROBUSTNESS PROTOCOL] + +Debug Callback: Enable GL_DEBUG_OUTPUT and glDebugMessageCallback +to capture driver-level warnings and errors in real-time. + +I will be using SSH from Windows to write code and check with claude. +You may compile the code during an SSH session. +Please do not try to run the code during SSH session. +I will run the code while physically using the Geekom. + +Please add MIT license header to each file +Please add Author: Mark Allyn to each file + +Use snake_case for variables and PascalCase for classes +use #pragma once +Use // for single line comments +use /* */ for multiple block comments spanning multiple lines +avoid using auto + +================================================================== + +SYSTEMWIDE INCLUDE FILE AND GLOBAL DATA FILE + +This file is located at /include/data_structure_and_constants.h + +There will be a system wide include header file for constants and +data structures + +For each entry in this file (which may be added piecemeal, a comment +needs to be in place with the name of the components that uses that +constant or data structure. Note that these comments will be updated +as I add new components to be built. + +SYSTEMWIDE GLOBAL DATA FILE + +There will be a file containing global data items. + +The file is at global_data.cpp + +For each entry in this file (which may be added piecemeal, a comment +needs to be in place with the name of the components that uses that +constant or data structure. Note that these comments will be updated +as I add new components to be built. + +SYSREMWIDE TESTING AND SETTINGS INCLUDE FILE + +The system wide testing and configuation file, located at include/settings.h + +The values for each component shall be preceded by the session name +as a comment. It shall be included in all components. + +Please use this file for defines and variables that I can +change and do a simple re-compile instead of having the ai re write the +code. This is for debugging. For example, I may want to disable the p7 persistance +to troubleshoot the actual target processnig before it goes to persistance, +disable the land and terrain so that I can see the targets alone. Things like +that. + + + +================================================================== + +PIECEMEAL BUILDING + +This project will be built piecemeal. Each components will be build by itself an integrated +with components that have been already built. + +Each component will have its own .md file for instructions and specifications. + +As a component is built and tested, I wil add a statement at the end of it's +.md file, looking like "COMPONENT DONE" + +Please note that each component shall have it's own c++ file; its own .h file; +and it's own sets for shaders. Full independance. + +================================================================== + +TEMPORARY TESTING FILES + +As each component if built, I may ask for temporary files to be created +for testing of the component. For example, I may ask for targets on a radar +before any target handling code is made. + +I will indicated what is needed to be built. And when I am done testing, I will +instruct that that file be deleted. These instructions will be done during the +dialog with claude code. + +=================================================================== + +HANDLING COMPILE AND BUILD OF SHADEARS DURIANG PIECEMEAL BUILDING + +As you know, all shaders are to be built and loaded at the beginning +of the application. + +I propose that each components will have it's own code for making the linking +its shaders as a function that will be called by the system's initialization code. + +==================================================================== + +Summary of project: + +This is a museum exhibit displaying and providing some interaction +of vintage 1940's, 1950's, and 1960's radars. A key objective is to +provide interaction with and viewing of radars from that era. + +The name of the application (the name of it's executable file) shall be +radar_simulator. Therefore, if you are in the directory in which the executable +is compiled, which in this case would be the build subdirectory of the project +directory, you would type ./radar_simulator, or use a full path name +of {PROJECT_DIR}/build/radar_simulator. + +In the CMakeLists.txt, plese use the name radar_simulator for the add_executable call. + +There will be three main areas of the screen. On the right hand side will be the radar +scope. + +On the left hand side of the screen will be a text description of the scope as well +as the controls of the scope and keyboard keys for each control. This text will be +white while the control labels will be red and the keystrokes will be in pink. +At some point, pending a decision with the museum, we may purchase components to mount the controls on a panel. Until that is done, the controls will be on the keyboard. + +On the right hand side of the screen, below the scope, would be a text status window, showing current +maximum range, range, and bearing as appropriate to which scope we are using as well as the identification +of the scope that we are using. + +Suggest that we use glViewport to define the left-hand text area, the main scope, +and the yellow status bar. This allows you to render the scope with its own coordinate +system while keeping the text fixed. Along with glViewport, use glScissor and glEnable(GL_SCISSOR_TEST) + +Below the scope will be a text status window. This text will be yellow + +Scopes in the right panel + +1. Introduction of Exhibit (Explanation of the project on the left hand text panel. +2. A-scope for Chain Home Radar in the 1940's (first radar and could be tricky) +3. A-scope for marine radar in the 1940's (Before PPI radar); was a bit tedious to operate +4. PPI scope for marine traffic control (uses beam sweeping in all 360 degrees of + rotation); Easier to use than a scope +5. PPI scope on board a boat. Shows how movement of a boat affects the radar display + +Please note that these scopes will not appear all at once. The selection of which scope +the visitor sees is done by pressing a forward control and a reverse control to go around +the loop of scopes. The first display when the system is turned on or booted up is the +Introduction of the exhibit. + + +===================================================================== + +CONTROL DEFINITIONS + +Please note that the first iteration of the project will have only minimal controls. +This is a suggestion I got after meeting with the museum staff. Perhaps later we may +add more controls. + +Also, please note that the state of the controls of each scope is independent of any +other scope. Furthermore, the controls will reset when a scope is exited and then re-entered. + +Controls to affect the behavior of the scopes; (these first implemented using keyboard +strokes; later when and if physical controls are completed, the keyboard controls will be removed) +These controls will affect the state variables and the uniform variables of the shaders. + +Please note that identical controls will be the same keyboard strikes or physical controls for all scopes. + +======================================================= +Overall control information + +These are knobs on the panel once that is built. Keyboard keys until then + +1. Intensity - scope overall intensity - Keyboard 3 is lower; 4 is higher - uniform is float intensity; +2. Receiver Sensitivity - signal intensity - Keyboard 5 is lower; 6 is higher - uniform is float sensitivity; +3. STC Sensitivity - sensitivity for closer in targets which can overwhelm + overall sensitivity - keyboard q for lower; w for higher - uniform is float stc_sensitivity; +4. STC Range - range to which sensitivity to closer targets is effective + keyboard e for lower; r for higher - uniform is float stc_range; +5. Noise filter for rain noise. This is for the ppi scopes. keyboard t for decrease filtering and y + to increase filtering - uniform is float noise_filter; +6. Radiogoniometer knob for Chain Home; keyboard u for left turn; + i for right turn. - uniform is float radiogoniometer; +7. Maximum Range for all scopes except for chain home, which is fixed. This control + will not operate for Chain Home. These maximum + range selections will be defined for each scope; If you try to go beyond the stated + maximum ranges, the control will have no effect; note that the default maximum range would + be the highest for that scope; keyboard o for lower; p for higher uniform is float max_range; +8. Range Cursor (for ppi scopes, not for a scopes) + keyboard a for lower; s for higher - uniform is float range_cursor; +9. Bearing Cursor (for all ppi scopes; not for a scopes) + keyboard d for counterclockwise f for clockwise uniform is float bearing_cursor; +10. Bearing for Marine A Scope. This is not for a cursor, but this operates the motor + that revolves the antenna unit keyboard g for counterclockwise and h for clockwise + uniform is float marine_a_bearing; + +Notes; I am maintaining control separation between radiogon, marine a scope bearing, and ppi bearing. +However, when I make the control panel, those will be combined as one physical knob with three +labels, chain home radiogon, marine a scope antenna rotation, and ppi scope bearing to save on +hardware; the same physical control can be used for multiple scopes. + +Note that the range cursor is different from the maximum range. Maximum range is the maximum +radar range setting and range cursor is the range portion of the ppi cursor. + +Note that these are to be implimented as I work on each component. You cannot impliment all of these +at the beginning as there will be no shaders for the uniforms + +Note that a copy of each uniform shall be maintained in the global_data.cpp file. + +=================================================================== + +Some data structures from my previoius work that should be relavent: + +All targets from the network pipeline and simulator map to this C master structure: + +struct target_data_structure { + double target_longitude; + double target_latitude; + std::string vessel_name; // will be null for no available name + std::string registration; // will be null for no registration + float length; // in meters + float beam; // in meters + int vessel_type; // AIS type code or aircraft type + uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft + float course; // course over ground, degrees, based on true north + float speed; // speed over ground, knots + float altitude; // meters, but 0 for boats + int type; // type of target; vessel or aircraft; 0 = vessel + int police_boat // 1 is police boat; 0 is not + time_t timestamp; +}; + +Of this heavy structure, only the following lean mathematical footprint is submitted +to the graphics shaders via an OpenGL Shader Storage Buffer Object (SSBO) layout(std430): + + +ssbo_target_information { // This is what is sent to the shaders as SSBO + float target_x; // Pre-converted local Cartesian offset X (meters relative to radar) + float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar) + float length; // Vessel length bounds (meters) + float beam; // Vessel beam bounds (meters) + float course; // Course over ground vector (radians relative to True North) + float altitude; // Target altitude profile (meters = 0 for boats) + time_t timestamp; // Data aging tracking identifier + float current_reflectivity; // derivied from vessel_type (see table below) + float height_estimate; // derived from vessel_type (see table below) + float noiseglint; // derived from vessel_type (see table below) + int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat + uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft + int type; // target type (0 for boat 1 for aircraft) +}; + +This is the structure sent to the software to send to the shaders. It does include the +text (string) values, but those are stripped off prior to being sent to the shaders. + +struct target_data_to_thread_1_structure { + float target_x; // Pre-converted local Cartesian offset X (meters relative to radar) + float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar) + std::string vessel_name; // will be null for no available name + std::string registration; // will be null for no registration + float length; // Vessel length bounds (meters) + float beam; // Vessel beam bounds (meters) + float course; // Course over ground vector (radians relative to True North) + float altitude; // Target altitude profile (meters = 0 for boats) + time_t timestamp; // Data aging tracking identifier + float current_reflectivity; // derived from calculation based on material - is dynamic + float height_estimate; // derived from vessel_type (see table below) + float noiseglint; // derived from vessel_type (see table below) + int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat + int type; // target type (0 for boat 1 for aircraft) + uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft +}; + +Please note that height and material are not included in the data received from the simulator +nor the raspberry pis. This has to be derived. That will be discussed when I talk about the +traffic cop component. + +Please note that the ssbo_target_information +data structure does not include the vessel_name nor the registration. +Those do not go to the shaders. + +Here is the data items for the table in the Postgres database: + +1. float length +2. float beam +3. int32_t may_need_update (this if a randome value is applied to any part of the target + and that the user may want to update the database. This + will not force the user to do the update, a later + database editing program will use this. +4. int vessel_type (AIS type code or aircraft type) +5. int type (1 for airplane, 0 for boat) +6. uint32_t mmsi (unique identification for boat or ICAL for aircraft +7. float reflectivity (derived from target type) +8. float height_estimate (derived from target type) +9. float noiseglint (derived from target type_ +10. std::string vessel_name; +11. std::string registration; +12. int32_t police_boat (this indicates that this is for the police boat - 1 is true) + +Please note that this database is only for the physical characteristics. Dynamic +information which is created by the simulator (or raspberry pis) as that data changes. + +===================================================================== + +THE THREAD INFORMATION + +I don't know how the mutex data is handled in an include file or global data; + +This is the outline of the threads that I know so far. We add those as needed when we +get to the components that need them. + +Now, lets discuss the threads. There will be five threads: + +Thread 1 = Operation of setting up the system; ie; initializeing Opengl, + compiling, building, and loading all of the shaders. It also handles + the keyboard operation of the radar controls as those are callbacks from + the OpenGL. Accepting target traffic from the Traffic Cop will be performed, + however, the Traffic Cop will need to assert mutex-target-data in order to write any + target data to this Thread 1. + + Please note that this thread also includes the hit_test as noted below. + +Thread 2 = Traffic Cop. The Traffic Cop will accept Target Data from the Simulator (which + will be discussed here) ; and the AIS and ADS(b) data from the raspberry pis. At + this time, we need to provide only a stub withing the traffic cop to access the Raspberry pis. + The traffic cop will need to set a mutex-target-data before + handing radar traffic to the Thread 1 software + which will send the radar data on to the shaders. Note that the traffic cop needs to do + the following processing with target data: + + 1. Convert the GPS longitude information to the local coordinates for each radar. + 2. Check and discard targets that are outside the range of the radar that is + currently being used. + 3. Discard targets whose timestamp is older than 1 hour + +Thread 3 = Simulator. The simulator creates and manages the simulated targets. It needs to + assert mutex-simulator-to-traffic-cop to transfer target information to the Traffic cop + +Thread 4 = Physical controls, knobs and switches. This has not been developed and will not + be developed with the current version of the project. It will be developed later. It + does need to set a mutex-control-data-to-shaders in order to send control + information to Thread 1 so that thread + can set the state variables and the uniforms for the controls in the shaders. + +Thread 5 = Raspberry pi data recever = this receives the data from the raspberry pis. It will + not be developed for the current version of the project. The Raspberry PI receiver will + need to set mutex-raspberry-pi in order to transfer target data to the traffic cop. + +================================================================================ + + + + diff --git a/global_data.cpp b/global_data.cpp new file mode 100644 index 0000000..e0696ce --- /dev/null +++ b/global_data.cpp @@ -0,0 +1,112 @@ +/* + * MIT License + * + * Copyright (c) 2026 Mark Allyn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * global_data.cpp + * Author: Mark Allyn + * + * Definitions of all system-wide global variables. + * Extern declarations live in include/data_structure_and_constants.h. + */ + +#include "include/data_structure_and_constants.h" + +/* ============================================================ + * THREAD MUTEXES + * Components: all threads as noted per mutex + * ============================================================ */ + +// Thread 2 -> Thread 1: target data handoff +// Components: Traffic Cop (Thread 2), Thread 1 +std::mutex mutex_target_data; + +// Thread 3 -> Thread 2: simulator to traffic cop +// Components: Simulator (Thread 3), Traffic Cop (Thread 2) +std::mutex mutex_simulator_to_traffic_cop; + +// Thread 4 -> Thread 1: physical control panel data (not yet implemented) +// Components: Physical Controls (Thread 4), Thread 1 +std::mutex mutex_control_data_to_shaders; + +// Thread 5 -> Thread 2: Raspberry Pi receiver to traffic cop (not yet implemented) +// Components: Raspberry Pi Receiver (Thread 5), Traffic Cop (Thread 2) +std::mutex mutex_raspberry_pi; + +/* ============================================================ + * SHADER UNIFORM COPIES + * These are set by keyboard callbacks in Thread 1 and pushed to + * GLSL shader uniforms each frame render. + * Initial values are sensible defaults; adjust in include/settings.h + * as components are developed and tested. + * ============================================================ */ + +// Scope intensity — keyboard 3 (lower) / 4 (higher) +// GLSL uniform: float intensity +// Components: all scopes +float uniform_intensity = 1.0f; + +// Receiver sensitivity — keyboard 5 (lower) / 6 (higher) +// GLSL uniform: float sensitivity +// Components: all scopes +float uniform_sensitivity = 1.0f; + +// STC sensitivity for close-in targets — keyboard q (lower) / w (higher) +// GLSL uniform: float stc_sensitivity +// Components: all scopes +float uniform_stc_sensitivity = 0.5f; + +// STC effective range (normalized 0-1) — keyboard e (lower) / r (higher) +// GLSL uniform: float stc_range +// Components: all scopes +float uniform_stc_range = 0.3f; + +// Rain noise filter, PPI scopes only — keyboard t (decrease) / y (increase) +// GLSL uniform: float noise_filter +// Components: PPI scopes (marine traffic control, on-board boat) +float uniform_noise_filter = 0.0f; + +// Chain Home radiogoniometer bearing in degrees — keyboard u (left) / i (right) +// GLSL uniform: float radiogoniometer +// Components: Chain Home A-scope +float uniform_radiogoniometer = 0.0f; + +// Maximum radar range (scope-dependent units) — keyboard o (lower) / p (higher) +// GLSL uniform: float max_range +// Components: Marine A-scope, PPI scopes (not Chain Home; that is fixed) +float uniform_max_range = 1.0f; + +// Range cursor position (normalized 0-1) — keyboard a (lower) / s (higher) +// GLSL uniform: float range_cursor +// Components: PPI scopes (marine traffic control, on-board boat) +float uniform_range_cursor = 0.5f; + +// Bearing cursor in degrees — keyboard d (CCW) / f (CW) +// GLSL uniform: float bearing_cursor +// Components: PPI scopes (marine traffic control, on-board boat) +float uniform_bearing_cursor = 0.0f; + +// Marine A-scope antenna rotation bearing in degrees — keyboard g (CCW) / h (CW) +// GLSL uniform: float marine_a_bearing +// Components: Marine A-scope +float uniform_marine_a_bearing = 0.0f; diff --git a/include/data_structure_and_constants.h b/include/data_structure_and_constants.h new file mode 100644 index 0000000..779893f --- /dev/null +++ b/include/data_structure_and_constants.h @@ -0,0 +1,178 @@ +/* + * MIT License + * + * Copyright (c) 2026 Mark Allyn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * data_structure_and_constants.h + * Author: Mark Allyn + * + * System-wide data structures, constants, and extern declarations. + * Include this file in ALL CPU source code files. + */ + +#pragma once + +#include +#include +#include +#include + +/* ============================================================ + * TARGET DATA STRUCTURES + * Components: Traffic Cop (Thread 2), Simulator (Thread 3), + * Thread 1 (OpenGL / shader pipeline) + * ============================================================ */ + +/* Master target record populated from simulator or Raspberry Pi data. + * Components: Traffic Cop (Thread 2), Simulator (Thread 3) */ +struct target_data_structure { + double target_longitude; + double target_latitude; + std::string vessel_name; // empty if unavailable + std::string registration; // empty if unavailable + float length; // meters + float beam; // meters + int vessel_type; // AIS type code or aircraft type + uint32_t mmsi; // AIS unique identifier; ICAO hex for aircraft + float course; // degrees, true north + float speed; // knots + float altitude; // meters; 0 for surface vessels + int type; // 0 = vessel, 1 = aircraft + int police_boat; // 1 = police boat, 0 = not + time_t timestamp; +}; + +/* Lean SSBO payload uploaded to shaders via SSBO layout(std430). + * String fields are stripped before upload. + * Components: Thread 1 (shader upload), all radar scope shaders */ +struct ssbo_target_information { + float target_x; // Cartesian offset X, meters from radar + float target_y; // Cartesian offset Y, meters from radar + float length; // meters + float beam; // meters + float course; // radians, true north + float altitude; // meters; 0 for surface vessels + time_t timestamp; + float current_reflectivity; // derived from vessel_type + float height_estimate; // derived from vessel_type + float noiseglint; // derived from vessel_type + int32_t police_boat; // 1 = police boat + uint32_t mmsi; + int type; // 0 = vessel, 1 = aircraft +}; + +/* Intermediate payload passed from Traffic Cop to Thread 1. + * String fields are present here but stripped before SSBO upload. + * Components: Traffic Cop (Thread 2) -> Thread 1 */ +struct target_data_to_thread_1_structure { + float target_x; + float target_y; + std::string vessel_name; // stripped before SSBO upload + std::string registration; // stripped before SSBO upload + float length; + float beam; + float course; + float altitude; + time_t timestamp; + float current_reflectivity; + float height_estimate; + float noiseglint; + int32_t police_boat; + int type; + uint32_t mmsi; +}; + +/* ============================================================ + * THREAD MUTEXES + * Defined in global_data.cpp; extern declared here. + * ============================================================ */ + +// Thread 2 -> Thread 1: protects target data handoff +extern std::mutex mutex_target_data; + +// Thread 3 -> Thread 2: protects simulator-to-traffic-cop handoff +extern std::mutex mutex_simulator_to_traffic_cop; + +// Thread 4 -> Thread 1: protects physical control data (Thread 4 not yet implemented) +extern std::mutex mutex_control_data_to_shaders; + +// Thread 5 -> Thread 2: protects Raspberry Pi receiver data (Thread 5 not yet implemented) +extern std::mutex mutex_raspberry_pi; + +/* ============================================================ + * SHADER UNIFORM COPIES + * Defined in global_data.cpp; extern declared here. + * Components: Thread 1 (keyboard callbacks and per-frame uniform push), + * all radar scope shaders. + * Note: uniforms are implemented as each scope component is built. + * ============================================================ */ + +// Scope intensity — keyboard 3 (lower) / 4 (higher) +// GLSL uniform: float intensity +// Components: all scopes +extern float uniform_intensity; + +// Receiver sensitivity — keyboard 5 (lower) / 6 (higher) +// GLSL uniform: float sensitivity +// Components: all scopes +extern float uniform_sensitivity; + +// STC sensitivity for close-in targets — keyboard q (lower) / w (higher) +// GLSL uniform: float stc_sensitivity +// Components: all scopes +extern float uniform_stc_sensitivity; + +// STC effective range — keyboard e (lower) / r (higher) +// GLSL uniform: float stc_range +// Components: all scopes +extern float uniform_stc_range; + +// Rain noise filter, PPI scopes only — keyboard t (decrease) / y (increase) +// GLSL uniform: float noise_filter +// Components: PPI scopes (marine traffic control, on-board boat) +extern float uniform_noise_filter; + +// Chain Home radiogoniometer bearing — keyboard u (left) / i (right) +// GLSL uniform: float radiogoniometer +// Components: Chain Home A-scope +extern float uniform_radiogoniometer; + +// Maximum radar range, all scopes except Chain Home — keyboard o (lower) / p (higher) +// GLSL uniform: float max_range +// Components: Marine A-scope, PPI scopes +extern float uniform_max_range; + +// Range cursor, PPI scopes only — keyboard a (lower) / s (higher) +// GLSL uniform: float range_cursor +// Components: PPI scopes (marine traffic control, on-board boat) +extern float uniform_range_cursor; + +// Bearing cursor, PPI scopes only — keyboard d (CCW) / f (CW) +// GLSL uniform: float bearing_cursor +// Components: PPI scopes (marine traffic control, on-board boat) +extern float uniform_bearing_cursor; + +// Marine A-scope antenna rotation bearing — keyboard g (CCW) / h (CW) +// GLSL uniform: float marine_a_bearing +// Components: Marine A-scope +extern float uniform_marine_a_bearing; diff --git a/include/settings.h b/include/settings.h new file mode 100644 index 0000000..c73e84d --- /dev/null +++ b/include/settings.h @@ -0,0 +1,128 @@ +/* + * MIT License + * + * Copyright (c) 2026 Mark Allyn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * settings.h + * Author: Mark Allyn + * + * System-wide configuration and debug toggles. + * Include this file in ALL components. + * Change a value and recompile — no AI rewrite needed. + * + * Each section is labeled with the component name it governs. + */ + +#pragma once + +/* ============================================================ + * GENERAL / OPENGL DEBUG + * Component: Thread 1 (initialization) + * ============================================================ */ + +// 1 = enable GL_DEBUG_OUTPUT and glDebugMessageCallback at startup +#define ENABLE_GL_DEBUG_OUTPUT 1 + +/* ============================================================ + * THREAD 1 - OpenGL / Shader Init / Keyboard / Main Loop + * ============================================================ */ + +// 1 = print shader compile and link status to stdout +#define DEBUG_SHADER_COMPILE 1 + +/* ============================================================ + * THREAD 2 - Traffic Cop + * ============================================================ */ + +// 1 = print each target record received from simulator or Raspberry Pi +#define DEBUG_TRAFFIC_COP_INPUT 0 + +// 1 = print each target record handed off to Thread 1 +#define DEBUG_TRAFFIC_COP_OUTPUT 0 + +/* ============================================================ + * THREAD 3 - Simulator + * ============================================================ */ + +// 1 = print simulated target positions each update cycle +#define DEBUG_SIMULATOR_OUTPUT 0 + +/* ============================================================ + * SCOPE RENDERING - ISOLATION TOGGLES + * Use these to isolate subsystems during development. + * ============================================================ */ + +// 1 = disable P7 phosphor persistence layer (see raw target hits only) +#define DISABLE_P7_PERSISTENCE 0 + +// 1 = disable land and terrain rendering (see targets without background) +#define DISABLE_LAND_TERRAIN 0 + +// 1 = disable target rendering (see terrain/land background alone) +#define DISABLE_TARGETS 0 + +/* ============================================================ + * CHAIN HOME A-SCOPE + * Component: Chain Home scope (1940s, World War 2) + * ============================================================ */ + +// Fixed maximum range in km; the max_range control has no effect for this scope +#define CHAIN_HOME_MAX_RANGE_KM 200.0f + +/* ============================================================ + * MARINE A-SCOPE + * Component: 1940s marine A-scope (pre-PPI) + * ============================================================ */ + +// Selectable maximum range steps in nautical miles (o/p keys cycle through these) +#define MARINE_A_SCOPE_NUM_RANGES 4 +#define MARINE_A_SCOPE_RANGE_STEP_1 3.0f +#define MARINE_A_SCOPE_RANGE_STEP_2 6.0f +#define MARINE_A_SCOPE_RANGE_STEP_3 12.0f +#define MARINE_A_SCOPE_RANGE_STEP_4 24.0f + +/* ============================================================ + * PPI SCOPE - MARINE TRAFFIC CONTROL + * Component: PPI scope, marine traffic control station + * ============================================================ */ + +// Selectable maximum range steps in nautical miles +#define PPI_MTC_NUM_RANGES 5 +#define PPI_MTC_RANGE_STEP_1 3.0f +#define PPI_MTC_RANGE_STEP_2 6.0f +#define PPI_MTC_RANGE_STEP_3 12.0f +#define PPI_MTC_RANGE_STEP_4 24.0f +#define PPI_MTC_RANGE_STEP_5 48.0f + +/* ============================================================ + * PPI SCOPE - ON-BOARD BOAT + * Component: PPI scope, on-board boat view + * ============================================================ */ + +// Selectable maximum range steps in nautical miles +#define PPI_BOAT_NUM_RANGES 5 +#define PPI_BOAT_RANGE_STEP_1 1.5f +#define PPI_BOAT_RANGE_STEP_2 3.0f +#define PPI_BOAT_RANGE_STEP_3 6.0f +#define PPI_BOAT_RANGE_STEP_4 12.0f +#define PPI_BOAT_RANGE_STEP_5 24.0f