Project

General

Profile

Emulator Issues #12725 » 00_Integer_Scale_CRT.glsl

taolas, 06/10/2022 09:26 PM

 
// Set aspect ratio to 'stretch'.

// Integer Scaling shader by One_More_Try / TryTwo
// Uses Sharp Bilinear from https://github.com/libretro/slang-shaders/blob/master/interpolation/shaders/sharp-bilinear.slang
// by Themaister, Public Domain license

/*
[configuration]
[OptionBool]
GUIName = Please Set Aspect Ratio to Stretch
OptionName = AMPTY
DefaultValue = false

[OptionBool]
GUIName = Unlock Width
OptionName = WIDTH_SKIP
DefaultValue = false

[OptionBool]
GUIName = Scale Width for CRT
OptionName = WIDTH_CRT
DefaultValue = false

[OptionBool]
GUIName = Apply sharp bilinear when width changes
OptionName = SHARP_BILINEAR
DefaultValue = false

[OptionRangeFloat]
GUIName = Sharp Bilinear pre-scale factor (0 = auto)
OptionName = SHARP_PRESCALE
MinValue = 0.0
MaxValue = 16.0
StepAmount = 1.0
DefaultValue = 0.0

[OptionBool]
GUIName = Manual Scale
OptionName = MANUALSCALE
DefaultValue = false

[OptionRangeFloat]
GUIName = Integer Scale
OptionName = INTEGER_SCALE
DependentOption = MANUALSCALE
MaxValue = 5.0
MinValue = 1.0
DefaultValue = 1.0
StepAmount = 1.0

[OptionBool]
GUIName = Allow Downscaling
OptionName = DOWNSCALE
DefaultValue = false

[/configuration]
*/

void main()
{
float4 c0 = float4(0.0, 0.0, 0.0, 0.0);
float scale = 1.0;
float2 xfb_res = GetResolution();
float2 win_res = GetWindowResolution();
float2 ratio = win_res/xfb_res;
if (OptionEnabled(WIDTH_SKIP))
ratio.x = 1.0;
else if (OptionEnabled(WIDTH_CRT))
ratio.y = 1.0;
if ( OptionEnabled(MANUALSCALE))
{
float calc_ir = ceil(xfb_res.y / 500);
scale = calc_ir / GetOption(INTEGER_SCALE);
ratio = ratio * float2(scale, scale);
}
else if ( OptionEnabled(DOWNSCALE) && (ratio.x < 1 || ratio.y < 1))
{
scale = ceil(max(1.0/ratio.y, 1.0/ratio.x));
ratio = ratio * float2(scale, scale);
}
float y = win_res.y - xfb_res.y / scale;

if (OptionEnabled(WIDTH_CRT))
y = 0.0;

float y_top = (y / 2.0) * GetInvWindowResolution().y;
float y_bottom = (win_res.y - y / 2.0) * GetInvWindowResolution().y;
float yloc = GetCoordinates().y * ratio.y - y_top * ratio.y;
float x = win_res.x - xfb_res.x / scale;
if (OptionEnabled(WIDTH_SKIP))
x = 0.0;

float x_left = (x / 2.0) * GetInvWindowResolution().x;
float x_right = (win_res.x - x / 2.0) * GetInvWindowResolution().x;
float xloc = GetCoordinates().x * ratio.x - x_left * ratio.x;
if (OptionEnabled(SHARP_BILINEAR) && (OptionEnabled(WIDTH_SKIP) || OptionEnabled(WIDTH_CRT)))
{
float texel = xloc * xfb_res.x;
float texel_floored = floor(texel);
float s = frac(texel);
float scale = GetOption(SHARP_PRESCALE);
if (scale == 0)
scale = ceil(win_res.x / xfb_res.x);

float region_range = 0.5 - 0.5 / scale;
float center_dist = s - 0.5;
float f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;

float mod_texel = texel_floored + f;
xloc = mod_texel / xfb_res.x;
}
if (GetCoordinates().x >= x_left && x_right >= GetCoordinates().x && GetCoordinates().y >= y_top && y_bottom >= GetCoordinates().y)
{
float2 sample_loc = float2(xloc, yloc);
c0 = SampleLocation(sample_loc);
}

SetOutput(c0);
}
(5-5/5)