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

/*
   Hyllian - Retro Shader - 2013

   A re-implementation from the original made by Hyllian and DOLLS!
   
   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.
*/

#include "../../compat_includes.inc"

uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

struct out_vertex
{
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD;
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
};
/*
	VERTEX_SHADER
*/
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
*/
// This value must be between 0.0 (totally black) and 1.0 (nearest neighbor)
#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01
#ifdef PARAMETER_UNIFORM
uniform float RETRO_PIXEL_SIZE;
#else
#define RETRO_PIXEL_SIZE  0.84
#endif

float4 retro_v2(float2 texture_size, float2 video_size, float2 output_size, float2 texCoord, COMPAT_Texture2D(decal))
{
    // Reading the texel
    float power = 2.4;
    float3 E = pow(COMPAT_SamplePoint(decal, texCoord).xyz, float3(power, power, power));

    float2 fp = frac(texCoord*texture_size);
    float2 ps = video_size/output_size;

    float2 f = clamp(clamp(fp + 0.5*ps, 0.0, 1.0) - float2(RETRO_PIXEL_SIZE, RETRO_PIXEL_SIZE), 0.0, ps)/ps;

    float max_coord = max(f.x, f.y);

    float3 res = lerp(E*(1.04+fp.x*fp.y), E*0.36, max_coord);

    // Product interpolation
    float pwr = 1.0 / 2.2;
    return float4(clamp( pow(res, float3(pwr, pwr, pwr)), 0.0, 1.0 ), 1.0);
}

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