|
// 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);
|
|
}
|