mirror of
https://github.com/holub/mame
synced 2025-10-04 00:23:43 +03:00
NTSC Refactoring and Options
- merged YIQ encode and decode pass into one NTSC pass - added options for most NTSC settings - reduced sample count to 64 - changed default O value to 0 - fit NTSC signal jitter between a reasonable limit of 0 and 1 - fit A and B value between a reasonable limit of -1 and 1 - fit scanline jitter between a reasonable limit of 0 and 1 - added hum bar simulation based on [MooglyGuy's] GLSL port of the mame shader pipeline - added monochrome-chessboard.png - added slot-mask-aligned.png (to simulate a TFT LCD)
This commit is contained in:
parent
ded9493cb0
commit
d516871e6f
BIN
artwork/monochrome-chessboard.png
Normal file
BIN
artwork/monochrome-chessboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB |
BIN
artwork/slot-mask-aligned.png
Normal file
BIN
artwork/slot-mask-aligned.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -38,15 +38,16 @@ scanline_size 0.0 to 4.0 The overall height of each scanline.
|
||||
scanline_height [height] Individual height scaling value for scanlines.
|
||||
scanline_bright_scale 0.0 to 2.0 The overall brightness multiplier for each scanline.
|
||||
scanline_bright_offset 0.0 to 1.0 The overall brightness additive value for each scanline.
|
||||
scanline_jitter 0.0 to 2.0 The relative scanline movement per field.
|
||||
scanline_jitter 0.0 to 1.0 The relative scanline movement per field.
|
||||
hum_bar_alpha 0.0 to 1.0 The maximum darkness of the hum bar gradient.
|
||||
defocus [xval,yval] This defines the overall defocus radius for the three
|
||||
post-converged beams. Values allowed range from 0.0 to
|
||||
32.0.
|
||||
post-converged beams. Values allowed range from 0.0 to
|
||||
10.0.
|
||||
converge_x [r,g,b] Convergence in screen-relative X direction.
|
||||
converge_y [r,g,b] Convergence in screen-relative Y direction.
|
||||
radial_converge_x [r,g,b] Radial convergence in screen-relative X direction.
|
||||
radial_converge_y [r,g,b] Radial convergence in screen-relative Y direction.
|
||||
Allowed values for convergence: -150 to 150 for each color.
|
||||
Allowed values for convergence: -10.0 to 10.0 for each color.
|
||||
red_ratio [r,g,b] These parameters define a 3x3 matrix which is multiplied
|
||||
grn_ratio [r,g,b] by the incoming RGB signal. This can be used for any
|
||||
blu_ratio [r,g,b] standard matrix convolution, including H/S/V or simply
|
||||
@ -78,15 +79,16 @@ NTSC Processing Parameters
|
||||
--------------------------
|
||||
|
||||
Name Default Values Description
|
||||
yiq_cc 3.59754545 Color Carrier frequency for NTSC signal processing.
|
||||
yiq_a 0.5 A value for NTSC signal processing.
|
||||
yiq_b 0.5 B value for NTSC signal processing.
|
||||
yiq_o 0.0 Outgoing Color Carrier phase offset for NTSC signal processing.
|
||||
yiq_p 1.0 Incoming Pixel Clock scaling value for NTSC signal processing.
|
||||
yiq_n 1.0 Y filter notch width for NTSC signal processing.
|
||||
yiq_y 6.0 Y filter cutoff frequency for NTSC signal processing.
|
||||
yiq_i 1.2 I filter cutoff frequency for NTSC signal processing.
|
||||
yiq_q 0.6 Q filter cutoff frequency for NTSC signal processing.
|
||||
yiq_jitter 0.0 Jitter for the NTSC signal processing. (0.0 to 1.0)
|
||||
yiq_cc 3.57954545 Color Carrier frequency for NTSC signal processing. (0.0 to 6.0)
|
||||
yiq_a 0.5 A value for NTSC signal processing. (-1.0 to 1.0)
|
||||
yiq_b 0.5 B value for NTSC signal processing. (-1.0 to 1.0)
|
||||
yiq_o 0.0 Outgoing Color Carrier phase offset for NTSC signal processing. (-3.0 to 3.0)
|
||||
yiq_p 1.0 Incoming Pixel Clock scaling value for NTSC signal processing. (-3.0 to 3.0)
|
||||
yiq_n 1.0 Y filter notch width for NTSC signal processing. (0.0 to 6.0)
|
||||
yiq_y 6.0 Y filter cutoff frequency for NTSC signal processing. (0.0 to 6.0)
|
||||
yiq_i 1.2 I filter cutoff frequency for NTSC signal processing. (0.0 to 6.0)
|
||||
yiq_q 0.6 Q filter cutoff frequency for NTSC signal processing. (0.0 to 6.0)
|
||||
yiq_scan_time 52.6 Horizontal scanline duration for NTSC signal processing. (usec)
|
||||
yiq_phase_count 2 Phase Count value for NTSC signal processing. (3 for NES, else 2)
|
||||
|
||||
|
@ -151,6 +151,11 @@ VS_OUTPUT vs_main(VS_INPUT Input)
|
||||
// Scanline, Shadowmask & Distortion Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
|
||||
uniform float HumBarAlpha = 0.0f;
|
||||
|
||||
uniform float TimeMilliseconds = 0.0f;
|
||||
|
||||
uniform float2 ScreenScale = float2(1.0f, 1.0f);
|
||||
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
|
||||
|
||||
@ -396,7 +401,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
}
|
||||
|
||||
// Mask Simulation (may not affect bloom)
|
||||
if (!PrepareBloom)
|
||||
if (!PrepareBloom && ShadowAlpha > 0.0f)
|
||||
{
|
||||
float2 shadowDims = ShadowDims;
|
||||
shadowDims = SwapXY
|
||||
@ -455,15 +460,24 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
// Scanline Simulation (may not affect bloom)
|
||||
if (!PrepareBloom)
|
||||
{
|
||||
// Scanline Simulation (disabled for vector)
|
||||
if (!PrepareVector)
|
||||
// Scanline Simulation (may not affect vector screen)
|
||||
if (!PrepareVector && ScanlineAlpha > 0.0f)
|
||||
{
|
||||
float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y;
|
||||
float ScanJitter = ScanlineOffset * SourceDims.y;
|
||||
float ScanBrightMod = sin(InnerSine * PI + ScanJitter);
|
||||
float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha);
|
||||
float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI;
|
||||
float ScanCoordJitter = ScanlineOffset * PHI;
|
||||
float ScanSine = sin(ScanCoord + ScanCoordJitter);
|
||||
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight);
|
||||
float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset;
|
||||
|
||||
BaseColor.rgb *= ScanColor;
|
||||
BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha);
|
||||
}
|
||||
|
||||
// Hum Bar Simulation (may not affect vector screen)
|
||||
if (!PrepareVector && HumBarAlpha > 0.0f)
|
||||
{
|
||||
float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate);
|
||||
float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha;
|
||||
BaseColor.rgb *= HumBrightness;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,26 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Decode Effect
|
||||
// NTSC Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sampler Definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
texture Composite;
|
||||
|
||||
sampler CompositeSampler = sampler_state
|
||||
{
|
||||
Texture = <Composite>;
|
||||
MipFilter = POINT;
|
||||
MinFilter = POINT;
|
||||
MagFilter = POINT;
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
AddressW = CLAMP;
|
||||
};
|
||||
|
||||
texture Diffuse;
|
||||
|
||||
sampler DiffuseSampler = sampler_state
|
||||
@ -81,51 +68,90 @@ VS_OUTPUT vs_main(VS_INPUT Input)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Decode Pixel Shader
|
||||
// NTSC Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float AValue = 0.5f;
|
||||
uniform float BValue = 0.5f;
|
||||
uniform float CCValue = 3.5975454f;
|
||||
uniform float CCValue = 3.5795454f;
|
||||
uniform float OValue = 0.0f;
|
||||
uniform float PValue = 1.0f; // unused
|
||||
|
||||
uniform float PValue = 1.0f;
|
||||
uniform float ScanTime = 52.6f;
|
||||
uniform float FrameOffset = 0.0f;
|
||||
|
||||
uniform float NotchHalfWidth = 1.0f;
|
||||
uniform float YFreqResponse = 6.0f;
|
||||
uniform float IFreqResponse = 1.2f;
|
||||
uniform float QFreqResponse = 0.6f;
|
||||
|
||||
uniform float SignalOffset = 0.0f;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const float PI = 3.1415927f;
|
||||
static const float PI2 = PI * 2.0f;
|
||||
|
||||
static const float4 YDot = float4(0.299f, 0.587f, 0.114f, 0.0f);
|
||||
static const float4 IDot = float4(0.595716f, -0.274453f, -0.321263f, 0.0f);
|
||||
static const float4 QDot = float4(0.211456f, -0.522591f, 0.311135f, 0.0f);
|
||||
|
||||
static const float3 RDot = float3(1.0f, 0.956f, 0.621f);
|
||||
static const float3 GDot = float3(1.0f, -0.272f, -0.647f);
|
||||
static const float3 BDot = float3(1.0f, -1.106f, 1.703f);
|
||||
|
||||
static const float4 OffsetX = float4(0.0f, 0.25f, 0.50f, 0.75f);
|
||||
static const float4 NotchOffset = float4(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
static const float PI = 3.1415927f;
|
||||
static const float PI2 = 6.2831855f;
|
||||
static const int SampleCount = 64;
|
||||
static const int HalfSampleCount = SampleCount / 2;
|
||||
|
||||
static const float MaxC = 2.1183f;
|
||||
static const float MinC = -1.1183f;
|
||||
static const float CRange = 3.2366f;
|
||||
float4 GetCompositeYIQ(float2 TexCoord)
|
||||
{
|
||||
float2 SourceTexelDims = 1.0f / SourceDims;
|
||||
float2 SourceRes = SourceDims * SourceRect;
|
||||
|
||||
float2 PValueSourceTexel = float2(PValue, 0.0f) * SourceTexelDims;
|
||||
|
||||
float2 C0 = TexCoord + PValueSourceTexel * OffsetX.x;
|
||||
float2 C1 = TexCoord + PValueSourceTexel * OffsetX.y;
|
||||
float2 C2 = TexCoord + PValueSourceTexel * OffsetX.z;
|
||||
float2 C3 = TexCoord + PValueSourceTexel * OffsetX.w;
|
||||
float4 Cx = float4(C0.x, C1.x, C2.x, C3.x);
|
||||
float4 Cy = float4(C0.y, C1.y, C2.y, C3.y);
|
||||
float4 Texel0 = tex2D(DiffuseSampler, C0);
|
||||
float4 Texel1 = tex2D(DiffuseSampler, C1);
|
||||
float4 Texel2 = tex2D(DiffuseSampler, C2);
|
||||
float4 Texel3 = tex2D(DiffuseSampler, C3);
|
||||
|
||||
float4 HPosition = Cx / SourceRect.x;
|
||||
float4 VPosition = Cy / SourceRect.y;
|
||||
|
||||
float4 Y = float4(dot(Texel0, YDot), dot(Texel1, YDot), dot(Texel2, YDot), dot(Texel3, YDot));
|
||||
float4 I = float4(dot(Texel0, IDot), dot(Texel1, IDot), dot(Texel2, IDot), dot(Texel3, IDot));
|
||||
float4 Q = float4(dot(Texel0, QDot), dot(Texel1, QDot), dot(Texel2, QDot), dot(Texel3, QDot));
|
||||
|
||||
float4 W = PI2 * CCValue * ScanTime;
|
||||
|
||||
float4 T = HPosition
|
||||
+ (AValue / 360.0f * SourceRes.y) * VPosition
|
||||
+ (BValue / 360.0f)
|
||||
+ (SignalOffset / 360.0f);
|
||||
float4 TW = T * W;
|
||||
|
||||
float4 CompositeYIQ = Y + I * cos(TW) + Q * sin(TW);
|
||||
|
||||
return CompositeYIQ;
|
||||
}
|
||||
|
||||
float4 ps_main(PS_INPUT Input) : COLOR
|
||||
{
|
||||
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord.xy);
|
||||
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
|
||||
|
||||
float2 InvDims = 1.0f / SourceDims;
|
||||
float2 SourceTexelDims = 1.0f / SourceDims;
|
||||
float2 SourceRes = SourceDims * SourceRect;
|
||||
|
||||
// YIQ convolution: N coefficients each
|
||||
float4 YAccum = 0.0f;
|
||||
float4 IAccum = 0.0f;
|
||||
float4 QAccum = 0.0f;
|
||||
|
||||
float BValueFrameOffset = BValue * FrameOffset;
|
||||
|
||||
float FrameWidthx4 = SourceDims.x * SourceRect.x * 4.0f;
|
||||
float TimePerSample = ScanTime / FrameWidthx4;
|
||||
float TimePerSample = ScanTime / (SourceRes.x * 4.0f);
|
||||
|
||||
float Fc_y1 = (CCValue - NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y2 = (CCValue + NotchHalfWidth) * TimePerSample;
|
||||
@ -142,24 +168,34 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
float Fc_y1_pi2 = Fc_y1 * PI2;
|
||||
float Fc_y2_pi2 = Fc_y2 * PI2;
|
||||
float Fc_y3_pi2 = Fc_y3 * PI2;
|
||||
float PI2Length = PI2 / 82.0f;
|
||||
float PI2Length = PI2 / SampleCount;
|
||||
|
||||
float W = PI2 * CCValue * ScanTime;
|
||||
|
||||
float4 YAccum = 0.0f;
|
||||
float4 IAccum = 0.0f;
|
||||
float4 QAccum = 0.0f;
|
||||
|
||||
float4 Cy = Input.TexCoord.y;
|
||||
float4 VPosition = Cy * (SourceDims.y * SourceRect.y) * 2.0f;
|
||||
float4 VPosition = Cy / SourceRect.y;
|
||||
|
||||
for(float n = -41.0f; n < 42.0f; n += 4.0f)
|
||||
for (float i = 0; i < SampleCount; i += 4.0f)
|
||||
{
|
||||
float n = i - HalfSampleCount;
|
||||
|
||||
float4 n4 = n + NotchOffset;
|
||||
|
||||
float4 Cx = Input.TexCoord.x + InvDims.x * n4 * 0.25f;
|
||||
float4 HPosition = (Cx / SourceRect.x);
|
||||
float4 Cx = Input.TexCoord.x + SourceTexelDims.x * (n4 * 0.25f);
|
||||
float4 HPosition = Cx / SourceRect.x;
|
||||
|
||||
float4 C = tex2D(CompositeSampler, float2(Cx.r, Cy.r)) * CRange + MinC;
|
||||
float4 C = GetCompositeYIQ(float2(Cx.r, Cy.r));
|
||||
|
||||
float4 T = HPosition + AValue * VPosition + BValueFrameOffset;
|
||||
float4 WT = W * T + OValue;
|
||||
float4 T = HPosition
|
||||
+ (AValue / 360.0f * SourceRes.y) * VPosition
|
||||
+ (BValue / 360.0f)
|
||||
+ (SignalOffset / 360.0f);
|
||||
float4 WT = W * T
|
||||
+ OValue;
|
||||
|
||||
float4 SincKernel = 0.54f + 0.46f * cos(PI2Length * n4);
|
||||
|
||||
@ -186,21 +222,21 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
QAccum = QAccum + C * sin(WT) * FilterQ;
|
||||
}
|
||||
|
||||
float Y = YAccum.r + YAccum.g + YAccum.b + YAccum.a;
|
||||
float I = (IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0f;
|
||||
float Q = (QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0f;
|
||||
float3 YIQ = float3(
|
||||
(YAccum.r + YAccum.g + YAccum.b + YAccum.a),
|
||||
(IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0f,
|
||||
(QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0f);
|
||||
|
||||
float3 YIQ = float3(Y, I, Q);
|
||||
float3 RGB = float3(
|
||||
dot(YIQ, RDot),
|
||||
dot(YIQ, GDot),
|
||||
dot(YIQ, BDot));
|
||||
|
||||
float3 Decode = float3(
|
||||
dot(YIQ, float3(1.0f, 0.956f, 0.621f)),
|
||||
dot(YIQ, float3(1.0f, -0.272f, -0.647f)),
|
||||
dot(YIQ, float3(1.0f, -1.106f, 1.703f)));
|
||||
return float4(Decode, BaseTexel.a);
|
||||
return float4(RGB, BaseTexel.a);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Decode Technique
|
||||
// NTSC Technique
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
technique DefaultTechnique
|
30
hlsl/post.fx
30
hlsl/post.fx
@ -65,6 +65,7 @@ struct PS_INPUT
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const float PI = 3.1415927f;
|
||||
static const float PHI = 1.618034f;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanline & Shadowmask Vertex Shader
|
||||
@ -118,6 +119,11 @@ VS_OUTPUT vs_main(VS_INPUT Input)
|
||||
// Scanline & Shadowmask Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
|
||||
uniform float HumBarAlpha = 0.0f;
|
||||
|
||||
uniform float TimeMilliseconds = 0.0f;
|
||||
|
||||
uniform float2 ScreenScale = float2(1.0f, 1.0f);
|
||||
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
|
||||
|
||||
@ -159,6 +165,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
{
|
||||
float2 ScreenTexelDims = 1.0f / ScreenDims;
|
||||
float2 SourceTexelDims = 1.0f / SourceDims;
|
||||
float2 SourceRes = SourceDims * SourceRect;
|
||||
|
||||
float2 HalfSourceRect = SourceRect * 0.5f;
|
||||
|
||||
@ -175,7 +182,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
}
|
||||
|
||||
// Mask Simulation (may not affect bloom)
|
||||
if (!PrepareBloom)
|
||||
if (!PrepareBloom && ShadowAlpha > 0.0f)
|
||||
{
|
||||
float2 shadowDims = ShadowDims;
|
||||
shadowDims = SwapXY
|
||||
@ -235,14 +242,23 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
if (!PrepareBloom)
|
||||
{
|
||||
// Scanline Simulation (may not affect vector screen)
|
||||
if (!PrepareVector)
|
||||
if (!PrepareVector && ScanlineAlpha > 0.0f)
|
||||
{
|
||||
float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y;
|
||||
float ScanJitter = ScanlineOffset * SourceDims.y;
|
||||
float ScanBrightMod = sin(InnerSine * PI + ScanJitter);
|
||||
float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha);
|
||||
float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI;
|
||||
float ScanCoordJitter = ScanlineOffset * PHI;
|
||||
float ScanSine = sin(ScanCoord + ScanCoordJitter);
|
||||
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight);
|
||||
float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset;
|
||||
|
||||
BaseColor.rgb *= ScanColor;
|
||||
BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha);
|
||||
}
|
||||
|
||||
// Hum Bar Simulation (may not affect vector screen)
|
||||
if (!PrepareVector && HumBarAlpha > 0.0f)
|
||||
{
|
||||
float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate);
|
||||
float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha;
|
||||
BaseColor.rgb *= HumBrightness;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,151 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Encode Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sampler Definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
texture Diffuse;
|
||||
|
||||
sampler DiffuseSampler = sampler_state
|
||||
{
|
||||
Texture = <Diffuse>;
|
||||
MipFilter = LINEAR;
|
||||
MinFilter = LINEAR;
|
||||
MagFilter = LINEAR;
|
||||
AddressU = CLAMP;
|
||||
AddressV = CLAMP;
|
||||
AddressW = CLAMP;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vertex Definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Encode Vertex Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float2 ScreenDims;
|
||||
uniform float2 SourceDims;
|
||||
uniform float2 SourceRect;
|
||||
|
||||
VS_OUTPUT vs_main(VS_INPUT Input)
|
||||
{
|
||||
VS_OUTPUT Output = (VS_OUTPUT)0;
|
||||
|
||||
Output.Position = float4(Input.Position.xyz, 1.0f);
|
||||
Output.Position.xy /= ScreenDims;
|
||||
Output.Position.y = 1.0f - Output.Position.y; // flip y
|
||||
Output.Position.xy -= 0.5f; // center
|
||||
Output.Position.xy *= 2.0f; // zoom
|
||||
|
||||
Output.TexCoord = Input.TexCoord;
|
||||
Output.TexCoord += 0.5f / SourceDims; // half texel offset correction (DX9)
|
||||
|
||||
Output.Color = Input.Color;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Encode Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float AValue = 0.5f;
|
||||
uniform float BValue = 0.5f;
|
||||
uniform float CCValue = 3.5975454f;
|
||||
uniform float OValue = 0.0f;
|
||||
uniform float PValue = 1.0f;
|
||||
|
||||
uniform float ScanTime = 52.6f;
|
||||
uniform float FrameOffset = 0.0f;
|
||||
|
||||
uniform float MaxC = 2.1183f;
|
||||
uniform float MinC = -1.1183f;
|
||||
uniform float CRange = 3.2366f;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const float4 YDot = float4(0.299f, 0.587f, 0.114f, 0.0f);
|
||||
static const float4 IDot = float4(0.595716f, -0.274453f, -0.321263f, 0.0f);
|
||||
static const float4 QDot = float4(0.211456f, -0.522591f, 0.311135f, 0.0f);
|
||||
static const float4 OffsetX = float4(0.0f, 0.25f, 0.50f, 0.75f);
|
||||
|
||||
static const float PI = 3.1415927f;
|
||||
static const float PI2 = 6.2831855f;
|
||||
|
||||
float4 ps_main(PS_INPUT Input) : COLOR
|
||||
{
|
||||
float2 InvDims = 1.0f / SourceDims;
|
||||
|
||||
float2 InvPValue = float2(PValue, 0.0f) * InvDims;
|
||||
|
||||
float2 C0 = Input.TexCoord + InvPValue * OffsetX.x;
|
||||
float2 C1 = Input.TexCoord + InvPValue * OffsetX.y;
|
||||
float2 C2 = Input.TexCoord + InvPValue * OffsetX.z;
|
||||
float2 C3 = Input.TexCoord + InvPValue * OffsetX.w;
|
||||
float4 Cx = float4(C0.x, C1.x, C2.x, C3.x);
|
||||
float4 Cy = float4(C0.y, C1.y, C2.y, C3.y);
|
||||
float4 Texel0 = tex2D(DiffuseSampler, C0);
|
||||
float4 Texel1 = tex2D(DiffuseSampler, C1);
|
||||
float4 Texel2 = tex2D(DiffuseSampler, C2);
|
||||
float4 Texel3 = tex2D(DiffuseSampler, C3);
|
||||
|
||||
float4 Y = float4(dot(Texel0, YDot), dot(Texel1, YDot), dot(Texel2, YDot), dot(Texel3, YDot));
|
||||
float4 I = float4(dot(Texel0, IDot), dot(Texel1, IDot), dot(Texel2, IDot), dot(Texel3, IDot));
|
||||
float4 Q = float4(dot(Texel0, QDot), dot(Texel1, QDot), dot(Texel2, QDot), dot(Texel3, QDot));
|
||||
|
||||
float BValueFrameOffset = BValue * FrameOffset;
|
||||
|
||||
float4 HPosition = Cx / SourceRect.x;
|
||||
float4 VPosition = Cy * (SourceDims.y * SourceRect.y) * 2.0f;
|
||||
|
||||
float4 W = PI2 * CCValue * ScanTime;
|
||||
float4 T = HPosition + AValue * VPosition + BValueFrameOffset;
|
||||
float4 TW = T * W + OValue;
|
||||
|
||||
float4 Encoded = Y + I * cos(TW) + Q * sin(TW);
|
||||
|
||||
return (Encoded - MinC) / CRange;;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// YIQ Encode Technique
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
technique DefaultTechnique
|
||||
{
|
||||
pass Pass0
|
||||
{
|
||||
Lighting = FALSE;
|
||||
|
||||
VertexShader = compile vs_3_0 vs_main();
|
||||
PixelShader = compile ps_3_0 ps_main();
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ shaders::shaders() :
|
||||
vecbuf_type(), vecbuf_index(0), vecbuf_count(0), avi_output_file(NULL), avi_frame(0), avi_copy_surface(NULL), avi_copy_texture(NULL), avi_final_target(NULL), avi_final_texture(NULL),
|
||||
black_surface(NULL), black_texture(NULL), render_snap(false), snap_rendered(false), snap_copy_target(NULL), snap_copy_texture(NULL), snap_target(NULL), snap_texture(NULL),
|
||||
snap_width(0), snap_height(0), lines_pending(false), backbuffer(NULL), curr_effect(NULL), default_effect(NULL), prescale_effect(NULL), post_effect(NULL), distortion_effect(NULL),
|
||||
focus_effect(NULL), phosphor_effect(NULL), deconverge_effect(NULL), color_effect(NULL), yiq_encode_effect(NULL), yiq_decode_effect(NULL), bloom_effect(NULL),
|
||||
focus_effect(NULL), phosphor_effect(NULL), deconverge_effect(NULL), color_effect(NULL), ntsc_effect(NULL), bloom_effect(NULL),
|
||||
downsample_effect(NULL), vector_effect(NULL), fsfx_vertices(NULL), curr_texture(NULL), curr_render_target(NULL), curr_poly(NULL)
|
||||
{
|
||||
master_enable = false;
|
||||
@ -632,7 +632,7 @@ void shaders::set_texture(texture_info *texture)
|
||||
default_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
|
||||
if (options->yiq_enable)
|
||||
{
|
||||
yiq_encode_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
|
||||
ntsc_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -706,7 +706,8 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende
|
||||
options->scanline_height = winoptions.screen_scanline_height();
|
||||
options->scanline_bright_scale = winoptions.screen_scanline_bright_scale();
|
||||
options->scanline_bright_offset = winoptions.screen_scanline_bright_offset();
|
||||
options->scanline_offset = winoptions.screen_scanline_offset();
|
||||
options->scanline_jitter = winoptions.screen_scanline_jitter();
|
||||
options->hum_bar_alpha = winoptions.screen_hum_bar_alpha();
|
||||
get_vector(winoptions.screen_defocus(), 2, options->defocus, TRUE);
|
||||
get_vector(winoptions.screen_converge_x(), 3, options->converge_x, TRUE);
|
||||
get_vector(winoptions.screen_converge_y(), 3, options->converge_y, TRUE);
|
||||
@ -722,6 +723,7 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende
|
||||
get_vector(winoptions.screen_phosphor(), 3, options->phosphor, TRUE);
|
||||
options->saturation = winoptions.screen_saturation();
|
||||
options->yiq_enable = winoptions.screen_yiq_enable();
|
||||
options->yiq_jitter = winoptions.screen_yiq_jitter();
|
||||
options->yiq_cc = winoptions.screen_yiq_cc();
|
||||
options->yiq_a = winoptions.screen_yiq_a();
|
||||
options->yiq_b = winoptions.screen_yiq_b();
|
||||
@ -917,8 +919,7 @@ int shaders::create_resources(bool reset)
|
||||
focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
|
||||
deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
|
||||
color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
|
||||
yiq_encode_effect = new effect(this, d3d->get_device(), "yiq_encode.fx", fx_dir);
|
||||
yiq_decode_effect = new effect(this, d3d->get_device(), "yiq_decode.fx", fx_dir);
|
||||
ntsc_effect = new effect(this, d3d->get_device(), "ntsc.fx", fx_dir);
|
||||
bloom_effect = new effect(this, d3d->get_device(), "bloom.fx", fx_dir);
|
||||
downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir);
|
||||
vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
|
||||
@ -931,8 +932,7 @@ int shaders::create_resources(bool reset)
|
||||
!focus_effect->is_valid() ||
|
||||
!deconverge_effect->is_valid() ||
|
||||
!color_effect->is_valid() ||
|
||||
!yiq_encode_effect->is_valid() ||
|
||||
!yiq_decode_effect->is_valid() ||
|
||||
!ntsc_effect->is_valid() ||
|
||||
!bloom_effect->is_valid() ||
|
||||
!downsample_effect->is_valid() ||
|
||||
!vector_effect->is_valid())
|
||||
@ -940,7 +940,7 @@ int shaders::create_resources(bool reset)
|
||||
return 1;
|
||||
}
|
||||
|
||||
effect *effects[14] = {
|
||||
effect *effects[13] = {
|
||||
default_effect,
|
||||
post_effect,
|
||||
distortion_effect,
|
||||
@ -949,15 +949,14 @@ int shaders::create_resources(bool reset)
|
||||
focus_effect,
|
||||
deconverge_effect,
|
||||
color_effect,
|
||||
yiq_encode_effect,
|
||||
yiq_decode_effect,
|
||||
ntsc_effect,
|
||||
color_effect,
|
||||
bloom_effect,
|
||||
downsample_effect,
|
||||
vector_effect
|
||||
};
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
effects[i]->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
|
||||
effects[i]->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
|
||||
@ -967,27 +966,16 @@ int shaders::create_resources(bool reset)
|
||||
effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
|
||||
}
|
||||
|
||||
yiq_encode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
|
||||
yiq_encode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
|
||||
yiq_encode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
|
||||
yiq_decode_effect->add_uniform("OValue", uniform::UT_FLOAT, uniform::CU_NTSC_O);
|
||||
yiq_encode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
|
||||
yiq_encode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
|
||||
yiq_encode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
|
||||
yiq_encode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
|
||||
yiq_encode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
|
||||
yiq_encode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
|
||||
|
||||
yiq_decode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
|
||||
yiq_decode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
|
||||
yiq_decode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
|
||||
yiq_decode_effect->add_uniform("OValue", uniform::UT_FLOAT, uniform::CU_NTSC_O);
|
||||
yiq_decode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
|
||||
yiq_decode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
|
||||
yiq_decode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
|
||||
yiq_decode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
|
||||
yiq_decode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
|
||||
yiq_decode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
|
||||
ntsc_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
|
||||
ntsc_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
|
||||
ntsc_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
|
||||
ntsc_effect->add_uniform("OValue", uniform::UT_FLOAT, uniform::CU_NTSC_O);
|
||||
ntsc_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
|
||||
ntsc_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
|
||||
ntsc_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
|
||||
ntsc_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
|
||||
ntsc_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
|
||||
ntsc_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
|
||||
|
||||
color_effect->add_uniform("RedRatios", uniform::UT_VEC3, uniform::CU_COLOR_RED_RATIOS);
|
||||
color_effect->add_uniform("GrnRatios", uniform::UT_VEC3, uniform::CU_COLOR_GRN_RATIOS);
|
||||
@ -1062,8 +1050,7 @@ void shaders::begin_draw()
|
||||
focus_effect->set_technique("DefaultTechnique");
|
||||
deconverge_effect->set_technique("DefaultTechnique");
|
||||
color_effect->set_technique("DefaultTechnique");
|
||||
yiq_encode_effect->set_technique("DefaultTechnique");
|
||||
yiq_decode_effect->set_technique("DefaultTechnique");
|
||||
ntsc_effect->set_technique("DefaultTechnique");
|
||||
color_effect->set_technique("DefaultTechnique");
|
||||
bloom_effect->set_technique("DefaultTechnique");
|
||||
downsample_effect->set_technique("DefaultTechnique");
|
||||
@ -1244,27 +1231,16 @@ int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int
|
||||
{
|
||||
return next_index;
|
||||
}
|
||||
|
||||
float frame_offset = curr_texture->get_cur_frame() == 0
|
||||
? 0.0f
|
||||
: (float)curr_texture->get_cur_frame();
|
||||
|
||||
// Convert our signal into YIQ
|
||||
curr_effect = yiq_encode_effect;
|
||||
curr_effect->update_uniforms();
|
||||
curr_effect->set_float("FrameOffset", frame_offset);
|
||||
|
||||
float signal_offset = curr_texture->get_cur_frame() == 0
|
||||
? 0.0f
|
||||
: options->yiq_jitter;
|
||||
|
||||
// initial "Diffuse" texture is set in shaders::set_texture()
|
||||
|
||||
next_index = rt->next_index(next_index);
|
||||
blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
|
||||
|
||||
// Convert our signal from YIQ
|
||||
curr_effect = yiq_decode_effect;
|
||||
curr_effect = ntsc_effect;
|
||||
curr_effect->update_uniforms();
|
||||
curr_effect->set_texture("Composite", rt->native_texture[next_index]);
|
||||
curr_effect->set_texture("Diffuse", curr_texture->get_finaltex());
|
||||
curr_effect->set_float("FrameOffset", frame_offset);
|
||||
curr_effect->set_float("SignalOffset", signal_offset);
|
||||
|
||||
next_index = rt->next_index(next_index);
|
||||
blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
|
||||
@ -1457,7 +1433,9 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
|
||||
curr_effect->set_vector("BackColor", 3, back_color);
|
||||
curr_effect->set_vector("ScreenScale", 2, screen_scale);
|
||||
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
|
||||
curr_effect->set_float("ScanlineOffset", curr_texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset);
|
||||
curr_effect->set_float("ScanlineOffset", curr_texture->get_cur_frame() == 0 ? 0.0f : options->scanline_jitter);
|
||||
curr_effect->set_float("TimeMilliseconds", (float)machine->time().as_double() * 1000.0f);
|
||||
curr_effect->set_float("HumBarAlpha", options->hum_bar_alpha);
|
||||
curr_effect->set_bool("PrepareBloom", prepare_bloom);
|
||||
curr_effect->set_bool("PrepareVector", prepare_vector);
|
||||
|
||||
@ -2159,15 +2137,10 @@ void shaders::delete_resources(bool reset)
|
||||
delete color_effect;
|
||||
color_effect = NULL;
|
||||
}
|
||||
if (yiq_encode_effect != NULL)
|
||||
if (ntsc_effect != NULL)
|
||||
{
|
||||
delete yiq_encode_effect;
|
||||
yiq_encode_effect = NULL;
|
||||
}
|
||||
if (yiq_decode_effect != NULL)
|
||||
{
|
||||
delete yiq_decode_effect;
|
||||
yiq_decode_effect = NULL;
|
||||
delete ntsc_effect;
|
||||
ntsc_effect = NULL;
|
||||
}
|
||||
|
||||
if (backbuffer != NULL)
|
||||
@ -2423,10 +2396,16 @@ static INT32 slider_scanline_bright_offset(running_machine &machine, void *arg,
|
||||
return slider_set(&(((hlsl_options*)arg)->scanline_bright_offset), 0.05f, "%2.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_scanline_offset(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
static INT32 slider_scanline_jitter(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->scanline_offset), 0.05f, "%2.2f", str, newval);
|
||||
return slider_set(&(((hlsl_options*)arg)->scanline_jitter), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_hum_bar_alpha(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->hum_bar_alpha), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_defocus_x(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
@ -2781,6 +2760,105 @@ static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, std::
|
||||
return slider_set(&(((hlsl_options*)arg)->bloom_level10_weight), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
|
||||
static INT32 slider_ntsc_enable(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
hlsl_options *options = (hlsl_options*)arg;
|
||||
if (newval != SLIDER_NOCHANGE)
|
||||
{
|
||||
options->yiq_enable = newval;
|
||||
}
|
||||
if (str != NULL)
|
||||
{
|
||||
strprintf(*str, "%s", options->yiq_enable == 0 ? "Off" : "On");
|
||||
}
|
||||
options->params_dirty = true;
|
||||
|
||||
return options->yiq_enable;
|
||||
}
|
||||
|
||||
// static INT32 slider_ntsc_phase_count(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
// {
|
||||
// hlsl_options *options = (hlsl_options*)arg;
|
||||
// if (newval != SLIDER_NOCHANGE)
|
||||
// {
|
||||
// options->yiq_phase_count = newval;
|
||||
// }
|
||||
// if (str != NULL)
|
||||
// {
|
||||
// strprintf(*str, "%d", options->yiq_phase_count);
|
||||
// }
|
||||
// options->params_dirty = true;
|
||||
|
||||
// return options->yiq_phase_count;
|
||||
// }
|
||||
|
||||
static INT32 slider_ntsc_jitter(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_jitter), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_a_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_a), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_b_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_b), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_p_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_p), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_o_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_o), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_cc_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_cc), 0.0001f, "%1.4f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_n_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_n), 0.01f, "%1.4f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_y_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_y), 0.01f, "%1.4f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_i_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_i), 0.01f, "%1.4f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_q_value(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_q), 0.01f, "%1.4f", str, newval);
|
||||
}
|
||||
|
||||
static INT32 slider_ntsc_scan_time(running_machine &machine, void *arg, std::string *str, INT32 newval)
|
||||
{
|
||||
((hlsl_options*)arg)->params_dirty = true;
|
||||
return slider_set(&(((hlsl_options*)arg)->yiq_scan_time), 0.01f, "%1.2f", str, newval);
|
||||
}
|
||||
|
||||
hlsl_options shaders::last_options = { false };
|
||||
|
||||
shaders::slider_desc shaders::s_sliders[] =
|
||||
@ -2805,7 +2883,8 @@ shaders::slider_desc shaders::s_sliders[] =
|
||||
{ "Scanline Indiv. Height", 1, 20, 80, 1, 5, slider_scanline_height },
|
||||
{ "Scanline Brightness", 0, 20, 40, 1, 5, slider_scanline_bright_scale },
|
||||
{ "Scanline Brightness Overdrive", 0, 0, 20, 1, 5, slider_scanline_bright_offset },
|
||||
{ "Scanline Jitter", 0, 0, 40, 1, 5, slider_scanline_offset },
|
||||
{ "Scanline Jitter", 0, 0, 100, 1, 5, slider_scanline_jitter },
|
||||
{ "Hum Bar Darkness", 0, 0, 100, 1, 5, slider_hum_bar_alpha },
|
||||
{ "Defocus X", 0, 0, 100, 1, 7, slider_defocus_x },
|
||||
{ "Defocus Y", 0, 0, 100, 1, 7, slider_defocus_y },
|
||||
{ "Red Position Offset X", -100, 0, 100, 1, 7, slider_red_converge_x },
|
||||
@ -2861,6 +2940,19 @@ shaders::slider_desc shaders::s_sliders[] =
|
||||
{ "Bloom Level 8 Scale", 0, 0, 100, 1, 7, slider_bloom_lvl8_scale },
|
||||
{ "Bloom Level 9 Scale", 0, 0, 100, 1, 7, slider_bloom_lvl9_scale },
|
||||
{ "Bloom Level 10 Scale", 0, 0, 100, 1, 7, slider_bloom_lvl10_scale },
|
||||
{ "NTSC processing", 0, 0, 1, 1, 5, slider_ntsc_enable },
|
||||
{ "Signal Jitter", 0, 0, 100, 1, 5, slider_ntsc_jitter },
|
||||
{ "A Value", -100, 50, 100, 1, 5, slider_ntsc_a_value },
|
||||
{ "B Value", -100, 50, 100, 1, 5, slider_ntsc_b_value },
|
||||
{ "Incoming Pixel Clock Scaling", -300, 100, 300, 1, 5, slider_ntsc_p_value },
|
||||
{ "Outgoing Color Carrier Phase", -300, 0, 300, 1, 5, slider_ntsc_o_value },
|
||||
{ "Color Carrier Frequency", 0, 35795, 60000, 5, 5, slider_ntsc_cc_value },
|
||||
{ "Y Notch", 0, 100, 600, 5, 5, slider_ntsc_n_value },
|
||||
{ "Y Frequency", 0, 600, 600, 5, 5, slider_ntsc_y_value },
|
||||
{ "I Frequency", 0, 120, 600, 5, 5, slider_ntsc_i_value },
|
||||
{ "Q Frequency", 0, 60, 600, 5, 5, slider_ntsc_q_value },
|
||||
{ "Scanline Duration", 0, 5260, 10000, 1, 5, slider_ntsc_scan_time },
|
||||
// { "Phase Count", 1, 2, 3, 1, 5, slider_ntsc_phase_count },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL },
|
||||
};
|
||||
|
||||
|
@ -210,7 +210,8 @@ struct hlsl_options
|
||||
float scanline_height;
|
||||
float scanline_bright_scale;
|
||||
float scanline_bright_offset;
|
||||
float scanline_offset;
|
||||
float scanline_jitter;
|
||||
float hum_bar_alpha;
|
||||
float defocus[2];
|
||||
float converge_x[3];
|
||||
float converge_y[3];
|
||||
@ -228,6 +229,7 @@ struct hlsl_options
|
||||
|
||||
// NTSC
|
||||
bool yiq_enable;
|
||||
float yiq_jitter;
|
||||
float yiq_cc;
|
||||
float yiq_a;
|
||||
float yiq_b;
|
||||
@ -427,8 +429,7 @@ private:
|
||||
effect * phosphor_effect; // pointer to the phosphor-effect object
|
||||
effect * deconverge_effect; // pointer to the deconvergence-effect object
|
||||
effect * color_effect; // pointer to the color-effect object
|
||||
effect * yiq_encode_effect; // pointer to the YIQ encoder effect object
|
||||
effect * yiq_decode_effect; // pointer to the YIQ decoder effect object
|
||||
effect * ntsc_effect; // pointer to the NTSC effect object
|
||||
effect * bloom_effect; // pointer to the bloom composite effect
|
||||
effect * downsample_effect; // pointer to the bloom downsample effect
|
||||
effect * vector_effect; // pointer to the vector-effect object
|
||||
|
@ -303,12 +303,13 @@ const options_entry windows_options::s_option_entries[] =
|
||||
{ WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.0", OPTION_FLOAT, "screen reflection amount" },
|
||||
{ WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.0", OPTION_FLOAT, "image vignetting amount" },
|
||||
/* Beam-related values below this line*/
|
||||
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "1.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
|
||||
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
|
||||
{ WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" },
|
||||
{ WINOPTION_SCANLINE_HEIGHT";fs_scanh(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height scaling value for scanlines" },
|
||||
{ WINOPTION_SCANLINE_BRIGHT_SCALE";fs_scanbs(0.0-2.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" },
|
||||
{ WINOPTION_SCANLINE_BRIGHT_OFFSET";fs_scanbo(0.0-1.0)", "0.0", OPTION_FLOAT, "overall brightness offset value for scanlines (additive)" },
|
||||
{ WINOPTION_SCANLINE_OFFSET";fs_scanjt(0.0-4.0)", "0.0", OPTION_FLOAT, "overall interlace jitter scaling value for scanlines" },
|
||||
{ WINOPTION_SCANLINE_JITTER";fs_scanjt(0.0-4.0)", "0.0", OPTION_FLOAT, "overall interlace jitter scaling value for scanlines" },
|
||||
{ WINOPTION_HUM_BAR_ALPHA";fs_humba(0.0-1.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for hum bar" },
|
||||
{ WINOPTION_DEFOCUS";fs_focus", "1.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" },
|
||||
{ WINOPTION_CONVERGE_X";fs_convx", "0.25,0.00,-0.25", OPTION_STRING, "convergence in screen-relative X direction" },
|
||||
{ WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.25,-0.25", OPTION_STRING, "convergence in screen-relative Y direction" },
|
||||
@ -327,10 +328,11 @@ const options_entry windows_options::s_option_entries[] =
|
||||
/* NTSC simulation below this line */
|
||||
{ NULL, NULL, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" },
|
||||
{ WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enables YIQ-space HLSL post-processing" },
|
||||
{ WINOPTION_YIQ_CCVALUE";yiqcc", "3.59754545", OPTION_FLOAT, "Color Carrier frequency for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_JITTER";yiqj", "0.0", OPTION_FLOAT, "Jitter for the NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_CCVALUE";yiqcc", "3.57954545", OPTION_FLOAT, "Color Carrier frequency for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_AVALUE";yiqa", "0.5", OPTION_FLOAT, "A value for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_BVALUE";yiqb", "0.5", OPTION_FLOAT, "B value for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_OVALUE";yiqo", "1.0", OPTION_FLOAT, "Outgoing Color Carrier phase offset for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_OVALUE";yiqo", "0.0", OPTION_FLOAT, "Outgoing Color Carrier phase offset for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_PVALUE";yiqp", "1.0", OPTION_FLOAT, "Incoming Pixel Clock scaling value for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_NVALUE";yiqn", "1.0", OPTION_FLOAT, "Y filter notch width for NTSC signal processing" },
|
||||
{ WINOPTION_YIQ_YVALUE";yiqy", "6.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
|
||||
|
@ -55,7 +55,8 @@
|
||||
#define WINOPTION_SCANLINE_HEIGHT "scanline_height"
|
||||
#define WINOPTION_SCANLINE_BRIGHT_SCALE "scanline_bright_scale"
|
||||
#define WINOPTION_SCANLINE_BRIGHT_OFFSET "scanline_bright_offset"
|
||||
#define WINOPTION_SCANLINE_OFFSET "scanline_jitter"
|
||||
#define WINOPTION_SCANLINE_JITTER "scanline_jitter"
|
||||
#define WINOPTION_HUM_BAR_ALPHA "hum_bar_alpha"
|
||||
#define WINOPTION_DEFOCUS "defocus"
|
||||
#define WINOPTION_CONVERGE_X "converge_x"
|
||||
#define WINOPTION_CONVERGE_Y "converge_y"
|
||||
@ -71,6 +72,7 @@
|
||||
#define WINOPTION_PHOSPHOR "phosphor_life"
|
||||
#define WINOPTION_SATURATION "saturation"
|
||||
#define WINOPTION_YIQ_ENABLE "yiq_enable"
|
||||
#define WINOPTION_YIQ_JITTER "yiq_jitter"
|
||||
#define WINOPTION_YIQ_CCVALUE "yiq_cc"
|
||||
#define WINOPTION_YIQ_AVALUE "yiq_a"
|
||||
#define WINOPTION_YIQ_BVALUE "yiq_b"
|
||||
@ -154,7 +156,8 @@ public:
|
||||
float screen_scanline_height() const { return float_value(WINOPTION_SCANLINE_HEIGHT); }
|
||||
float screen_scanline_bright_scale() const { return float_value(WINOPTION_SCANLINE_BRIGHT_SCALE); }
|
||||
float screen_scanline_bright_offset() const { return float_value(WINOPTION_SCANLINE_BRIGHT_OFFSET); }
|
||||
float screen_scanline_offset() const { return float_value(WINOPTION_SCANLINE_OFFSET); }
|
||||
float screen_scanline_jitter() const { return float_value(WINOPTION_SCANLINE_JITTER); }
|
||||
float screen_hum_bar_alpha() const { return float_value(WINOPTION_HUM_BAR_ALPHA); }
|
||||
float screen_reflection() const { return float_value(WINOPTION_REFLECTION); }
|
||||
float screen_curvature() const { return float_value(WINOPTION_CURVATURE); }
|
||||
float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); }
|
||||
@ -169,6 +172,7 @@ public:
|
||||
const char *screen_grn_ratio() const { return value(WINOPTION_GRN_RATIO); }
|
||||
const char *screen_blu_ratio() const { return value(WINOPTION_BLU_RATIO); }
|
||||
bool screen_yiq_enable() const { return bool_value(WINOPTION_YIQ_ENABLE); }
|
||||
float screen_yiq_jitter() const { return float_value(WINOPTION_YIQ_JITTER); }
|
||||
float screen_yiq_cc() const { return float_value(WINOPTION_YIQ_CCVALUE); }
|
||||
float screen_yiq_a() const { return float_value(WINOPTION_YIQ_AVALUE); }
|
||||
float screen_yiq_b() const { return float_value(WINOPTION_YIQ_BVALUE); }
|
||||
|
Loading…
Reference in New Issue
Block a user