// Anaglyph to Side-by-Side
// by hunterk
// license: public domain
//
// This shader is designed to convert Mednafen-VB's anaglyph 3D output to
// side-by-side 3D for use with VR headsets, such as Oculus Rift and Google Cardboard.

#pragma parameter eye_sep "Eye Separation" 0.35 -1.0 5.0 0.01
#pragma parameter y_loc "Vertical Placement" 0.30 -1.0 1.0 0.025
#pragma parameter BOTH "Horizontal Placement" 0.64 -2.0 2.0 0.005
#pragma parameter ana_zoom "Zoom" 0.75 -2.0 2.0 0.05
#pragma parameter WIDTH "Side-by-Side Image Width" 3.05 1.0 7.0 0.05
#pragma parameter HEIGHT "Side-by-Side Image Height" 2.0 1.0 5.0 0.1
#pragma parameter palette "Red Palette Toggle" 0.0 0.0 1.0 1.0
#pragma parameter warpX "warpX" 0.3 0.0 0.5 0.05
#pragma parameter warpY "warpY" 0.3 0.0 0.5 0.05
#ifdef PARAMETER_UNIFORM
uniform float eye_sep;
uniform float y_loc;
uniform float ana_zoom;
uniform float WIDTH;
uniform float BOTH;
uniform float HEIGHT;
uniform float palette;
uniform float warpX;
uniform float warpY;
#else
#define eye_sep 0.35
#define y_loc 0.30
#define ana_zoom 0.75
#define WIDTH 3.05
#define BOTH 0.64
#define HEIGHT 2.0
#define palette 0.0
#define warpX 0.3
#define warpY 0.3
#endif

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

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

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

    uniform float4x4 modelViewProj,
	uniform input IN,

	out float4 oPosition : POSITION,
	out float4 oColor    : COLOR,
	out float2 otexCoord : TEXCOORD
)
{
	float2 shift = 0.5 * IN.video_size / IN.texture_size;
	oPosition = mul(modelViewProj, position);
	oColor = color;
	otexCoord = ((texCoord - shift) * ana_zoom + shift) * float2(WIDTH, HEIGHT) - float2(BOTH, 0.0);
}

struct output 
{
  float4 color    : COLOR;
};

//warp function from Lottes' scanline shader
float2 Warp(float2 pos){
  pos=pos*2.0-1.0;    
  pos*=float2(1.0+(pos.y*pos.y)*warpX,1.0+(pos.x*pos.x)*warpY);
  return pos*0.5+0.5;}

output main_fragment(float2 texCoord : TEXCOORD0, uniform sampler2D decal : TEXUNIT0, uniform input IN) 
{
float2 warpCoord1 = Warp((texCoord.xy - float2(eye_sep, y_loc))*(IN.texture_size.xy / IN.video_size.xy))*(IN.video_size.xy / IN.texture_size.xy);
float2 warpCoord2 = Warp((texCoord.xy + float2(eye_sep, -y_loc))*(IN.texture_size.xy / IN.video_size.xy))*(IN.video_size.xy / IN.texture_size.xy);

float2 fragCoord1 = warpCoord1 * IN.video_size / IN.texture_size;
float2 fragCoord2 = warpCoord2 * IN.video_size / IN.texture_size;

//ghetto imitation of CLAMP_TO_BORDER
float4 frame1 = float4(0.0);
if ( fragCoord1.x < 1.0 && fragCoord1.x > 0.0 && fragCoord1.y < 1.0 && fragCoord1.y > 0.0 )
frame1 = tex2D(decal, warpCoord1);

float4 frame2 = float4(0.0);
if ( fragCoord2.x < 1.0 && fragCoord2.x > 0.0 && fragCoord2.y < 1.0 && fragCoord2.y > 0.0 )
frame2 = tex2D(decal, warpCoord2);

frame1.gb = float2(frame1.r);
frame2.r = frame2.g;

float4 final = float4(0.0);
if (palette > 0.5)
final = frame1 + frame2;
else
final = float4(frame1.r + frame2.r, 0.0, 0.0, 1.0);

   output OUT;
   OUT.color = final;
   return OUT;
}