CTR Decrypted

Screen filters

OPTIONS → Video → Screen Filter, saved as screen_filter under [Video & QoL] in config.ini. It decides how the finished frame reaches the window, and switches live.

Menu screen_filter= Effect
SMOOTH 0 Linear scaling at the scaled render modes. Default. At Render Scale ORIGINAL the frame is presented exactly as shipped
SHARP 1 Nearest-neighbour scaling at the scaled render modes
SHARP BILINEAR 2 Whole-pixel scaling with a linear seam about one window pixel wide: crisp pixels without nearest's uneven widths at a non-integer scale
FXAA 3 Fast approximate anti-aliasing of the rendered image, then Sharp Bilinear scaling
SCANLINES 4 The game's 216 lines as light beams with dark gaps, on crisp pixels
CRT 5 Scanlines with soft pixels, an aperture grille and a slightly curved screen
LCD 6 Each PSX pixel a cell of red, green and blue stripes with darker rows between cells, like a handheld's screen

A config.ini with the old smooth_scaling = false and no screen_filter loads as SHARP.

Render Scale and Screen Filter are independent. Scanlines, CRT and LCD always draw the PSX picture pixel for pixel, so a higher render scale only costs time with them. FXAA does most at 2X and above, smoothing the stair-steps the higher raster still has.

Colour filter

OPTIONS → Extras → Colour Filter, saved as colour_filter under [Extras]. It changes the picture's colours and the screen filter shows the result, so the two combine (CRT in greyscale, FXAA with a colour-blind mode). It switches live.

Menu colour_filter= Effect
OFF 0 Default
GREYSCALE 1 Luma (Rec. 709 weights)
SEPIA 2 The usual sepia matrix
NEGATIVE 3 Inverted colours
VIGNETTE 4 Darkens toward the corners, to 35%
PROTANOPIA 5 Colour-blind correction for players without red cones
DEUTERANOPIA 6 Colour-blind correction for players without green cones

The colour-blind modes are daltonize corrections: the colour as that player sees it (Machado, Oliveira and Fernandes 2009, full severity, linear light) is subtracted, and the missed difference is added into green and blue (Fidaner's shift), so red and green also differ in lightness and blue. This separates red from green, and orange from green, much more, at the cost of a few pairs that were already distinct. There is no tritanopia mode: no fixed shift made blue and yellow easier to tell apart without making more pairs harder.

How it works

platform/native_renderer.c, from NativeRenderer_DrawScreenFilter. The ladder and its helpers are in include/platform/native_screen_filter.h.

Checking

Capture after the filter with CTR_DEV_SHOT_PRESENTED=1 and compare against SMOOTH with tools/decrypted/filter_check.py (DEV-TOOLS.md). Expected:

High Octane's effects

High Octane has 13 effects in one list, adapted from DaedalusX64-vitaGL's shaders and tuned to the Vita's 960×544. These filters are written for this renderer instead, so they follow the presentation viewport and PSX raster at any window size, and colour effects are a separate row so they combine with screen filters. Its LCD 3x became LCD, drawn on PSX pixels rather than a fixed 640×480 grid. Not ported: Hue (it turns colours around the wheel unevenly) and Gamma (the display's own setting does the same). Its colour-blind matrices are replaced by the correction above, which separates red from green further.