/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
   - FX11 compilers
*/

/*
	Scale2x

Filter:	Nearest
Scale:	2x

Scale2x 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  

*/

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

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

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);
	float2 ps = float2(1.0/COMPAT_texture_size.x, 1.0/COMPAT_texture_size.y);
	float dx = ps.x;
	float dy = ps.y;

	OUT.texCoord = texCoord;				// E
	OUT.t1 = texCoord.xyxy + float4(  0,-dy,-dx,  0);	// B, D
	OUT.t2 = texCoord.xyxy + float4( dx,  0,  0, dy);	// F, H	
	
	return OUT;
}

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

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

float3 scale2x(float2 texture_size, float4 t1, float4 t2, float2 texCoord, COMPAT_Texture2D(decal))
{
	// subpixel determination
	float2 fp = floor(2.0 * frac(texCoord*texture_size));

	/*
		  B		E0 E1
		D E F		E2 E3
		  H
	*/

	// reading the texels
	float3 B = COMPAT_SamplePoint(decal, t1.xy).xyz;
	float3 D = COMPAT_SamplePoint(decal, t1.zw).xyz;
	float3 E = COMPAT_SamplePoint(decal, texCoord).xyz;
	float3 F = COMPAT_SamplePoint(decal, t2.xy).xyz;
	float3 H = COMPAT_SamplePoint(decal, t2.zw).xyz;

	// rules
	float3 E0 = eq(B,D) ? B : E;
	float3 E1 = eq(B,F) ? B : E;
	float3 E2 = eq(H,D) ? H : E;
	float3 E3 = eq(H,F) ? H : E;

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

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return float4(scale2x(COMPAT_texture_size, VOUT.t1, VOUT.t2, VOUT.texCoord, decal), 1.0);
}
COMPAT_END