1
2///////////////
3//	TV-out tweaks Linearized Multipass - Pass1
4//	Author: aliaspider and RiskyJumps
5//	License: GPLv3
6////////////////////////////////////////////////////////
7
8
9// this shader is meant to be used when running
10// an emulator on a real CRT-TV @240p or @480i
11////////////////////////////////////////////////////////
12// Basic settings:
13
14// signal resolution
15// higher = sharper
16#pragma parameter TVOUT_RESOLUTION "TVOut Signal Resolution" 256.0 0.0 1024.0 32.0 // default, minimum, maximum, optional step
17
18// simulate a composite connection instead of RGB
19//#pragma parameter TVOUT_COMPOSITE_CONNECTION "TVOut Composite Enable" 0.0 0.0 1.0 1.0
20
21//// use TV video color range (16-235)
22//// instead of PC full range (0-255)
23//#pragma parameter TVOUT_TV_COLOR_LEVELS "TVOut TV Color Levels Enable" 0.0 0.0 1.0 1.0
24////////////////////////////////////////////////////////
25
26////////////////////////////////////////////////////////
27// Advanced settings:
28//
29// these values will be used instead
30// if COMPOSITE_CONNECTION is defined
31// to simulate different signal resolutions(bandwidth)
32// for luma (Y) and chroma ( I and Q )
33// this is just an approximation
34// and will only simulate the low bandwidth anspect of
35// composite signal, not the crosstalk between luma and chroma
36// Y = 4MHz I=1.3MHz Q=0.4MHz
37#pragma parameter TVOUT_RESOLUTION_Y "TVOut Luma (Y) Resolution" 256.0 0.0 1024.0 32.0
38#pragma parameter TVOUT_RESOLUTION_I "TVOut Chroma (I) Resolution" 83.2 0.0 256.0 8.0
39#pragma parameter TVOUT_RESOLUTION_Q "TVOut Chroma (Q) Resolution" 25.6 0.0 256.0 8.0
40
41// formula is MHz=resolution*15750Hz
42// 15750Hz being the horizontal Frequency of NTSC
43// (=262.5*60Hz)
44////////////////////////////////////////////////////////
45
46#if defined(VERTEX)
47
48#if __VERSION__ >= 130
49#define COMPAT_VARYING out
50#define COMPAT_ATTRIBUTE in
51#define COMPAT_TEXTURE texture
52#else
53#define COMPAT_VARYING varying
54#define COMPAT_ATTRIBUTE attribute
55#define COMPAT_TEXTURE texture2D
56#endif
57
58#ifdef GL_ES
59#define COMPAT_PRECISION mediump
60#else
61#define COMPAT_PRECISION
62#endif
63
64COMPAT_ATTRIBUTE vec4 VertexCoord;
65COMPAT_ATTRIBUTE vec4 COLOR;
66COMPAT_ATTRIBUTE vec4 TexCoord;
67COMPAT_VARYING vec4 COL0;
68COMPAT_VARYING vec4 TEX0;
69
70vec4 _oPosition1;
71uniform mat4 MVPMatrix;
72uniform COMPAT_PRECISION int FrameDirection;
73uniform COMPAT_PRECISION int FrameCount;
74uniform COMPAT_PRECISION vec2 OutputSize;
75uniform COMPAT_PRECISION vec2 TextureSize;
76uniform COMPAT_PRECISION vec2 InputSize;
77
78void main()
79{
80    gl_Position = MVPMatrix * VertexCoord;
81    TEX0.xy = TexCoord.xy;
82}
83
84#elif defined(FRAGMENT)
85
86#if __VERSION__ >= 130
87#define COMPAT_VARYING in
88#define COMPAT_TEXTURE texture
89out vec4 FragColor;
90#else
91#define COMPAT_VARYING varying
92#define FragColor gl_FragColor
93#define COMPAT_TEXTURE texture2D
94#endif
95
96#ifdef GL_ES
97#ifdef GL_FRAGMENT_PRECISION_HIGH
98precision highp float;
99#else
100precision mediump float;
101#endif
102#define COMPAT_PRECISION mediump
103#else
104#define COMPAT_PRECISION
105#endif
106
107#ifdef PARAMETER_UNIFORM // If the shader implementation understands #pragma parameters, this is defined.
108uniform COMPAT_PRECISION float TVOUT_RESOLUTION;
109uniform COMPAT_PRECISION float TVOUT_COMPOSITE_CONNECTION;
110uniform COMPAT_PRECISION float TVOUT_TV_COLOR_LEVELS;
111uniform COMPAT_PRECISION float TVOUT_RESOLUTION_Y;
112uniform COMPAT_PRECISION float TVOUT_RESOLUTION_I;
113uniform COMPAT_PRECISION float TVOUT_RESOLUTION_Q;
114#else
115// Fallbacks if parameters are not supported.
116#define TVOUT_RESOLUTION 256.0 // Default
117#define TVOUT_COMPOSITE_CONNECTION 0
118#define TVOUT_TV_COLOR_LEVELS 0
119#define TVOUT_RESOLUTION_Y 256.0
120#define TVOUT_RESOLUTION_I 83.2
121#define TVOUT_RESOLUTION_Q 25.6
122#endif
123
124#define pi			3.14159265358
125#define a(x) abs(x)
126#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))
127#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))
128#define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))
129
130#define GETC(c) \
131   if (TVOUT_COMPOSITE_CONNECTION > 0.5) \
132      c = ((COMPAT_TEXTURE(Texture, vec2(TEX0.x - X*oneT,TEX0.y)).xyz) * RGB_to_YIQ); \
133   else \
134      c = ((COMPAT_TEXTURE(Texture, vec2(TEX0.x - X*oneT,TEX0.y)).xyz))
135
136#define VAL(tempColor) \
137   if (TVOUT_COMPOSITE_CONNECTION > 0.5) \
138      tempColor += vec3((c.x*STU(X,(TVOUT_RESOLUTION_Y*oneI))),(c.y*STU(X,(TVOUT_RESOLUTION_I*oneI))),(c.z*STU(X,(TVOUT_RESOLUTION_Q*oneI)))); \
139   else \
140      tempColor += (c*STU(X,(TVOUT_RESOLUTION*oneI)))
141
142
143uniform COMPAT_PRECISION int FrameDirection;
144uniform COMPAT_PRECISION int FrameCount;
145uniform COMPAT_PRECISION vec2 OutputSize;
146uniform COMPAT_PRECISION vec2 TextureSize;
147uniform COMPAT_PRECISION vec2 InputSize;
148uniform sampler2D Texture;
149COMPAT_VARYING vec4 TEX0;
150
151void main()
152{
153mat3 RGB_to_YIQ = mat3(
154	0.300,  0.5900,  0.1100,
155	0.599, -0.2773, -0.3217,
156	0.213, -0.5251,  0.3121
157);
158
159mat3 YIQ_to_RGB = mat3(
160	1.0,  0.946882217090069,  0.623556581986143,
161	1.0, -0.274787646298978, -0.635691079187380,
162	1.0, -1.108545034642030,  1.709006928406470
163);
164
165   vec3 tempColor = vec3(0.0,0.0,0.0);
166   float	offset	= fract((TEX0.x * TextureSize.x) - 0.5);
167   float oneT = 1.0 / TextureSize.x;
168   float oneI = 1.0 / InputSize.x;
169
170   float X;
171   vec3 c;
172
173   X = (offset-(-1.0));//X(-1.0);
174   GETC(c);
175   VAL(tempColor);
176
177   X = (offset-(0.0));//X(0.0);
178   GETC(c);
179   VAL(tempColor);
180
181   X = (offset-(1.0));//X(1.0);
182   GETC(c);
183   VAL(tempColor);
184
185   X = (offset-(2.0));//X(2.0);
186   GETC(c);
187   VAL(tempColor);
188
189   if (TVOUT_COMPOSITE_CONNECTION > 0.5)
190      tempColor = tempColor * YIQ_to_RGB;
191
192   FragColor = vec4(pow(tempColor, vec3(1.0/2.2)), 1.0);
193}
194#endif
195