/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

/*
   Copyright (C) 2007 guest(r) - guest.r@gmail.com

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

const half     halfpi     = 1.5707963267948966192313216916398;
const half         pi     = 3.1415926535897932384626433832795;

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


struct out_vertex {
	half4 position : POSITION;
	half2 texCoord : TEXCOORD0;
	half4 t1 : TEXCOORD1;
	half4 t2 : TEXCOORD2;
	half4 t3 : TEXCOORD3;
	half4 t4 : TEXCOORD4;
	half4 t5 : TEXCOORD5;
	half4 t6 : TEXCOORD6;
	half4 t7 : TEXCOORD7;
	half4 t8 : TEXCOORD8;
};

/*    VERTEX_SHADER    */
out_vertex main_vertex
(
	half4 position	: POSITION,
	half2 tex      : TEXCOORD0,

   	uniform float4x4 modelViewProj,
	uniform input IN
)
{
	half2 ps = 1.0/IN.texture_size;
	half dx = ps.x;
	half dy = ps.y;

	out_vertex OUT = { 
		mul(modelViewProj, position),
		tex,
		half4(tex,tex) + half4(-dx,    -dy,     0.0,    -dy), // outer diag. texels
		half4(tex,tex) + half4( dx,    -dy,  2.0*dx,    -dy),
		half4(tex,tex) + half4(-dx,    0.0,     0.0,    0.0), // inner diag. texels
		half4(tex,tex) + half4( dx,    0.0,  2.0*dx,    0.0),
		half4(tex,tex) + half4(-dx,     dy,     0.0,     dy), // inner hor/vert texels
		half4(tex,tex) + half4( dx,     dy,  2.0*dx,     dy),
		half4(tex,tex) + half4(-dx, 2.0*dy,     0.0, 2.0*dy),
		half4(tex,tex) + half4( dx, 2.0*dy,  2.0*dx, 2.0*dy)
	};

	return OUT;
}


half l(half x)
{ 
  if (x==0.0)
  {
     return pi*halfpi;
  }
  else
  {
     return sin(x*halfpi)*sin(x*pi)/(x*x);
  }
}

half4 main_fragment(in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR
{
  half3 pix[4][4];
  half2 fract = frac(VAR.texCoord*IN.texture_size);

// calculating texel weights

  half a,b,c,d,p,q,r,s;

  a = l(1+fract.x); 
  b = l(  fract.x); 
  c = l(1-fract.x); 
  d = l(2-fract.x);

  p = l(1+fract.y); 
  q = l(  fract.y); 
  r = l(1-fract.y); 
  s = l(2-fract.y);

// reading the texels

  pix[0][0] = tex2D(s_p,VAR.t1.xy).xyz;
  pix[1][0] = tex2D(s_p,VAR.t1.zw).xyz;
  pix[2][0] = tex2D(s_p,VAR.t2.xy).xyz;
  pix[3][0] = tex2D(s_p,VAR.t2.zw).xyz;
  pix[0][1] = tex2D(s_p,VAR.t3.xy).xyz;
  pix[1][1] = tex2D(s_p,VAR.t3.zw).xyz;
  pix[2][1] = tex2D(s_p,VAR.t4.xy).xyz;
  pix[3][1] = tex2D(s_p,VAR.t4.zw).xyz;
  pix[0][2] = tex2D(s_p,VAR.t5.xy).xyz;
  pix[1][2] = tex2D(s_p,VAR.t5.zw).xyz;
  pix[2][2] = tex2D(s_p,VAR.t6.xy).xyz;
  pix[3][2] = tex2D(s_p,VAR.t6.zw).xyz;
  pix[0][3] = tex2D(s_p,VAR.t7.xy).xyz;
  pix[1][3] = tex2D(s_p,VAR.t7.zw).xyz;
  pix[2][3] = tex2D(s_p,VAR.t8.xy).xyz;
  pix[3][3] = tex2D(s_p,VAR.t8.zw).xyz;




// final sum and weight normalization 
return half4((mul(half4(p,q,r,s), half4x3(mul(half4(a,b,c,d), half4x3(-pix[0][0], pix[1][0], pix[2][0], -pix[3][0])),
					  mul(half4(a,b,c,d), half4x3( pix[0][1], pix[1][1], pix[2][1],  pix[3][1])),
                                          mul(half4(a,b,c,d), half4x3( pix[0][2], pix[1][2], pix[2][2],  pix[3][2])),
                                          mul(half4(a,b,c,d), half4x3(-pix[0][3], pix[1][3], pix[2][3], -pix[3][3])))))/((a+b+c+d)*(p+q+r+s)-2*(a+d)*(p+s)),1.0);
}

