Skip to content

CapView 1.9

Choose a tag to compare

@NuclearMeltdown NuclearMeltdown released this 25 Aug 10:06
· 19 commits to main since this release

Retro scaling, a settings window that stays out of the preview's way, and an autocrop that knows when not to.

Native pixel grid

Every output pixel resolves to the console's own pixel rather than to a fraction of one. A card samples the line at a fixed rate — usually 720 — while a SNES draws 256 across it, so each console pixel lands on about 2.8 samples and the boundaries end up wherever the arithmetic puts them. Told the real count, the grid comes back: measured, 245 to 252 clean column transitions out of a theoretical 255.

The dropdown names the console next to each width, because "256" is a number and "SNES, Mega Drive" is an answer.

This recovers the grid, not the detail the grid used to carry. An OSSC samples the waveform at the console's dot clock and can do the second; nothing downstream of a capture card can.

Scanlines and a shadow mask

Off by default, display only, and both compensate their own brightness so the controls change structure rather than exposure — measured mean exactly 1.000 across every scale. Scanlines switch off below twice the source height, where there is nowhere to put a gap and the result would be moire.

Both are capped at 0.5. Past that the compensation cannot hold the colour: the lift needed to restore the brightness starts clipping channels apart from one another, and what arrives is a colour cast rather than a stronger effect. The gain is additionally limited by the pixel's brightest channel, so a bright area gets darker than ideal instead of changing hue.

Avoid ghosting

The four-frame average can only average, and averaging across movement is smearing. The new checkbox moves where that trade happens rather than pretending to remove it: held on late, slow low-contrast movement drags a trail; released early, moving edges stay clean and slow areas keep some crawl for the demodulator to pick up.

The gate keeps five levels out of 255 of slack either way. That is not a sensitivity — it is the card's noise floor, and removing it makes the filter switch on and off on a still picture.

No-signal detection and an idle screen

Snow, a flat line and a real picture are told apart from the luma itself, with the thresholds set against live content rather than guessed. Losing the signal brings up CapView's own idle screen instead of leaving whatever the card last produced on screen.

Autocrop refuses to crop to a logo

The border measurement finds the edges of what is not black, and cannot tell a border from a part of the picture that simply is not lit right now. A console on its home screen is exactly that case.

Detect now asks how much would survive, and the statistic is area — a real border eats one direction, a logo on black eats both. Measured on a GameCube home screen at 720x480: 48 % wide, 77 % tall, 37 % of the area, against 57 % for the widest border that is still a border. It refuses, and names the number it refused on.

The settings window

The preview no longer cares what the window does. Two wrong fixes came before this one, and both were a number: a fixed 30 ms ceiling, then the source's own frame rate — which was worse, because PAL delivers 25 frames while the preview shows 50 deinterlaced fields, and GetTickCount rounds any threshold up to its next 15.6 ms step. 40 ms becomes 46.8, which is 21 frames a second. There is no ceiling now; the drag loop applies the same three conditions the main loop always has.

Switching between embedded and separate hands the position over instead of each form reappearing wherever it last was. Matched outer edge to outer edge, because the embedded panel counts its own title bar and a real window does not — that difference was the few pixels of drift on every switch. A separate window dragged outside the main window centres itself when embedded, rather than opening somewhere unreachable.

The black flicker on interlaced sources is gone. With the settings open the message queue never goes quiet, and the field schedule was conditional on it being quiet — so every second field was dropped for as long as the dialog was open.

Smaller things

  • The crop overlay's dimming no longer paints over its own Apply and Cancel buttons. Dragging an edge across them used to make them too dark to read, exactly when you were reaching for them — the four dimmed rectangles were on ImGui's foreground draw list, which is composited after every window rather than before.
  • The demodulator slider snaps to the steps that actually change the window width, nine of them on PAL. The positions in between computed the same filter.
  • Sharpening works. It was scaling its sample offsets by the destination size instead of the source, so at any real scale factor it sampled inside a single source pixel and returned the pixel unchanged.
  • Colour shimmer weights each neighbour by how close its colour is to the centre's. An unweighted average across a colour edge turns complementary colours grey — measured saturation loss 0.42 down to 0.09.

Full detail in the wiki.