Feature/source plugins #1

Merged
martino merged 130 commits from feature/source-plugins into main 2026-11-04 07:35:21 +01:00
3 changed files with 24 additions and 1 deletions
Showing only changes of commit 5e32199597 - Show all commits

No files matched your search

+1 -1
@@ -403,6 +403,17 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
* **The switch deposits what is already on screen.** `on && !density_was_on` sets the same pending * **The switch deposits what is already on screen.** `on && !density_was_on` sets the same pending
flag, so a user who turns persistence on while an event is held sees it instead of waiting for a flag, so a user who turns persistence on while an event is held sees it instead of waiting for a
latch that `single` mode may never send. latch that `single` mode may never send.
* **The brightness ceiling is the fade's steady state, and the ramp is linear in sweeps.** The app
states `DensityConfig::full_scale` from the fade it configured -- `1/(1 - factor)` for the
acquisition fade, the library's default two sweeps for the time one, which has no fixed steady
state (it settles where the rate and the constant meet) -- and leaves `gamma` at 1.0. A ceiling
at *one* sweep is the defect a user reported as "the colour fading is not applied, it looks
white": a single sweep was already full ink, everything above it clamped to the same pixel, and
a display of one sweep and a display of five were the same white. It is also the one half that
the *grid's* own numbers cannot see -- `ink`/`peak` were right while the picture was flat -- so
the assertion is a **framebuffer** one: `a_phosphor_density_is_drawn_under_the_traces` measures a
cell at a quarter of the scale against one at the ceiling and against the background
(`empty=21 full=83 quarter=54`), which is the reading the eye asked for.
* **It is the plot's, so a figure rebuild resets it** -- the grid lives on each `Plot`, and * **It is the plot's, so a figure rebuild resets it** -- the grid lives on each `Plot`, and
`rebuild_all()` builds new ones. That is the one state a structural change (a row added, a signal `rebuild_all()` builds new ones. That is the one state a structural change (a row added, a signal
switched off, a trace recoloured) does not carry: it costs the accumulated image and nothing else, switched off, a trace recoloured) does not carry: it costs the accumulated image and nothing else,
+12
View File
@@ -3396,6 +3396,18 @@ void apply_density(App& app, DisplayMode display, bool live_display) {
: plot::DensityDecay::PerAcquisition; : plot::DensityDecay::PerAcquisition;
cfg.time_constant_s = static_cast<float>(tc.density_tau_s); cfg.time_constant_s = static_cast<float>(tc.density_tau_s);
cfg.per_acquisition = static_cast<float>(tc.density_factor); cfg.per_acquisition = static_cast<float>(tc.density_factor);
// The brightness ceiling: the ink this fade settles at, so the newest acquisition is a
// *fraction* of full ink and the display reaches white only where the acquisitions agree. For a
// per-acquisition fade that is the geometric sum `1/(1-f)` exactly. A time fade has no fixed
// one -- it settles where the trigger's rate and the constant meet, which is the point of it --
// so it keeps the library's default of two sweeps, and a fast trigger then reads brighter than
// a slow one the way a phosphor's does. The gamma is left at the library's 1.0: the cell is a
// count of sweeps, so half as many sweeps must read as half the ink. (With the ceiling at one
// sweep -- the library's first default -- one sweep was already full white and the fade was
// invisible, which is exactly what a user reported seeing.)
cfg.full_scale = tc.density_decay == PersistDecay::Time
? 2.0f
: static_cast<float>(1.0 / std::max(1.0 - tc.density_factor, 0.05));
// The plot drops what it held when this turns the display off, so the step below only ever // The plot drops what it held when this turns the display off, so the step below only ever
// speaks about an image that is on screen. // speaks about an image that is on screen.
p->set_density(cfg); p->set_density(cfg);