/*
	Scale3x

Filter:	Nearest
Scale:	3x

Scale3x is real-time graphics effect able to increase the size of small bitmaps guessing the missing pixels without blurring the images.
It was originally developed for the AdvanceMAME project in the year 2001 to improve the quality of old games with a low video resolution.

Homepage: http://scale2x.sourceforge.net/
Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni 
License: GNU-GPL  

*/


bool eq(float3 A, float3 B){
	return all(A==B);
}

bool neq(float3 A, float3 B){
	return any(A!=B);
}

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


struct out_vertex {
	float4 position : POSITION;
	float2 texCoord : TEXCOORD0;
	float4 t1 : TEXCOORD1;
	float4 t2 : TEXCOORD2;
	float4 t3 : TEXCOORD3;
};

/*    VERTEX_SHADER    */
out_vertex main_vertex
(
	float4 position	: POSITION,
	float2 texCoord : TEXCOORD0,

   	uniform float4x4 modelViewProj,
	uniform input IN
)
{
	out_vertex OUT;

	OUT.position = mul(modelViewProj, position);

	float2 ps = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
	float dx = ps.x;
	float dy = ps.y;

	OUT.texCoord = texCoord;
	OUT.t1 = texCoord.xxxy + float4(-dx,  0, dx,-dy);	// A, B, C
	OUT.t2 = texCoord.xxxy + float4(-dx,  0, dx,  0);	// D, E, F
	OUT.t3 = texCoord.xxxy + float4(-dx,  0, dx, dy);	// G, H, I

	return OUT;
}


float3 main_fragment(in out_vertex VAR, uniform sampler2D decal : TEXUNIT0, uniform input IN) : COLOR
{
	// subpixel determination
	float2 fp = floor(3.0 * frac(VAR.texCoord*IN.texture_size));

	/*
		A B C		E0 E1 E2
		D E F		E3 E4 E5
		G H I		E6 E7 E8
	*/

	// reading the texels
	float3 A = tex2D(decal, VAR.t1.xw).xyz;
	float3 B = tex2D(decal, VAR.t1.yw).xyz;
	float3 C = tex2D(decal, VAR.t1.zw).xyz;
	float3 D = tex2D(decal, VAR.t2.xw).xyz;
	float3 E = tex2D(decal, VAR.t2.yw).xyz;
	float3 F = tex2D(decal, VAR.t2.zw).xyz;
	float3 G = tex2D(decal, VAR.t3.xw).xyz;
	float3 H = tex2D(decal, VAR.t3.yw).xyz;
	float3 I = tex2D(decal, VAR.t3.zw).xyz;

	// equality checks
	bool eqBD = eq(B,D), eqBF = eq(B,F), eqHD = eq(H,D), eqHF = eq(H,F), neqEA = neq(E,A), neqEC = neq(E,C), neqEG = neq(E,G), neqEI = neq(E,I); 

	// rules
	float3 E0 = eqBD ? B : E;
	float3 E1 = eqBD && neqEC || eqBF && neqEA ? B : E;
	float3 E2 = eqBF ? B : E;
	float3 E3 = eqBD && neqEG || eqHD && neqEA ? D : E;
	float3 E5 = eqBF && neqEI || eqHF && neqEC ? F : E;
	float3 E6 = eqHD ? H : E;
	float3 E7 = eqHD && neqEI || eqHF && neqEG ? H : E;
	float3 E8 = eqHF ? H : E;

	// general condition & subpixel output
	return neq(B,H) && neq(D,F) ? (fp.y == 0 ? (fp.x == 0 ? E0 : fp.x == 1 ? E1 : E2) : (fp.y == 1 ? (fp.x == 0 ? E3 : fp.x == 1 ? E : E5) : (fp.x == 0 ? E6 : fp.x == 1 ? E7 : E8))) : E;
}
