/*
   Hyllian's 2xBR v2.1 Shader
   
   Copyright (C) 2011 Hyllian/Jararaca - sergiogdb@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.

*/

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

	uniform float4x4 modelViewProj,

	out float4 oPosition	: POSITION,
	out float4 oColor	: COLOR,
	out float2 otexCoord	: TEXCOORD
)
{
	oPosition = mul(modelViewProj, position);
	oColor = color;
	otexCoord = texCoord;
}

/*
	FRAGMENT SHADER
*/


const float3 dtt = float3(65536,255,1);

struct output
{
	float4 color	: COLOR;
};

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

float reduce(float3 color)
{ 
	return dot(color, dtt);
}

output main_fragment(float2 texCoord: TEXCOORD0, uniform sampler2D decal : TEXUNIT0, uniform input IN)
{

	float2 ps = float2(0.9999/IN.texture_size.x, 0.9999/IN.texture_size.y);
	float2 dx = float2(ps.x, 0.0);
	float2 dy = float2(0.0, ps.y);

	float2 pixcoord = texCoord/ps;
	float2 fp	= frac(pixcoord);
	float2 d11	= texCoord-fp*ps;

	// Reading the texels

	float3 A = tex2D(decal,d11-dx-dy).xyz;
	float3 B = tex2D(decal,d11   -dy).xyz;
	float3 C = tex2D(decal,d11+dx-dy).xyz;
	float3 D = tex2D(decal,d11-dx   ).xyz;
	float3 E = tex2D(decal,d11      ).xyz;
	float3 F = tex2D(decal,d11+dx   ).xyz;
	float3 G = tex2D(decal,d11-dx+dy).xyz;
	float3 H = tex2D(decal,d11+dy   ).xyz;
	float3 I = tex2D(decal,d11+dx+dy).xyz;
	
	float3 P00 = tex2D(decal,d11-dx-dx-dy-dy).xyz;
	float3 P04 = tex2D(decal,d11+dx+dx-dy-dy).xyz;
	float3 P40 = tex2D(decal,d11-dx-dx+dy+dy).xyz;
	float3 P44 = tex2D(decal,d11+dx+dx+dy+dy).xyz;
	float3  A1 = tex2D(decal,d11   -dx-dy-dy).xyz;
	float3  B1 = tex2D(decal,d11      -dy-dy).xyz;
	float3  C1 = tex2D(decal,d11   +dx-dy-dy).xyz;
	float3  A0 = tex2D(decal,d11-dx-dx-dy   ).xyz;
	float3  D0 = tex2D(decal,d11-dx-dx      ).xyz;
	float3  G0 = tex2D(decal,d11-dx-dx+dy   ).xyz;
	float3  C4 = tex2D(decal,d11+dx+dx-dy   ).xyz;
	float3  F4 = tex2D(decal,d11+dx+dx      ).xyz;
	float3  I4 = tex2D(decal,d11+dx+dx+dy   ).xyz;
	float3  G5 = tex2D(decal,d11   -dx+dy+dy).xyz;
	float3  H5 = tex2D(decal,d11      +dy+dy).xyz;
	float3  I5 = tex2D(decal,d11   +dx+dy+dy).xyz;

	float3 E0 = E;
	float3 E1 = E;
	float3 E2 = E;
	float3 E3 = E;

		
	float a = reduce(A);
	float b = reduce(B);
	float c = reduce(C);
	float d = reduce(D);
	float e = reduce(E);
	float f = reduce(F);
	float g = reduce(G);
	float h = reduce(H);
	float i = reduce(I);

	float p00 = reduce(P00);
	float p04 = reduce(P04);
	float p40 = reduce(P40);
	float p44 = reduce(P44);
	float  a1 = reduce( A1);
	float  b1 = reduce( B1);
	float  c1 = reduce( C1);
	float  a0 = reduce( A0);
	float  d0 = reduce( D0);
	float  g0 = reduce( G0);
	float  c4 = reduce( C4);
	float  f4 = reduce( F4);
	float  i4 = reduce( I4);
	float  g5 = reduce( G5);
	float  h5 = reduce( H5);
	float  i5 = reduce( I5);

	
	if ( e!=h && h==f && ( (e!=i && (e!=b || e!=d || f!=b && f!=c || h!=d && h!=g))
		|| (e==g && (i==h || e==d || h!=d))
		|| (e==c && (i==h || e==b || f!=b))
	      ))
		{
			if (e==c && e==d && h==g)
			{
				if (d==d0 && g==g0)
				{
					E3  = lerp(E3 , H,  0.8333);
					E2  = lerp(E2 , H,  0.5   );
				}
				else
				{
					E3  = lerp(E3 , H,  0.75);
					E2  = E2 + H - E3;
				}
			}
			else if (e==g && e==b && f==c)
			{
				if (b==b1 && c==c1)
				{
					E3  = lerp(E3 , F,  0.8333);
					E1  = lerp(E1 , F,  0.5   );
				}
				else
				{
					E3  = lerp(E3 , F,  0.75);
					E1  = E1 + F - E3;
				}
			}
			else
			{
				E3  = lerp(E3 , F,  0.5);
			}
		}
	else if (e!=h && e!=i && e!=f && e==g && e==c)
	{
		E3  = lerp(E3 , F,  0.5);
	}
	else if (f!=i && i==f4 && (f!=i4 || i!=p44) && f==c4 && f==e && i==h && e==d && h==g)
	{
		E3  = lerp(E3 , H,  0.25);
	}
	else if (h!=i && i==h5 && (h!=i5 || i!=p44) && h==g5 && h==e && i==f && e==b && f==c)
	{
		E3  = lerp(E3 , F,  0.25);
	}

	if ( e!=f && f==b && ( (e!=c && (e!=d || e!=h || b!=d && b!=a || f!=h && f!=i))
		|| (e==i && (c==f || e==h || f!=h))
		|| (e==a && (c==f || e==d || b!=d))
	      ) )
		{
			if (e==a && e==h && f==i)
			{
				if (h==h5 && i==i5)
				{
					E1  = lerp(E1 , F,  0.8333);
					E3  = lerp(E3 , F,  0.5   );
				}
				else
				{
					E1  = lerp(E1 , F,  0.75);
					E3  = E3 + F - E1;
				}
			}
			else if (e==i && e==d && b==a)
			{
				if (d==d0 && a==a0)
				{
					E1  = lerp(E1 , B,  0.8333);
					E0  = lerp(E0 , B,  0.5   );
				}
				else
				{
					E1  = lerp(E1 , B,  0.75);
					E0  = E0 + B - E1;
				}
			}
			else
			{
				E1  = lerp(E1 , B,  0.5);
			}
		}
	else if (e!=f && e!=c && e!=b && e==i && e==a)
	{
		E1  = lerp(E1 , B,  0.5);
	}
	else if (b!=c && c==b1 && (b!=c1 || c!=p04) && b==a1 && b==e && c==f && e==h && f==i)
	{
		E1  = lerp(E1 , F,  0.25);
	}
	else if (f!=c && c==f4 && (f!=c4 || c!=p04) && f==i4 && f==e && c==b && e==d && b==a)
	{
		E1  = lerp(E1 , B,  0.25);
	}



	if ( e!=b && b==d && ( (e!=a && (e!=h || e!=f || d!=h && d!=g || b!=f && b!=c))
		|| (e==c && (a==b || e==f || b!=f))
		|| (e==g && (a==b || e==h || d!=h))
	      ) )
		{
			if (e==g && e==f && b==c)
			{
				if (f==f4 && c==c4)
				{
					E0  = lerp(E0 , B,  0.8333);
					E1  = lerp(E1 , B,  0.5   );
				}
				else
				{
					E0  = lerp(E0 , B,  0.75);
					E1  = E1 + B - E0;
				}
			}
			else if (e==c && e==h && d==g)
			{
				if (h==h5 && g==g5)
				{
					E0  = lerp(E0 , D,  0.8333);
					E2  = lerp(E2 , D,  0.5   );
				}
				else
				{
					E0  = lerp(E0 , D,  0.75);
					E2  = E2 + D - E0;
				}
			}
			else
			{
				E0  = lerp(E0 , D,  0.5);
			}
		}
	else if (e!=b && e!=a && e!=d && e==c && e==g)
	{
		E0  = lerp(E0 , D,  0.5);
	}
	else if (d!=a && a==d0 && (d!=a0 || a!=p00) && d==g0 && d==e && a==b && e==f && b==c)
	{
		E0  = lerp(E0 , B,  0.25);
	}
	else if (b!=a && a==b1 && (b!=a1 || a!=p00) && b==c1 && b==e && a==d && e==h && d==g)
	{
		E0  = lerp(E0 , D,  0.25);
	}


	if ( e!=d && d==h && ( (e!=g && (e!=f || e!=b || h!=f && h!=i || d!=b && d!=a))
		|| (e==a && (g==d || e==b || d!=b))
		|| (e==i && (g==d || e==f || h!=f))
	      ))
		{
			if (e==i && e==b && d==a)
			{
				if (b==b1 && a==a1)
				{
					E2  = lerp(E2 , D,  0.8333);
					E0  = lerp(E0 , D,  0.5   );
				}
				else
				{
					E2  = lerp(E2 , D,  0.75);
					E0  = E0 + D - E2;
				}
			}
			else if (e==a && e==f && h==i)
			{
				if (f==f4 && i==i4)
				{
					E2  = lerp(E2 , H,  0.8333);
					E3  = lerp(E3 , H,  0.5   );
				}
				else
				{
					E2  = lerp(E2 , H,  0.75);
					E3  = E3 + H - E2;
				}
			}
			else
			{
				E2  = lerp(E2 , H,  0.5);
			}
		}
	else if (e!=d && e!=g && e!=h && e==a && e==i)
	{
		E2  = lerp(E2 , H,  0.5);
	}
	else if (h!=g && g==h5 && (h!=g5 || g!=p40) && h==i5 && h==e && g==d && e==b && d==a)
	{
		E2  = lerp(E2 , D,  0.25);
	}
	else if (d!=g && g==d0 && (d!=g0 || g!=p40) && d==a0 && d==e && g==h && e==f && h==i)
	{
		E2  = lerp(E2 , H,  0.25);
	}
	
	float3 res;

	res = (fp.x < 0.50) ? (fp.y < 0.50 ? E0 : E2) : (fp.y < 0.50 ? E1: E3);
	
	// Product interpolation
	output OUT;
	OUT.color = float4(res, 1.0); 
	return OUT;
}
