struct data
{
   float2 tex;
   float2 pix_no;
   float2 one;
};

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

void main_vertex
(
   float4 position : POSITION,
   out float4 oPosition : POSITION,
   uniform float4x4 modelViewProj,
   float2 tex : TEXCOORD,
   uniform input IN,
   out data oData
)
{
   oPosition = mul(modelViewProj, position);
   oData.tex = tex;
   oData.pix_no = tex * IN.texture_size;
   oData.one = 1.0 / IN.texture_size;
}

#pragma parameter NTSC_CRT_GAMMA "NTSC CRT Gamma" 2.5 0.0 10.0 0.1
#pragma parameter NTSC_DISPLAY_GAMMA "NTSC Display Gamma" 2.1 0.0 10.0 0.1

#ifdef PARAMETER_UNIFORM
uniform float NTSC_CRT_GAMMA;
uniform float NTSC_DISPLAY_GAMMA;
#else
#define NTSC_CRT_GAMMA 2.5
#define NTSC_DISPLAY_GAMMA 2.1
#endif

float4 main_fragment (uniform input IN, in data vertex, uniform sampler2D s0 : TEXUNIT0) : COLOR
{
#define TEX(off) pow(tex2D(s0, vertex.tex + float2(0.0, (off) * vertex.one.y)).rgb, float3(NTSC_CRT_GAMMA))

   float3 frame0 = TEX(-2.0);
   float3 frame1 = TEX(-1.0);
   float3 frame2 = TEX(0.0);
   float3 frame3 = TEX(1.0);
   float3 frame4 = TEX(2.0);

   float offset_dist = frac(vertex.pix_no.y) - 0.5;
   float dist0 =  2.0 + offset_dist;
   float dist1 =  1.0 + offset_dist;
   float dist2 =  0.0 + offset_dist;
   float dist3 = -1.0 + offset_dist;
   float dist4 = -2.0 + offset_dist;

   float3 scanline = frame0 * exp(-5.0 * dist0 * dist0);
   scanline += frame1 * exp(-5.0 * dist1 * dist1);
   scanline += frame2 * exp(-5.0 * dist2 * dist2);
   scanline += frame3 * exp(-5.0 * dist3 * dist3);
   scanline += frame4 * exp(-5.0 * dist4 * dist4);

   return float4(pow(1.15 * scanline, float3(1.0 / NTSC_DISPLAY_GAMMA)), 1.0);
}

