#pragma parameter target_gamma "Target Gamma" 2.2 0.1 5.0 0.1
#pragma parameter monitor_gamma "Monitor Gamma" 2.2 0.1 5.0 0.1
#pragma parameter overscan_percent_x "Horizontal Overscan %" 0.0 -25.0 25.0 1.0
#pragma parameter overscan_percent_y "Vertical Overscan %" 0.0 -25.0 25.0 1.0
#pragma parameter saturation "Saturation" 1.0 0.0 5.0 0.1
#pragma parameter contrast "Contrast" 1.0 0.0 7.5 0.1
#pragma parameter luminance "Luminance" 1.0 0.0 2.0 0.1
#pragma parameter black_level "Black Level" 0.00 -0.30 0.30 0.01
#pragma parameter bright_boost "Brightness Boost" 0.0 -1.0 1.0 0.1
#pragma parameter R "Red Channel" 1.0 0.0 2.0 0.05
#pragma parameter G "Green Channel" 1.0 0.0 2.0 0.05
#pragma parameter B "Blue Channel" 1.0 0.0 2.0 0.05
#pragma parameter ZOOM "Zoom Factor" 1.0 0.0 4.0 0.01
#pragma parameter XPOS "X Modifier" 0.0 -2.0 2.0 0.005
#pragma parameter YPOS "Y Modifier" 0.0 -2.0 2.0 0.005
#pragma parameter TOPMASK "Overscan Mask Top" 0.0 0.0 1.0 0.0025
#pragma parameter BOTMASK "Overscan Mask Bottom" 0.0 0.0 1.0 0.0025
#pragma parameter LMASK "Overscan Mask Left" 0.0 0.0 1.0 0.0025
#pragma parameter RMASK "Overscan Mask Right" 0.0 0.0 1.0 0.0025
#ifdef PARAMETER_UNIFORM
uniform float target_gamma;
uniform float monitor_gamma;
uniform float overscan_percent_x;
uniform float overscan_percent_y;
uniform float saturation;
uniform float contrast;
uniform float luminance;
uniform float black_level;
uniform float bright_boost;
uniform float R;
uniform float G;
uniform float B;
uniform float ZOOM;
uniform float XPOS;
uniform float YPOS;
uniform float TOPMASK;
uniform float BOTMASK;
uniform float LMASK;
uniform float RMASK;
#else
#define overscan_percent_x 0.0         // crop width of image by X%; default is 0.0
#define overscan_percent_y 0.0         // crop height of image by X%; default is 0.0
#define saturation 1.0                 // color saturation; default 1.0
#define monitor_gamma 2.2              // gamma setting of your current display; LCD monitors typically have a gamma of 2.2
#define target_gamma 2.2               // the gamma you want the image to have; CRT TVs typically have a gamma of 2.4
#define contrast 1.0                   // image contrast; default 1.0
#define luminance 1.0                  // image luminance; default 1.0
#define black_level 0.0                 // black level; default 0.0
#define bright_boost 0.0               // adds to the total brightness. Negative values decrease it; Use values between 1.0 (totally white) and -1.0 (totally black); default is 0.0
#define R 1.0
#define G 1.0
#define B 1.0
#define ZOOM 1.0
#define XPOS 0.0
#define YPOS 0.0
#define TOPMASK 0.0
#define BOTMASK 0.0
#define LMASK 0.0
#define RMASK 0.0
#endif
// END PARAMETERS //

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

struct input
{
  float2 video_size;
  float2 texture_size;
  float2 output_size;
  float  frame_count;
  float  frame_direction;
  float frame_rotation;
};

void main_vertex
(
    float4 position    : POSITION,
    float4 color    : COLOR,
    float2 texCoord : TEXCOORD0,

    uniform float4x4 modelViewProj,
    uniform input IN,

    out float4 oPosition : POSITION,
    out float4 oColor    : COLOR,
    out float2 otexCoord : TEXCOORD
)
{
   oPosition = mul(modelViewProj, position);
   oColor = color;
   float2 shift = 0.5 * IN.video_size / IN.texture_size;
   float2 overscan_coord = ((texCoord - shift) / ZOOM) * (1.0 - float2(overscan_percent_x / 100.0, overscan_percent_y / 100.0)) + shift;
   otexCoord = overscan_coord + float2(XPOS, YPOS);
}

struct output 
{
   float4 color    : COLOR;
};

float3 grayscale(float3 col)
{
   // ATSC grayscale standard
   return float3(dot(col, float3(0.2126, 0.7152, 0.0722)));
}

float4 main_fragment(float2 texCoord : TEXCOORD, in sampler2D s0 : TEXUNIT0, uniform input IN) : COLOR
{
float2 fragcoord = texCoord.xy * (IN.texture_size.xy / IN.video_size.xy);
   float3 res = tex2D(s0, texCoord).rgb; // sample the texture
   float3 gamma = float3(monitor_gamma / target_gamma); // setup ratio of display's gamma vs desired gamma
   float3 AvgLumin = float3(0.5, 0.5, 0.5);
   float3 intensity = grayscale(res); // find luminance
   float3 satColor = lerp(intensity, res, saturation); // apply saturation
   float3 conColor = lerp(AvgLumin, satColor, contrast);   // apply contrast
   conColor -=float3(black_level); // apply black level
   conColor *=(1.0 / float3(1.0-black_level));
   conColor = pow(conColor, 1.0 / float3(gamma)); // Apply gamma correction
   conColor = saturate(conColor * luminance); // apply luminance
   conColor += float3(bright_boost); // apply brightboost
   conColor *= float3(R, G, B);
if (fragcoord.y > TOPMASK && fragcoord.y < (1.0 - BOTMASK))
conColor = conColor;
else
conColor = 0.0;

if (fragcoord.x > LMASK && fragcoord.x < (1.0 - RMASK))
conColor = conColor;
else
conColor = 0.0;
   return float4(conColor, 1.0);
}
