Files
updated-radar/CLAUDE.md

599 lines
36 KiB
Markdown

Introduction:
This is a project for a museum to demonstrate a simulation of a 1950's to 1960's
vintage marine radar and air traffic control radar
The project will be implemented on a Geekom A8 Max
with AMD AI chip R9-8945HS with 32 GB ram
# Project: C++ OpenGL Radar Simulation
**Environment:** Ubuntu Linux (Remote SSH from Windows)
**Tech Stack:** C++20, OpenGL 3.3 Core, GLFW, GLAD, FreeType
The operating system is Linux (Ubuntu)
Details:
Distributor ID: Ubuntu
Description: Ubuntu 25.10
Release: 25.10
Codename: questing
The compiler is cpp (Ubuntu 15.2.0-4ubuntu4) 15.2.0
We plan to use the cmake for building.
Please add MIT license header to each file
Please add Author: Mark Allyn to each file
Here is the directory structure with files already installed:
All directories are in the new-radar top level directory. The
entire directory list is /home/maallyn/new-radar on the Geekom.
./shaders
./shaders/CLAUDE.md
./glad
./glad/src
./glad/src/glad.c
./include
./include/glad
./include/glad/glad.h
./include/CLAUDE.md
./include/KHR
./include/KHR/khrplatform.h
./new-claude
./README.md
./CMakeLists.txt
./build
./build/CLAUDE.md
./CLAUDE.md
./.new-claude.swp
./LICENSE
./src
./src/CLAUDE.md
==================================================================
GENERAL STUFF
==================================================================
Please note that all on-screen text shall be white and fully
illuminated and is not subject to phosphor persistance or decay.
Exceptions:
Graticule text: should be incandescent for the bearing marks.
Graticale text for all a-scope should be incandenecent, not white
and not phosphor as they are dependent on glass graticules with etched
lines and text.
PPI Scope Range Ring Markers Text on the PPI scope range rings shall be blue
fade to yellow green as on p7 phosphor. Which is the same for ppi targets.
Please note that direction as stated here are True directions. 000 is True North
Maximum Range is 6 miles for marine type radar
Maximum Range is 20 miles for air traffic control radar.
Maximum Range is 100 miles for chain home
Maximum Range 10 miles for precision approach radar; graticule is
incandescent showing the azimouth path and elevation path as describe
below in PAR description. Those graticules are etched glass for minimal
parralax
The proposed location of the marine radar antenna is in the middle of Bellingham
Bay on a 100 foot platform. (This should be mentioned as fictitous in the description)
Location is 48.74361448950435 latitude, -122.56466911663048 longitude
The proposed location of the air traffic control radar is the Bellingham
airport (BLI) control tower. Latitude: 48° 47' 33.7" N ; Longitude: 122° 32' 15.1" W
The proposed location for the chain home would be at the original location on
the UK coast facing the European Continent
The following types of scope will be used; (note that these are not all
going to show at once. They will be selectable using a push button (a letter
the keyboard until I get physical buttons that are connected to a gpio pin.
The selection key should be s (short for scope)
PLease note that all keyboard based controls need to be described in each
scope's left hand text panel. These are different for each scope. Note that
the s for selecting a scope should be in each scope's description and what
would the next scope be.
Also not that when the radar exhibit starts, the very first option will
be on the screen. Then the screen will advance through the scopes by two means;
the pressing of the s key by the user, or automatically at every 120 seconds. You will
need to emphasize in the first desciption that you can advance without waiting
for the automatic advancing by pressing the s key. You can reverse by hitting the S key
(upper case s) This should be articulated for the
discrition window for each scope. When the main exhibit descriptor screen comes up, it's
important to highlight the feature that the user can press the s key or the S key any time to 'hurry up'
the scope advancement.
Also ensure that the timeout clock will reset when the user changes to a new scope, or presses
any key or operate any control on the panel. This
should be articulated in the descriptive text
1. Exhibit introduction - a text block describing the exhibit and the
basics on how to use it and what you are seeing. This should be text only. Top would
be in all caps, "WELCOME TO MUSEUM VINTAGE RADAR EXHIBIT"
2. Marine A-Scope - (horizontal axis is range; vertical axis is amplitude of
return pulse; bearing will be set via a bearing control; current implimentation
would be two keys on the keyboard; one key to go clockwise on bearing and another
key would be to go counterclockwise. The A scope phosphor is P1, which is green.
The c key for clockwise on a scope and v for counterclockwise.
The step rate for this control, before the knob is implemented would be one or two
degrees per key press, but if the key is held down, it would increase slowly due to
how long the keep is depressed
The A scope graticule is manually swapped out at each maximum range value
by the operator during the period. Here we will have to fake it out. And that
graticule needs to have an incandescent color. That graticule will have three horizontal
graticule lines for estimating return pulse strength. The range lines (vertical lines)
should mush match the interim and final ranges as selected by the max range selelction
To change maximum range, use key u for up and d for down. Possible settings are 2,4,6
miles; this must be noted clearly on the description text.
Max is 2; one interim range at 1
Max is 4; one interim range at 2
Max is 6; one interim range at 4
In addition to the blips for targets, there would be a floor of noise (signal received by
rain and waves. This needs to be shown.
Graticule swap simulation: In the period, changing maximum range required the operator
to physically slide the glass graticule panel upward and out from in front of the CRT,
then slide the replacement graticule (calibrated for the new range) downward into position.
This must be simulated when the operator presses u or d to change range.
The graticule swap animation uses four states:
NORMAL - graticule in place, scope operating normally
SLIDING_OUT - old graticule translates upward off screen (~0.5 seconds)
BARE_CRT - no graticule visible; CRT trace and noise floor still running
SLIDING_IN - new graticule (correct lines for new range) slides down into position (~0.5 seconds)
After SLIDING_IN completes, state returns to NORMAL with the new range active.
The u and d keys are ignored during the swap animation (operator's hands are busy).
The graticule remains incandescent color throughout — it is edge-lit glass.
3. Chain Home A Scope There is a second use of the a-scope.
That is for the early world war 2 chain home
radar. This operated very differently. You have a large array of high power transmitters
'floodlighting' the target area (in world war 2, that would be the english channel.
Since we don't care about land reflactions with the original chain home setup was
facing the englash channel, we can tell visitors that this radar is set at the
english channelk (do this explanation on the explantation side panel for this
radar mode. And for simulating operator using this radar, there would be two controls,
one for the 'nulling the signal at the correct direction; simulating the behavior
of the goniometer and the other for using the goniometer for elevation. For museum
accuracy, we need to simulate the sharp 'null' when the goniometer is at the direction
of the signal. This concept needs to be covered in the description text thoroughly
as this is a bit advanced. I need your advise to how to do this for children and those
who never heard of chain home.
The goniometer vertical and horizontal switch could be key [ for toggling. The gonometer tuning
would be 9 and 0 to avoid using the shift key. The tuning keys should have one unit
for single press, but a slow build of of speed if key is held down. This has to stay
slow due to the sudden appearance of the null.
Targets for Chain Home would all have to be simulated as there will be no ais
nor ads-b. Simulations would show several aircraft approaching the radar in many
different directions and ranges. The museum visitor for exercise could try to sort
out the targets by range and bearing and elevation by the nulling procedure noted
above as well as the distance of the pulse from the origin.
The graticule is etched glass (side lit with incandescent lights) with 10 mile
markers for range (horizontal axis). There are no vertical markers; the signal
strength value is not important. The only vertical value that is important is the
nulling of the signal based on bearing and elevation from the manipulation of the
goniometer.
The refresh rates for chain home were slow in order to avoid aliasing with targets
far away, the pulse repitation frequency (PRF) is about 25 times per seconds. This
rate is 1/2 of the standard 50 hz for brittish power.
The operator did have a switch to switch from the 25 pulses per second PRF to 12.5
pulses per second PRF so that they could help eliminate teh range ambiguity
problem, where a target that is away could appear to be right on site since that echo
would return at the precise time for the next pulse to go out at 25 PRF. This needs
to be explained in the explainer window for the chain home. Mention that mountains or planes
in the continent could have that kind of range. Furthermore, the operator can reduce
the PRF in order to reduce confusion caused by other radio transmissions such as press-to-talk
communications transmissions.
Lets assign key . for toggling between 25 and 12.5 PRF. There is no range selection.
Note on description; this is to reduce use of the shift key.
Because of the slow repitition rate, the phosphor used was a early implementation
of the p7 phosphor so that the targets will still glow between the sweeps and not cause
flickering.
Another unique feature would be a response to the drifting problem in early electronics.
The scope electronics would use a crystal calibrator that puts tiny pips or spikes at
known intervals (10 miles). The operator would use a knob, or control, to stretch or
shrink the electronic trace so tht the 10 mile pips align perfectly with the 10 mile
marks on the edge lit glass graticule.
Lets assign keya n for shrink and m for stretch. (may be ambiguous, but I am running
out of keys. Note in the descriptor.
4. Marine PPI Scope -
maring scopes have the following items in common:
Targets, range rings, and range ring text levels shall be treated the same for
presentation. All are P7 phosphor. Immediatel strike by the electron beam is blue.
persistance is green/yellow. Targets, range rings, and range ring labels shall all
persiste and fade out together. They should be faded out by the time the sweep
to that location.
The maximum range settings are 6 miles for the marine radar scope
Rings should be 2,4, and 6 miles for marine.
The max range settings for marine ppi will be u for up and d for
down. If you are in the marine ppi, you change only the max range for the marine
ppi. The possible max range values for
the marine radar are 2,4,6
miles.
Marine:
Max is 2; one interim range at 1, final ring at 2
Max is 4; one interim range at 2, final ring at 4
Max is 6; one interim range at 4, final ring at 6
Note on range. If cursor range is beyone max, clamp it to the max.
Bear in mind that the max range setting is independent for both radars.
The bearing graticle (lit incandescent) There shold
be an inner circle with tickmarks for each degree, starting at 0 (north) and going
clockwise to the last tick, which is 359. Outside the innter ring shall be text
labels for every 15 degrees. Outside the text labels, there will be
an outer ring. Both inner and outer rings, along with ticks, and the bearing
labels are to be incandescent color.
The sweep time shall be 4 seconds for the marine scope
The sweep direction is clockwise, which means that the entenna
dish rotates clockwise.
The scope has a cursor for range and bearing. The cursor consists of a
section of a ring ( 10 degrees) and a cross line for bearing.
The cursor should be yellow (it
a plastic overlay in the period time. Two controls control the cursor; range and
bearing. Both were physical crank controls. For now, both we need to use key pairs
on the keyboard. A white text indication of range and bearing should be put under
the scope. In the real day, it was a machanical readout. The key sewuence would be
r for bearing to the right and l for bearing for the left; and t for higher range
and y for smaller range. These controls should have slow movement for single stroke; but
gradual for for holding key down.
5. Air Traffic PPI Scope -
Targets, range rings, and range ring text levels
All are P7 phosphor. Immediatel strike by the electron beam is blue.
persistance is green/yellow. Targets, range rings, and range ring labels shall all
persiste and fade out together. They should be faded out by the time the sweep
to that location.
Rings should be 5,10,15,20 for the air traffic control radar.
The max range settings for air ppi will be u for up and d for
down. Use of these controls affect only the scope you are in. No other scopes are
affected.
The ranges for air traffic control radar are 5,10,15,20
miles.
Air Traffic Control:
Max is 5; one interim rainge; two total; rings at 2.5; final ring at 5
Max is 10; four interim ranges, five total; 2,4,6,8; final ring at 10
Max is 15; three interim ranges four total; 4,8,12; final ring at 15
Max is 20, three interim ranges four total; 5,10,15; final ring at 20
Note on range. If cursor range is beyone max, clamp it to the max.
Bear in mind that the max range setting is independent for both radars.
The bearing graticle (lit incandescent) for the scopes are the same. There shold
be an inner circle with tickmarks for each degree, starting at 0 (north) and going
clockwise to the last tick, which is 359. Outside the innter ring shall be text
labels for every 15 degrees. Outside the text labels, there will be
an outer ring. Both inner and outer rings, along with ticks, and the bearing
labels are to be incandescent color.
The sweep time shall be 5 seconds for the
air traffic scope.
The sweep direction on the scope is clockwise, which means that the entenna
dish rotates clockwise.
The scope has cursor for range and bearing. The cursor consists of a
section of a ring ( 10 degrees) and a cross line for bearing.
The cursor should be yellow (it
a plastic overlay in the period time. Two controls control the cursor; range and
bearing. Both were physical crank controls. For now, both we need to use key pairs
on the keyboard. A white text indication of range and bearing should be put under
the scope. In the real day, it was a machanical readout. The key sewuence would be
r for bearing to the right and l for bearing for the left; and t for higher range
and y for smaller range.
These controls should have slow movement for single stroke; but
gradual for for holding key down.
6. Precision approach (PAR for short)
PAR was developed in WWII and matured in the 1950s. With a fixec 10 mile range, it was
controller who talked the pilot down verbally over radio, which means that the pilot
does not have to rely on any equipment on the plane itself to help with landing.
The display shows the full 10-mile approach path, but the controller's active guidance window
is roughly the last 5 miles, intensifying from about 2 miles out to touchdown.
This needs to be carefully explained on the explainer screen.
Lets locate this at the south end of Runway 16/34 landing at BLI and lets have the
active runway 34 (northbound landing)
Locate at the end of Runway 16/34
at Bellingham Airport (BLI). Two vertically stacked scopes share the
right panel. Top scope: azimuth (lateral deviation vs. range from
touchdown). Bottom scope: elevation (vertical deviation vs. range).
Have the azimouth scope to about 1/3 larger than the elevation scope
Both use P7 phosphor; graticules are incandescent etched glass.
Range: 10 miles maximum, fixed (no range change control).
Non-linear scale: inner 5 miles occupies 70% of horizontal width.
All targets are simulated. No cursor or bearing controls; PAR
has no bearing selection — it always points toward the runway.
Sweep rate: approximately 30 Hz alternating between azimuth and
elevation planes so that each will scan 1/15 th of a second.
THREADS
These are the threads of processes:
1. Display initiation and operation (anything that 'touches' the display and the shaders) Thread 1
2. Software that receives data for targets. Thread 2 (this is the traffic cop that polls the
raspberry pis. and the Simulator. This needs mutex access to shared data with thread 1. It will
also need mutex access to shared data with thread 4 (the simulator)
3. Knob panel - thread 3 - uses a mutex to write shared state variables that thread 1 reads
to send to the shaders.
4. Simulator, thread 4. It is polled by the traffic cop
Threads 2,3, need mutex access to shared data that is read by thread 1.
Thread 2 needs mutex access for shared data with thread 4, the simulator
SUMMARY OF Controls:
● ┌─────┬─────────────────────────────────────┬───────┬──────────┬──────────────┬────────────┬─────────┬─────┐
│ Key │ Function │ Intro │ Marine A │ Chain Home A │ Marine PPI │ ATC PPI │ PAR │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ s │ Advance to next scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ S │ back to previous scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ c │ Bearing clockwise │ │ ✓ │ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ v │ Bearing counterclockwise │ │ ✓ │ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ u │ Max range up │ │ ✓ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ d │ Max range down │ │ ✓ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ r │ Cursor bearing right │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ l │ Cursor bearing left │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ t │ Cursor range increase │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ y │ Cursor range decrease │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ k │ Antenna bearing offset right (boat) │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ j │ Antenna bearing offset left (boat) │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ [ │ Goniometer H/V switch │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ 9 │ Goniometer tune left │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ 0 │ Goniometer tune right │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ . │ Toggle PRF (25/12.5 Hz) │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ n │ Calibrator shrink │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
│ m │ Calibrator stretch │ │ │ ✓ │ │ │ │
└─────┴─────────────────────────────────────┴───────┴──────────┴──────────────┴────────────┴─────────┴─────┘
SUMMARY of target handling:
The traffic cop handles anything that is coming from the simulator as well as the raspberry pi's
It will use pollnig to find if anything is available from the raspberry pis and the simulator. It will
poll each source once per beam update
The raspberry pi receiver pulls the data from each raspberry pi. If nothing, it does nothing else
for this sweep. If there is data, it will provide data to the traffic cop upon poll.
Each raspberry pi, after boot-up, will respond to poles from the raspberry pi receiver (thread 2)
The Simulator will run all fake targets. It will provide data to the traffic cop upon traffic cop poll.
It can run as a separate thread. It will not write data to anywhere except when polled by the traffic cop.
CONTROLS
Things to note about the keyboard type controls.
The letter on the keyboard are temporary. When I get around to making
the operators panel, this all will go away.
Implementation of controls:
1. For keyboard controls. Those are run as thread one where The keyboard callback
belongs to GLFW (glfwSetKeyCallback)
They will manipulate the shaders only.
2. The control desk controls will have to mutex to access the state variables that
thread 1 sends to the shaders.
3. If the control does not yet exist, we still want stubs for receiving control
data for that control. It's just that nothing will call it.
Scope and left window arrangement.
For each scope, put the scope itself on the right hand of the window.
On the left hand of the window will be a text description of that scope.
Underneath each scope's description will be cursor range and bearing from the radar
location; and the setting of maximum range; and the bearing offset; for 0 would
be to have 0 degrees pointing to true north (this is needed if I decide to
implement a radar on a boat. If implimented, use k for bearing to right; and
j for bearing to left. Make note in description that this is only used if this
is a radar on a boat. (perhaps later on, I could ad a PPI on a boat scenario)
Please note that some keys may be the same from scope to scope. This is okay. Each
scope's controls are for that scope that you are connected do.They will not effect
settings on another scope.
Please note that the maximum range setting on a scope specific to that scope
and will be in that scope's definition. and the bearing selection
is scope specific. The manually operated radar dish for the a scope is not the same
as the PPI radar dishes. They are from different eras. In addition, all range and
bearing data for marine is separate than for air traffic control. They are completly
different radars. Range and bearing for the precision aproach radar will be different
than any other radar as that radar is located at the end of the runway and scan both
horizontal and vertical.
Please analyze and comment. Please do not generate any code file nor shader files.
==================================================================
CLASS DESIGN AND FILE LAYOUT
==================================================================
Class Hierarchy:
Scope (abstract base)
├── ExhibitIntro
├── AScope (abstract)
│ ├── MarineAScope
│ └── ChainHomeAScope
├── PPIScope (abstract)
│ ├── MarinePPIScope
│ └── ATCPPIScope
└── PARScope
Scope (abstract base) — everything all scopes share:
- Left panel text rendering
- s / S key handling (scope advance / reverse)
- Auto-advance timer reset on any key or control input
- Pure virtual: render(), handleKey(), getDescription()
ExhibitIntro : public Scope
- Text-only rendering, no radar display
- Header: "WELCOME TO MUSEUM VINTAGE RADAR EXHIBIT" (all caps)
AScope : public Scope (abstract) — shared A-scope behavior:
- Horizontal range axis, vertical amplitude axis
- Noise floor rendering (rain/wave clutter)
- Incandescent graticule (three horizontal amplitude lines + vertical range lines)
- Bearing control with key-hold acceleration
- Phosphor type as parameter (P1 or P7)
MarineAScope : public AScope
- P1 phosphor (green)
- Range settings: 2, 4, 6 miles
- Graticule swap animation state machine (NORMAL/SLIDING_OUT/BARE_CRT/SLIDING_IN)
when operator changes max range — see Marine A-Scope section above for full detail
- Keys: c (bearing CW), v (bearing CCW), u (range up), d (range down)
u and d ignored during graticule swap animation
ChainHomeAScope : public AScope
- P7 phosphor (early implementation)
- Goniometer state: H/V mode toggle, azimuth angle, elevation angle
- PRF toggle: 25 Hz / 12.5 Hz
- Calibrator stretch/shrink scale factor
- Fixed 100-mile range
- Keys: [ (goniometer H/V toggle), 9/0 (tune), . (PRF), n/m (calibrator)
PPIScope : public Scope (abstract) — shared PPI behavior:
- Clockwise sweep with P7 phosphor persistence (blue strike, green/yellow decay)
- Incandescent bearing graticule (1-degree ticks, 15-degree labels, inner/outer rings)
- Yellow cursor: 10-degree arc + bearing crossline
- Cursor range/bearing readout under scope (white text)
- Bearing offset for boat mode (k/j)
- Cursor range clamped to max range
MarinePPIScope : public PPIScope
- Sweep time: 4 seconds
- Max range: 2, 4, 6 miles with correct ring sets
- Keys: u (range up), d (range down) — this scope only
ATCPPIScope : public PPIScope
- Sweep time: 5 seconds
- Max range: 5, 10, 15, 20 miles with correct ring sets
- Keys: u (range up), d (range down) — this scope only
PARScope : public Scope
- Two stacked sub-scopes: azimuth (top, ~1/3 larger) and elevation (bottom)
- 30 Hz alternating scan between planes (~15 Hz each)
- Fixed 10-mile range, non-linear scale (inner 5 miles = 70% width)
- P7 phosphor; incandescent etched glass graticules
- All targets simulated; no cursor or bearing controls
Supporting classes:
ScopeManager Thread 1 — owns scope list, s/S switching, 120s auto-advance timer
PhosphorRenderer Thread 1 — P1 and P7 decay/persistence; shared dependency
Graticule Thread 1 — incandescent graticule lines/text; parameterized per scope
LeftPanel Thread 1 — scope description text panel (left side of window)
SharedRenderState Threads 1,2,3 — Mutex A; state vars Thread 1 reads each frame for shader uniforms
TargetBuffer Threads 2,4 — Mutex B; target data handoff between TrafficCop and Simulator
TrafficCop Thread 2 — polls Simulator and RPi receivers; writes to SharedRenderState
Simulator Thread 4 — runs fake targets; returns data to TrafficCop when polled
KnobPanel Thread 3 — future hardware stub; writes to SharedRenderState under Mutex A
RPiReceiver Thread 2 — stub; one per Raspberry Pi; called by TrafficCop
File layout:
src/
main.cpp
scope_manager.h / scope_manager.cpp
scope.h / scope.cpp — abstract Scope base
scope_intro.h / scope_intro.cpp
scope_ascope.h / scope_ascope.cpp — abstract AScope
scope_marine_a.h / scope_marine_a.cpp
scope_chain_home.h / scope_chain_home.cpp
scope_ppi.h / scope_ppi.cpp — abstract PPIScope
scope_marine_ppi.h / scope_marine_ppi.cpp
scope_atc_ppi.h / scope_atc_ppi.cpp
scope_par.h / scope_par.cpp
phosphor.h / phosphor.cpp
graticule.h / graticule.cpp
left_panel.h / left_panel.cpp
shared_render_state.h / shared_render_state.cpp
target_buffer.h / target_buffer.cpp
traffic_cop.h / traffic_cop.cpp
simulator.h / simulator.cpp
knob_panel.h / knob_panel.cpp
rpi_receiver.h / rpi_receiver.cpp
settings.h — all tunable constants; no .cpp needed
shaders/
phosphor.vert / phosphor.frag — parameterized for P1 and P7 via uniforms
graticule.vert / graticule.frag
text.vert / text.frag
sweep.vert / sweep.frag
settings.h — tunable constants:
All magic numbers live here. Every source file that needs a tunable value
includes settings.h. No values are hardcoded elsewhere.
Categories planned:
- Phosphor P1 color
- Phosphor P7 strike color, persistence color, decay times (PPI and Chain Home)
- Sweep line width, brightness, fade trail, periods per scope
- PAR scan rate; Chain Home PRF high and low
- Graticule incandescent color, line widths
- PPI bearing ring tick lengths, label interval, font size
- PPI range ring line width, label size, label color
- Cursor color, line width, arc span
- Noise floor amplitude and variation (Marine A-Scope)
- Graticule swap animation durations (slide out, bare CRT, slide in)
- Key-hold acceleration (initial step, rate, max) — separate for goniometer
- Auto-advance timer interval (120 seconds)
- Window size and panel layout fractions
- PAR azimuth/elevation height fractions
- UI text color and size; cursor readout text size
- Graticule label color (incandescent)