#pragma parameter INTERNAL_RES "Internal Resolution" 1.0 1.0 8.0 1.0
#ifdef PARAMETER_UNIFORM
uniform float INTERNAL_RES;
#else
#define INTERNAL_RES  1.0
#endif
// END PARAMETERS //

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

//##############################################################//
//						                //
//       AA Shader 4.o shader - coded by guest(r)               //
//		     part of code by ShadX		        //
//##############################################################// 
// Ported by Hyllian - 2015

#include "../../compat_includes.inc"
uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

static const float3 dt = float3(1.0,1.0,1.0);

float3 texture2d (COMPAT_Texture2D(s2D), float2 texcoord, float4 yx)
{
	float3 s00 = COMPAT_SamplePoint(s2D, texcoord + yx.zw).xyz; 
	float3 s20 = COMPAT_SamplePoint(s2D, texcoord + yx.xw).xyz; 
	float3 s22 = COMPAT_SamplePoint(s2D, texcoord + yx.xy).xyz; 
	float3 s02 = COMPAT_SamplePoint(s2D, texcoord + yx.zy).xyz; 

	float m1=dot(abs(s00-s22),dt)+0.001;
	float m2=dot(abs(s02-s20),dt)+0.001;

	return .5*(m2*(s00+s22)+m1*(s02+s20))/(m1+m2);
}

struct out_vertex
{
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD0;
};

out_vertex main_vertex(COMPAT_IN_VERTEX)
{
	out_vertex OUT;
#ifdef HLSL_4
	float4 position = VIN.position;
	float2 texCoord = VIN.texCoord;
#else
	OUT.Color = color;
#endif

	OUT.position = mul(modelViewProj, position);
	OUT.texCoord = texCoord;

	return OUT;
}


/*    FRAGMENT SHADER    */
float4 aa_shader_4_o(float2 texture_size, float2 video_size, float2 output_size, COMPAT_Texture2D(decal), float2 texCoord)
{
	// Calculating texel coordinates
	float2 size     = 4.0*texture_size/INTERNAL_RES;
//	float2 size     = X*(output_size/video_size)*texture_size;
	float2 inv_size = 1/size;

	float4 yx = float4(inv_size, -inv_size);
	
	float2 OGL2Pos = texCoord*size;

	float2 fp = frac(OGL2Pos);
	float2 dx = float2(inv_size.x,0.0);
	float2 dy = float2(0.0, inv_size.y);
	float2 g1 = float2(inv_size.x,inv_size.y);
	float2 g2 = float2(-inv_size.x,inv_size.y);
	
	float2 pC4 = floor(OGL2Pos) * inv_size;	
	
	// Reading the texels
	float3 C0 = texture2d(decal, pC4 - g1, yx); 
	float3 C1 = texture2d(decal, pC4 - dy, yx);
	float3 C2 = texture2d(decal, pC4 - g2, yx);
	float3 C3 = texture2d(decal, pC4 - dx, yx);
	float3 C4 = texture2d(decal, pC4     , yx);
	float3 C5 = texture2d(decal, pC4 + dx, yx);
	float3 C6 = texture2d(decal, pC4 + g2, yx);
	float3 C7 = texture2d(decal, pC4 + dy, yx);
	float3 C8 = texture2d(decal, pC4 + g1, yx);
	
	float3 ul, ur, dl, dr;
	float m1, m2;
	
	m1 = dot(abs(C0-C4),dt)+0.001;
	m2 = dot(abs(C1-C3),dt)+0.001;
	ul = (m2*(C0+C4)+m1*(C1+C3))/(m1+m2);  
	
	m1 = dot(abs(C1-C5),dt)+0.001;
	m2 = dot(abs(C2-C4),dt)+0.001;
	ur = (m2*(C1+C5)+m1*(C2+C4))/(m1+m2);
	
	m1 = dot(abs(C3-C7),dt)+0.001;
	m2 = dot(abs(C6-C4),dt)+0.001;
	dl = (m2*(C3+C7)+m1*(C6+C4))/(m1+m2);
	
	m1 = dot(abs(C4-C8),dt)+0.001;
	m2 = dot(abs(C5-C7),dt)+0.001;
	dr = (m2*(C4+C8)+m1*(C5+C7))/(m1+m2);
	
	float3 c11 = 0.5*((dr*fp.x+dl*(1-fp.x))*fp.y+(ur*fp.x+ul*(1-fp.x))*(1-fp.y) );

	return float4(c11, 1.0);
}

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return aa_shader_4_o(COMPAT_texture_size, COMPAT_video_size, COMPAT_output_size, decal, VOUT.texCoord);
}
COMPAT_END