summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2011-05-30 21:10:23 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2011-05-30 21:10:23 +0000
commit796e691522ba5c47fc0610da4f557514563f85b9 (patch)
tree961683497fd1e4d7369da812c579572f880b188a
parente532e74a8a869af6da71222657f39684210b624e (diff)
HLSL Updates: [Ryan Holtz, Bat Country Entertainment, austere, SoltanGris42]
- Added the ability to render screenshots at arbitrary resolutions. - Added the ability to record AVI videos (albeit with no audio) at arbitrary resolutions. - Added a 43-tap-wide FIR-based NTSC filter with tunable Y, I and Q frequency response. - Updated scanlines to have a user-tunable pixel-height ratio in addition to the current screen-height ratio. - Fixed a VRAM leak that was causing many dynamic-resolution drivers to run out of memory mid-run.
-rw-r--r--.gitattributes1
-rw-r--r--hlsl/deconverge.fx11
-rw-r--r--hlsl/post.fx7
-rw-r--r--hlsl/prescale.fx90
-rw-r--r--hlsl/yiq_decode.fx163
-rw-r--r--hlsl/yiq_encode.fx49
-rw-r--r--src/osd/windows/d3d8intf.c8
-rw-r--r--src/osd/windows/d3d9intf.c8
-rw-r--r--src/osd/windows/d3dintf.h1
-rw-r--r--src/osd/windows/drawd3d.c1335
-rw-r--r--src/osd/windows/drawdd.c2
-rw-r--r--src/osd/windows/drawgdi.c2
-rw-r--r--src/osd/windows/drawnone.c2
-rw-r--r--src/osd/windows/input.c14
-rw-r--r--src/osd/windows/video.c8
-rw-r--r--src/osd/windows/window.c46
-rw-r--r--src/osd/windows/window.h4
-rw-r--r--src/osd/windows/winmain.c29
-rw-r--r--src/osd/windows/winmain.h38
19 files changed, 1487 insertions, 331 deletions
diff --git a/.gitattributes b/.gitattributes
index c5ff7b7be26..8bce026a717 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -16,6 +16,7 @@ hlsl/focus.fx svneol=native#text/plain
hlsl/phosphor.fx svneol=native#text/plain
hlsl/pincushion.fx svneol=native#text/plain
hlsl/post.fx svneol=native#text/plain
+hlsl/prescale.fx svneol=native#text/plain
hlsl/primary.fx svneol=native#text/plain
hlsl/yiq_decode.fx svneol=native#text/plain
hlsl/yiq_encode.fx svneol=native#text/plain
diff --git a/hlsl/deconverge.fx b/hlsl/deconverge.fx
index a65f06bbe92..2618fdffad9 100644
--- a/hlsl/deconverge.fx
+++ b/hlsl/deconverge.fx
@@ -98,6 +98,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.BluCoord.y = ((((TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + BluRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + BluConvergeY * invDims.y;
Output.TexCoord = TexCoord;
+
return Output;
}
@@ -124,9 +125,13 @@ float4 ps_main(PS_INPUT Input) : COLOR
GrnCoord.y = GrnCoord.y - frac(GrnCoord.y);
BluCoord.y = BluCoord.y - frac(BluCoord.y);
- float RedTexel = tex2D(DiffuseSampler, lerp(TexCoord, RedCoord, Deconverge) / RawDims + 0.5f / RawDims).r;
- float GrnTexel = tex2D(DiffuseSampler, lerp(TexCoord, GrnCoord, Deconverge) / RawDims + 0.5f / RawDims).g;
- float BluTexel = tex2D(DiffuseSampler, lerp(TexCoord, BluCoord, Deconverge) / RawDims + 0.5f / RawDims).b;
+ RedCoord = lerp(TexCoord, RedCoord, Deconverge) / RawDims;
+ GrnCoord = lerp(TexCoord, GrnCoord, Deconverge) / RawDims;
+ BluCoord = lerp(TexCoord, BluCoord, Deconverge) / RawDims;
+
+ float RedTexel = tex2D(DiffuseSampler, RedCoord + float2(0.0f, 0.5f) / RawDims).r;
+ float GrnTexel = tex2D(DiffuseSampler, GrnCoord + float2(0.0f, 0.5f) / RawDims).g;
+ float BluTexel = tex2D(DiffuseSampler, BluCoord + float2(0.0f, 0.5f) / RawDims).b;
//RedTexel *= Input.RedCoord.x < (WidthRatio / RawWidth) ? 0.0f : 1.0f;
//RedTexel *= Input.RedCoord.y < (HeightRatio / RawHeight) ? 0.0f : 1.0f;
diff --git a/hlsl/post.fx b/hlsl/post.fx
index ff1cbfa1f47..69ececd4249 100644
--- a/hlsl/post.fx
+++ b/hlsl/post.fx
@@ -99,6 +99,7 @@ uniform float ScanlineScale = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
+uniform float ScanlineHeight = 0.5f;
uniform float UseShadow = 0.0f;
uniform float ShadowBrightness = 1.0f;
@@ -155,8 +156,8 @@ float4 ps_main(PS_INPUT Input) : COLOR
// -- Scanline Simulation --
float InnerSine = BaseCoord.y * RawHeight * ScanlineScale;
- float3 ScanBrightness = lerp(1.0f, abs(sin(InnerSine * PI + ScanlineOffset * RawHeight)) * ScanlineBrightScale + 1.0f, ScanlineAmount);
- //float3 Scanned = BaseTexel.rgb * ScanBrightness;
+ float ScanBrightMod = sin(InnerSine * PI + ScanlineOffset * RawHeight);
+ float3 ScanBrightness = lerp(1.0f, pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f, ScanlineAmount);
float3 Scanned = BaseTexel.rgb * ScanBrightness;
float2 ShadowDims = float2(ShadowWidth, ShadowHeight);
@@ -164,7 +165,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float2 ShadowMaskSize = float2(ShadowMaskSizeX, ShadowMaskSizeY);
float2 ShadowFrac = frac(BaseCoord * ShadowMaskSize * 0.5f);
float2 ShadowCoord = ShadowFrac * ShadowUV + float2(1.5f / ShadowWidth, 1.5f / ShadowHeight);
- float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord), UseShadow);
+ float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord).rgb, UseShadow);
// -- Final Pixel --
float4 Output = float4(Scanned * lerp(1.0f, ShadowTexel, ShadowBrightness), BaseTexel.a) * Input.Color;
diff --git a/hlsl/prescale.fx b/hlsl/prescale.fx
new file mode 100644
index 00000000000..4ba0495320e
--- /dev/null
+++ b/hlsl/prescale.fx
@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+// Passthrough Effect
+//-----------------------------------------------------------------------------
+
+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;
+ float2 TexCoord : TEXCOORD0;
+};
+
+struct VS_INPUT
+{
+ float4 Position : POSITION;
+ float4 Color : COLOR0;
+ float2 TexCoord : TEXCOORD0;
+};
+
+struct PS_INPUT
+{
+ float2 TexCoord : TEXCOORD0;
+};
+
+//-----------------------------------------------------------------------------
+// Passthrough Vertex Shader
+//-----------------------------------------------------------------------------
+
+float TargetWidth;
+float TargetHeight;
+
+float RawWidth;
+float RawHeight;
+
+VS_OUTPUT vs_main(VS_INPUT Input)
+{
+ VS_OUTPUT Output = (VS_OUTPUT)0;
+
+ Output.Position = float4(Input.Position.xyz, 1.0f);
+ Output.Position.x /= TargetWidth;
+ Output.Position.y /= TargetHeight;
+ Output.Position.y = 1.0f - Output.Position.y;
+ Output.Position.x -= 0.5f;
+ Output.Position.y -= 0.5f;
+ Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
+
+ Output.TexCoord = Input.TexCoord + 0.5f / float2(RawWidth, RawHeight);
+
+ return Output;
+}
+
+//-----------------------------------------------------------------------------
+// Passthrough Pixel Shader
+//-----------------------------------------------------------------------------
+
+float4 ps_main(PS_INPUT Input) : COLOR
+{
+ float4 Center = tex2D(DiffuseSampler, Input.TexCoord);
+ return Center;
+}
+
+//-----------------------------------------------------------------------------
+// Passthrough Effect
+//-----------------------------------------------------------------------------
+
+technique DeconvergeTechnique
+{
+ pass Pass0
+ {
+ Lighting = FALSE;
+
+ VertexShader = compile vs_3_0 vs_main();
+ PixelShader = compile ps_3_0 ps_main();
+ }
+}
diff --git a/hlsl/yiq_decode.fx b/hlsl/yiq_decode.fx
index 550a0a83062..a85590d998f 100644
--- a/hlsl/yiq_decode.fx
+++ b/hlsl/yiq_decode.fx
@@ -20,9 +20,9 @@ texture Diffuse;
sampler DiffuseSampler = sampler_state
{
Texture = <Diffuse>;
- MipFilter = POINT;
- MinFilter = POINT;
- MagFilter = POINT;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
@@ -35,15 +35,7 @@ sampler DiffuseSampler = sampler_state
struct VS_OUTPUT
{
float4 Position : POSITION;
- float4 Color : COLOR0;
float4 Coord0 : TEXCOORD0;
- float4 Coord1 : TEXCOORD1;
- float4 Coord2 : TEXCOORD2;
- float4 Coord3 : TEXCOORD3;
- float4 Coord4 : TEXCOORD4;
- float4 Coord5 : TEXCOORD5;
- float4 Coord6 : TEXCOORD6;
- float4 Coord7 : TEXCOORD7;
};
struct VS_INPUT
@@ -55,15 +47,7 @@ struct VS_INPUT
struct PS_INPUT
{
- float4 Color : COLOR0;
float4 Coord0 : TEXCOORD0;
- float4 Coord1 : TEXCOORD1;
- float4 Coord2 : TEXCOORD2;
- float4 Coord3 : TEXCOORD3;
- float4 Coord4 : TEXCOORD4;
- float4 Coord5 : TEXCOORD5;
- float4 Coord6 : TEXCOORD6;
- float4 Coord7 : TEXCOORD7;
};
//-----------------------------------------------------------------------------
@@ -79,8 +63,6 @@ uniform float RawHeight;
uniform float WidthRatio;
uniform float HeightRatio;
-uniform float FscValue;
-
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
@@ -88,25 +70,12 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.x /= TargetWidth;
Output.Position.y /= TargetHeight;
- //Output.Position.x /= WidthRatio;
- //Output.Position.y /= HeightRatio;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.x -= 0.5f;
Output.Position.y -= 0.5f;
Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
- Output.Color = Input.Color;
- Output.Coord0.xy = Input.TexCoord + float2(0.00f / RawWidth, 0.0f);
- Output.Coord1.xy = Input.TexCoord + float2(0.25f / RawWidth, 0.0f);
- Output.Coord2.xy = Input.TexCoord + float2(0.50f / RawWidth, 0.0f);
- Output.Coord3.xy = Input.TexCoord + float2(0.75f / RawWidth, 0.0f);
- Output.Coord4.xy = Input.TexCoord + float2(1.00f / RawWidth, 0.0f);
- Output.Coord5.xy = Input.TexCoord + float2(1.25f / RawWidth, 0.0f);
- Output.Coord6.xy = Input.TexCoord + float2(1.50f / RawWidth, 0.0f);
- Output.Coord7.xy = Input.TexCoord + float2(1.75f / RawWidth, 0.0f);
- Output.Coord0.zw = Input.TexCoord + float2(2.00f / RawWidth, 0.0f);
- Output.Coord1.zw = Input.TexCoord + float2(2.25f / RawWidth, 0.0f);
- Output.Coord2.zw = Input.TexCoord + float2(2.50f / RawWidth, 0.0f);
- Output.Coord3.zw = Input.TexCoord + float2(2.75f / RawWidth, 0.0f);
+ Output.Coord0.xy = Input.TexCoord + 0.5f / float2(RawWidth, RawHeight);
+ Output.Coord0.zw = float2(1.0f / RawWidth, 0.0f);
return Output;
}
@@ -115,95 +84,67 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// YIQ Decode Pixel Shader
//-----------------------------------------------------------------------------
-uniform float YSubsampleLength = 3.0f;
-uniform float ISubsampleLength = 3.0f;
-uniform float QSubsampleLength = 3.0f;
+uniform float AValue = 0.0f;
+uniform float BValue = 0.0f;
+uniform float CCValue = 3.04183f;
+uniform float PValue = 1.0f;
+uniform float OValue = 0.0f;
+uniform float ScanTime = 52.6f;
-uniform float WValue;
-uniform float AValue;
-uniform float BValue;
+uniform float YFreqResponse = 3.0f;
+uniform float IFreqResponse = 1.2f;
+uniform float QFreqResponse = 0.6f;
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 RawDims = float2(RawWidth, RawHeight);
- float4 BaseTexel = tex2D(DiffuseSampler, Input.Coord0.xy + float2(0.5f, 0.5f) / RawDims);
- float4 OrigC = tex2D(CompositeSampler, Input.Coord0.xy + float2(0.5f, 0.5f) / RawDims);
- float4 OrigC2 = tex2D(CompositeSampler, Input.Coord4.xy + float2(0.5f, 0.5f) / RawDims);
- float4 OrigC3 = tex2D(CompositeSampler, Input.Coord0.zw + float2(0.5f, 0.5f) / RawDims);
- float4 C = OrigC;
- float4 C2 = OrigC2;
- float4 C3 = OrigC3;
+ float4 BaseTexel = tex2D(DiffuseSampler, Input.Coord0.xy + 0.5f / RawDims);
+
+ // YIQ convolution: N coefficients each
+ float4 YAccum = 0.0f;
+ float4 IAccum = 0.0f;
+ float4 QAccum = 0.0f;
float MaxC = 2.1183f;
float MinC = -1.1183f;
float CRange = MaxC - MinC;
-
- C = C * CRange + MinC;
- C2 = C2 * CRange + MinC;
-
- float2 Coord0 = Input.Coord0.xy * RawDims;
- float2 Coord1 = Input.Coord1.xy * RawDims;
- float2 Coord2 = Input.Coord2.xy * RawDims;
- float2 Coord3 = Input.Coord3.xy * RawDims;
- float2 Coord4 = Input.Coord4.xy * RawDims;
- float2 Coord5 = Input.Coord5.xy * RawDims;
- float2 Coord6 = Input.Coord6.xy * RawDims;
- float2 Coord7 = Input.Coord7.xy * RawDims;
- float2 Coord8 = Input.Coord0.zw * RawDims;
- float2 Coord9 = Input.Coord1.zw * RawDims;
- float2 CoordA = Input.Coord2.zw * RawDims;
- float2 CoordB = Input.Coord3.zw * RawDims;
-
- float W = WValue * 2.0f;
- float T0 = Coord0.x + AValue * Coord0.y + BValue;
- float T1 = Coord1.x + AValue * Coord1.y + BValue;
- float T2 = Coord2.x + AValue * Coord2.y + BValue;
- float T3 = Coord3.x + AValue * Coord3.y + BValue;
- float T4 = Coord4.x + AValue * Coord4.y + BValue;
- float T5 = Coord5.x + AValue * Coord5.y + BValue;
- float T6 = Coord6.x + AValue * Coord6.y + BValue;
- float T7 = Coord7.x + AValue * Coord7.y + BValue;
- float T8 = Coord8.x + AValue * Coord8.y + BValue;
- float T9 = Coord9.x + AValue * Coord9.y + BValue;
- float TA = CoordA.x + AValue * CoordA.y + BValue;
- float TB = CoordB.x + AValue * CoordB.y + BValue;
- float4 Tc = float4(T0, T1, T2, T3);
- float4 Tc2 = float4(T4, T5, T6, T7);
- float4 Tc3 = float4(T8, T9, TA, TB);
-
- float Yvals[8];
- Yvals[0] = C.r; Yvals[1] = C.g; Yvals[2] = C.b; Yvals[3] = C.a; Yvals[4] = C2.r; Yvals[5] = C2.g; Yvals[6] = C2.b; Yvals[7] = C2.a;
- float Ytotal = 0.0f;
- for(uint idx = 0; idx < FscValue * 4.0f; idx++ )
+ float Fc_y = YFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float Fc_i = IFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float Fc_q = QFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float PI = 3.1415926535897932384626433832795;
+ float PI2 = 2.0f * PI;
+ float PI2Length = PI2 / 42.0f;
+ for(float n = -21.0f; n < 22.0f; n += 4.0f)
{
- Ytotal = Ytotal + Yvals[idx];
+ float4 n4 = float4(n + 0.0f, n + 1.0f, n + 2.0f, n + 3.0f);
+ float4 CoordX = Input.Coord0.x + Input.Coord0.z * n4 * 0.25f;
+ float4 CoordY = Input.Coord0.y;
+ float4 C = tex2D(CompositeSampler, float2(CoordX.r, CoordY.r)) * CRange + MinC;
+ float4 WT = PI2 * CCValue * ScanTime * (CoordX * WidthRatio + AValue * CoordY * 2.0f * (RawHeight / HeightRatio) + BValue) + OValue;
+
+ float4 SincYIn = PI2 * Fc_y * n4;
+ float4 IdealY = 2.0f * Fc_y * ((SincYIn != 0.0f) ? (sin(SincYIn) / SincYIn) : 1.0f);
+ float4 FilterY = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealY;
+
+ float4 SincIIn = PI2 * Fc_i * n4;
+ float4 IdealI = 2.0f * Fc_i * ((SincIIn != 0.0f) ? (sin(SincIIn) / SincIIn) : 1.0f);
+ float4 FilterI = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealI;
+
+ float4 SincQIn = PI2 * Fc_q * n4;
+ float4 IdealQ = 2.0f * Fc_q * ((SincQIn != 0.0f) ? (sin(SincQIn) / SincQIn) : 1.0f);
+ float4 FilterQ = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealQ;
+
+ YAccum = YAccum + C * FilterY;
+ IAccum = IAccum + C * cos(WT) * FilterI;
+ QAccum = QAccum + C * sin(WT) * FilterQ;
}
- float Yavg = Ytotal / (FscValue * 4.0f);
-
- float4 I = (C - Yavg) * sin(W * Tc);
- float4 Q = (C - Yavg) * cos(W * Tc);
- float4 I2 = (C2 - Yavg) * sin(W * Tc2);
- float4 Q2 = (C2 - Yavg) * cos(W * Tc2);
- float4 I3 = (C3 - Yavg) * sin(W * Tc3);
- float4 Q3 = (C3 - Yavg) * cos(W * Tc3);
- float Itotal = 0.0f;
- float Qtotal = 0.0f;
+ 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;
- float Ivals[8];
- float Qvals[8];
- Ivals[0] = I.r; Ivals[1] = I.g; Ivals[2] = I.b; Ivals[3] = I.a; Ivals[4] = I2.r; Ivals[5] = I2.g; Ivals[6] = I2.b; Ivals[7] = I2.a;
- Qvals[0] = Q.r; Qvals[1] = Q.g; Qvals[2] = Q.b; Qvals[3] = Q.a; Qvals[4] = Q2.r; Qvals[5] = Q2.g; Qvals[6] = Q2.b; Qvals[7] = Q2.a;
- for(uint idx = 0; idx < FscValue * 4.0f; idx++ )
- {
- Itotal = Itotal + Ivals[idx];
- Qtotal = Qtotal + Qvals[idx];
- }
- float Iavg = Itotal / (FscValue * 3.0f);
- float Qavg = Qtotal / (FscValue * 3.0f);
+ float3 YIQ = float3(Y, I, Q);
- float3 YIQ = float3(Yavg, Iavg * 1.5f, Qavg);
-
float3 OutRGB = 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(OutRGB, BaseTexel.a);
diff --git a/hlsl/yiq_encode.fx b/hlsl/yiq_encode.fx
index b8ee1e22de5..119a9169bf8 100644
--- a/hlsl/yiq_encode.fx
+++ b/hlsl/yiq_encode.fx
@@ -82,35 +82,32 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// YIQ Encode Pixel Shader
//-----------------------------------------------------------------------------
-uniform float YSubsampleLength = 3.0f;
-uniform float ISubsampleLength = 3.0f;
-uniform float QSubsampleLength = 3.0f;
-
-uniform float WValue;
-uniform float AValue;
-uniform float BValue;
-
-uniform float FscScale;
+uniform float AValue = 0.0f;
+uniform float BValue = 0.0f;
+uniform float CCValue = 3.04183f;
+uniform float PValue = 1.0f;
+uniform float ScanTime = 52.6f;
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 Scaler = float2(RawWidth, RawHeight);
float2 InvRatios = float2(1.0f / WidthRatio, 1.0f / HeightRatio);
- float3 Texel0 = tex2D(DiffuseSampler, Input.Coord0 + float2(FscScale * 0.00f + 0.5f, 0.5f) / Scaler).rgb;
- float3 Texel1 = tex2D(DiffuseSampler, Input.Coord1 + float2(FscScale * 0.25f + 0.5f, 0.5f) / Scaler).rgb;
- float3 Texel2 = tex2D(DiffuseSampler, Input.Coord2 + float2(FscScale * 0.50f + 0.5f, 0.5f) / Scaler).rgb;
- float3 Texel3 = tex2D(DiffuseSampler, Input.Coord3 + float2(FscScale * 0.75f + 0.5f, 0.5f) / Scaler).rgb;
+ float3 Texel0 = tex2D(DiffuseSampler, Input.Coord0 + float2(PValue * 0.00f + 0.5f, 0.5f) / Scaler).rgb;
+ float3 Texel1 = tex2D(DiffuseSampler, Input.Coord1 + float2(PValue * 0.25f + 0.5f, 0.5f) / Scaler).rgb;
+ float3 Texel2 = tex2D(DiffuseSampler, Input.Coord2 + float2(PValue * 0.50f + 0.5f, 0.5f) / Scaler).rgb;
+ float3 Texel3 = tex2D(DiffuseSampler, Input.Coord3 + float2(PValue * 0.75f + 0.5f, 0.5f) / Scaler).rgb;
- float2 Coord0 = (Input.Coord0.xy + float2(0.00f / RawWidth, 0.0f)) * Scaler;
- float2 Coord1 = (Input.Coord1.xy + float2(0.25f / RawWidth, 0.0f)) * Scaler;
- float2 Coord2 = (Input.Coord2.xy + float2(0.50f / RawWidth, 0.0f)) * Scaler;
- float2 Coord3 = (Input.Coord3.xy + float2(0.75f / RawWidth, 0.0f)) * Scaler;
+ float2 Coord0 = (Input.Coord0.xy + float2(0.00f / RawWidth, 0.0f));
+ float2 Coord1 = (Input.Coord1.xy + float2(0.25f / RawWidth, 0.0f));
+ float2 Coord2 = (Input.Coord2.xy + float2(0.50f / RawWidth, 0.0f));
+ float2 Coord3 = (Input.Coord3.xy + float2(0.75f / RawWidth, 0.0f));
- float W = WValue * 2.0f;
- float T0 = Coord0.x + AValue * Coord0.y + BValue;
- float T1 = Coord1.x + AValue * Coord1.y + BValue;
- float T2 = Coord2.x + AValue * Coord2.y + BValue;
- float T3 = Coord3.x + AValue * Coord3.y + BValue;
+ float PI = 3.1415926535897932384626433832795;
+ float W = PI * 2.0f * CCValue * ScanTime;
+ float T0 = Coord0.x * WidthRatio + AValue * Coord0.y * 2.0f * (RawHeight / HeightRatio) + BValue;
+ float T1 = Coord1.x * WidthRatio + AValue * Coord1.y * 2.0f * (RawHeight / HeightRatio) + BValue;
+ float T2 = Coord2.x * WidthRatio + AValue * Coord2.y * 2.0f * (RawHeight / HeightRatio) + BValue;
+ float T3 = Coord3.x * WidthRatio + AValue * Coord3.y * 2.0f * (RawHeight / HeightRatio) + BValue;
float Y0 = dot(Texel0, float3(0.299f, 0.587f, 0.114f));
float I0 = dot(Texel0, float3(0.595716f, -0.274453f, -0.321263f));
@@ -132,10 +129,10 @@ float4 ps_main(PS_INPUT Input) : COLOR
float MinC = -1.1183f;
float CRange = MaxC - MinC;
- float C0 = Y0 + I0 * sin(T0 * W) + Q0 * cos(T0 * W);
- float C1 = Y1 + I1 * sin(T1 * W) + Q1 * cos(T1 * W);
- float C2 = Y2 + I2 * sin(T2 * W) + Q2 * cos(T2 * W);
- float C3 = Y3 + I3 * sin(T3 * W) + Q3 * cos(T3 * W);
+ float C0 = Y0 + I0 * cos(T0 * W) + Q0 * sin(T0 * W);
+ float C1 = Y1 + I1 * cos(T1 * W) + Q1 * sin(T1 * W);
+ float C2 = Y2 + I2 * cos(T2 * W) + Q2 * sin(T2 * W);
+ float C3 = Y3 + I3 * cos(T3 * W) + Q3 * sin(T3 * W);
C0 = (C0 - MinC) / CRange;
C1 = (C1 - MinC) / CRange;
C2 = (C2 - MinC) / CRange;
diff --git a/src/osd/windows/d3d8intf.c b/src/osd/windows/d3d8intf.c
index da220335b71..0218309b193 100644
--- a/src/osd/windows/d3d8intf.c
+++ b/src/osd/windows/d3d8intf.c
@@ -360,6 +360,13 @@ static HRESULT d3d_device_get_render_target(d3d_device *dev, DWORD index, d3d_su
}
+static HRESULT d3d_device_get_render_target_data(d3d_device *dev, d3d_surface *rendertarget, d3d_surface *destsurface)
+{
+ assert(false);
+ return D3D_OK;
+}
+
+
static HRESULT d3d_device_present(d3d_device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags)
{
IDirect3DDevice8 *device = (IDirect3DDevice8 *)dev;
@@ -470,6 +477,7 @@ static const d3d_device_interface d3d8_device_interface =
d3d_device_end_scene,
d3d_device_get_raster_status,
d3d_device_get_render_target,
+ d3d_device_get_render_target_data,
d3d_device_present,
d3d_device_release,
d3d_device_reset,
diff --git a/src/osd/windows/d3d9intf.c b/src/osd/windows/d3d9intf.c
index f2b3a19877f..dccf68cde75 100644
--- a/src/osd/windows/d3d9intf.c
+++ b/src/osd/windows/d3d9intf.c
@@ -398,6 +398,13 @@ static HRESULT d3d_device_get_render_target(d3d_device *dev, DWORD index, d3d_su
}
+static HRESULT d3d_device_get_render_target_data(d3d_device *dev, d3d_surface *rendertarget, d3d_surface *destsurface)
+{
+ IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
+ return IDirect3DDevice9_GetRenderTargetData(device, (IDirect3DSurface9 *)rendertarget, (IDirect3DSurface9 *)destsurface);
+}
+
+
static HRESULT d3d_device_present(d3d_device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags)
{
IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
@@ -544,6 +551,7 @@ static const d3d_device_interface d3d9_device_interface =
d3d_device_end_scene,
d3d_device_get_raster_status,
d3d_device_get_render_target,
+ d3d_device_get_render_target_data,
d3d_device_present,
d3d_device_release,
d3d_device_reset,
diff --git a/src/osd/windows/d3dintf.h b/src/osd/windows/d3dintf.h
index 1c939b17bdc..4819281339e 100644
--- a/src/osd/windows/d3dintf.h
+++ b/src/osd/windows/d3dintf.h
@@ -190,6 +190,7 @@ struct _d3d_device_interface
HRESULT (*end_scene)(d3d_device *dev);
HRESULT (*get_raster_status)(d3d_device *dev, D3DRASTER_STATUS *status);
HRESULT (*get_render_target)(d3d_device *dev, DWORD index, d3d_surface **surface);
+ HRESULT (*get_render_target_data)(d3d_device *dev, d3d_surface *rendertarget, d3d_surface *destsurface);
HRESULT (*present)(d3d_device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags);
ULONG (*release)(d3d_device *dev);
HRESULT (*reset)(d3d_device *dev, d3d_present_parameters *params);
diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c
index 47af7112138..d2bf7ed4a64 100644
--- a/src/osd/windows/drawd3d.c
+++ b/src/osd/windows/drawd3d.c
@@ -54,6 +54,7 @@
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
+#include <math.h>
#undef interface
// MAME headers
@@ -63,6 +64,8 @@
#include "rendutil.h"
#include "options.h"
#include "emuopts.h"
+#include "aviio.h"
+#include "png.h"
// MAMEOS headers
#include "d3dintf.h"
@@ -116,6 +119,7 @@ typedef struct _texture_info texture_info;
struct _texture_info
{
texture_info * next; // next texture in the list
+ texture_info * prev; // prev texture in the list
UINT32 hash; // hash value for the texture
UINT32 flags; // rendering flags
render_texinfo texinfo; // copy of the texture info
@@ -130,19 +134,8 @@ struct _texture_info
int cur_frame; // what is our current frame?
d3d_texture * d3dtex; // Direct3D texture pointer
d3d_surface * d3dsurface; // Direct3D offscreen plain surface pointer
- d3d_surface * d3dtarget0; // Direct3D render target surface pointer (pass 0, if necessary)
- d3d_surface * d3dtarget1; // Direct3D render target surface pointer (pass 1, if necessary)
- d3d_surface * d3dtarget2; // Direct3D render target surface pointer (pass 2, if necessary)
- d3d_surface * d3dtarget3; // Direct3D render target surface pointer (pass 3, if necessary)
- d3d_surface * d3dtarget4; // Direct3D render target surface pointer (pass 4, if necessary)
- d3d_surface * d3dsmalltarget0; // Direct3D render target surface pointer (small pass 0, if necessary)
- d3d_texture * d3dtexture0; // Direct3D render target texture pointer (pass 0, if necessary)
- d3d_texture * d3dtexture1; // Direct3D render target texture pointer (pass 1, if necessary)
- d3d_texture * d3dtexture2; // Direct3D render target texture pointer (pass 2, if necessary)
- d3d_texture * d3dtexture3; // Direct3D render target texture pointer (pass 3, if necessary)
- d3d_texture * d3dtexture4; // Direct3D render target texture pointer (pass 4, if necessary)
- d3d_texture * d3dsmalltexture0; // Direct3D render target texture pointer (small pass 0, if necessary)
d3d_texture * d3dfinaltex; // Direct3D final (post-scaled) texture
+ int target_index; // Direct3D target index
};
@@ -169,7 +162,6 @@ struct _d3d_vertex
float u0, v0; // texture stage 0 coordinates
};
-
/* d3d_options is the information about runtime-mutable Direct3D options */
typedef struct _d3d_options d3d_options;
struct _d3d_options
@@ -183,6 +175,7 @@ struct _d3d_options
float screen_pincushion;
float screen_scanline_alpha;
float screen_scanline_scale;
+ float screen_scanline_height;
float screen_scanline_bright_scale;
float screen_scanline_bright_offset;
float screen_scanline_offset;
@@ -227,6 +220,88 @@ struct _d3d_options
float screen_saturation;
};
+static d3d_options g_d3d_hlsl_presets[6] =
+{
+ { 0.00f, 1, 1, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f,
+ 1.1f, 1.1f, 1.1f,
+ 0.9f, 0.9f, 0.9f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 1.4f },
+ { 0.15f, 512, 384, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f,
+ 1.1f, 1.1f, 1.1f,
+ 0.9f, 0.9f, 0.9f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 1.4f },
+ { 0.15f, 512, 384, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.4f, 0.1f, 0.0, 0.0f,-0.25f,-0.3f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f,
+ 1.1f, 1.1f, 1.1f,
+ 0.9f, 0.9f, 0.9f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 1.4f },
+ { 0.15f, 512, 384, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.4f, 0.1f, 0.0, 0.0f,-0.25f,-0.3f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 1.0f },
+ { 0.15f, 512, 384, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.4f, 0.1f, 0.0, 0.0f,-0.25f,-0.3f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 0.8f },
+ { 0.15f, 512, 384, 0.1875f, 0.1875f,
+ 0.03f, 0.03f,
+ 0.25f, 1.0f, 1.0f, 0.6f, 0.0f,
+ 0.0f, 0.0f,
+ 0.4f, 0.1f, 0.0, 0.0f,-0.25f,-0.3f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.7f, 0.3f, 0.0f, 0.0f, 0.7f, 0.3f, 0.3f, 0.0f, 0.7f,
+ 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 0.05f, 0.05f, 0.05f,
+ 0.45f, 0.45f, 0.45f,
+ 0.8f }
+};
+
/* d3d_info is the information about Direct3D for the current screen */
typedef struct _d3d_info d3d_info;
struct _d3d_info
@@ -249,6 +324,7 @@ struct _d3d_info
int numverts; // number of accumulated vertices
d3d_effect * effect; // pointer to the current effect object
+ d3d_effect * prescale_effect; // pointer to the current prescale-effect object
d3d_effect * post_effect; // pointer to the current post-effect object
d3d_effect * pincushion_effect; // pointer to the current pincushion-effect object
d3d_effect * focus_effect; // pointer to the current focus-effect object
@@ -291,16 +367,54 @@ struct _d3d_info
bitmap_t * default_bitmap; // experimental: default bitmap
texture_info * default_texture; // experimental: default texture
- bool hlsl_enable; // experimental: HLSL enable flag
- bool yiq_enable; // experimental: HLSL YIQ-convolution flag
- d3d_surface * last_d3dtarget[9]; // Direct3D render target surface pointer for each screen's previous frame
- d3d_texture * last_d3dtexture[9]; // Direct3D render target texture pointer for each screen's previous frame
- float oversample_x; // experimental: render target oversampling factor (width) for shader prettification
- float oversample_y; // experimental: render target oversampling factor (height) for shader prettification
- bitmap_t * shadow_bitmap; // experimental: shadow mask bitmap for post-processing shader
- texture_info * shadow_texture; // experimental: shadow mask texture for post-processing shader
+ bool hlsl_enable; // HLSL enable flag
+ bool yiq_enable; // HLSL YIQ-convolution flag
+ bool hlsl_prescale; // HLSL prescale enable flag
+ int hlsl_prescale_size; // HLSL prescale size
+ int hlsl_preset; // HLSL preset, if relevant
+ float oversample_x; // render target oversampling factor (width) for shader prettification
+ float oversample_y; // render target oversampling factor (height) for shader prettification
+ bitmap_t * shadow_bitmap; // shadow mask bitmap for post-processing shader
+ texture_info * shadow_texture; // shadow mask texture for post-processing shader
int registered_targets; // Number of registered HLSL targets (i.e., screens)
d3d_options * hlsl_options; // HLSL uniforms
+ avi_file * hlsl_avi_file; // HLSL AVI file
+ bitmap_t * hlsl_avi_snap; // HLSL AVI snapshot
+ int hlsl_avi_frame; // HLSL AVI frame
+ attotime hlsl_avi_frame_period; // HLSL AVI frame period
+ attotime hlsl_avi_next_frame_time; // HLSL AVI next frame time
+ d3d_surface * hlsl_avi_copy_surface; // HLSL AVI destination surface in system memory
+ d3d_texture * hlsl_avi_copy_texture; // HLSL AVI destination texture in system memory
+ d3d_surface * hlsl_avi_final_target; // HLSL AVI upscaled surface
+ d3d_texture * hlsl_avi_final_texture; // HLSL AVI upscaled texture
+ bool hlsl_render_snap; // whether or not to take HLSL post-render snapshot
+ bool hlsl_snap_rendered; // whether we just rendered our HLSL post-render shot or not
+ d3d_surface * hlsl_snap_copy_target; // HLSL snapshot destination surface in system memory
+ d3d_texture * hlsl_snap_copy_texture; // HLSL snapshot destination surface in system memory
+ d3d_surface * hlsl_snap_target; // HLSL snapshot upscaled surface
+ d3d_texture * hlsl_snap_texture; // HLSL snapshot upscaled texture
+ int hlsl_snap_width; // HLSL snapshot width
+ int hlsl_snap_height; // HLSL snapshot height
+
+ // HLSL render targets
+ int target_use_count[9]; // Whether or not a target has been used yet
+ texture_info * target_in_use[9]; // Target texture that is currently in use
+ d3d_surface * last_hlsltarget[9]; // HLSL render target surface pointer for each screen's previous frame
+ d3d_texture * last_hlsltexture[9]; // HLSL render target texture pointer for each screen's previous frame
+ d3d_surface * hlslprescaletarget0[9]; // Direct3D render target surface pointer (prescale, if necessary)
+ d3d_surface * hlsltarget0[9]; // HLSL render target surface pointer (pass 0, if necessary)
+ d3d_surface * hlsltarget1[9]; // HLSL render target surface pointer (pass 1, if necessary)
+ d3d_surface * hlsltarget2[9]; // HLSL render target surface pointer (pass 2, if necessary)
+ d3d_surface * hlsltarget3[9]; // HLSL render target surface pointer (pass 3, if necessary)
+ d3d_surface * hlsltarget4[9]; // HLSL render target surface pointer (pass 4, if necessary)
+ d3d_surface * hlslsmalltarget0[9]; // HLSL render target surface pointer (small pass 0, if necessary)
+ d3d_texture * hlslprescaletexture0[9]; // HLSL render target surface pointer (prescale, if necessary)
+ d3d_texture * hlsltexture0[9]; // HLSL render target texture pointer (pass 0, if necessary)
+ d3d_texture * hlsltexture1[9]; // HLSL render target texture pointer (pass 1, if necessary)
+ d3d_texture * hlsltexture2[9]; // HLSL render target texture pointer (pass 2, if necessary)
+ d3d_texture * hlsltexture3[9]; // HLSL render target texture pointer (pass 3, if necessary)
+ d3d_texture * hlsltexture4[9]; // HLSL render target texture pointer (pass 4, if necessary)
+ d3d_texture * hlslsmalltexture0[9]; // HLSL render target texture pointer (small pass 0, if necessary)
};
@@ -422,6 +536,11 @@ static INT32 slider_scanline_scale(running_machine &machine, void *arg, astring
return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_scale), 0.05f, "%2.2f", string, newval);
}
+static INT32 slider_scanline_height(running_machine &machine, void *arg, astring *string, INT32 newval)
+{
+ return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_height), 0.05f, "%2.2f", string, newval);
+}
+
static INT32 slider_scanline_bright_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
{
return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_bright_scale), 0.05f, "%2.2f", string, newval);
@@ -656,7 +775,8 @@ static slider_state *init_slider_list(d3d_info *d3d)
*tailptr = slider_alloc(d3d->window->machine(), "Screen Curvature", 0, 0, 100, 1, slider_curvature, (void*)d3d); tailptr = &(*tailptr)->next;
*tailptr = slider_alloc(d3d->window->machine(), "Image Pincushion", 0, 0, 100, 1, slider_pincushion, (void*)d3d); tailptr = &(*tailptr)->next;
*tailptr = slider_alloc(d3d->window->machine(), "Scanline Darkness", 0, 0, 100, 1, slider_scanline_alpha, (void*)d3d); tailptr = &(*tailptr)->next;
- *tailptr = slider_alloc(d3d->window->machine(), "Scanline Size", 1, 20, 80, 1, slider_scanline_scale, (void*)d3d); tailptr = &(*tailptr)->next;
+ *tailptr = slider_alloc(d3d->window->machine(), "Scanline Screen Height", 1, 20, 80, 1, slider_scanline_scale, (void*)d3d); tailptr = &(*tailptr)->next;
+ *tailptr = slider_alloc(d3d->window->machine(), "Scanline Indiv. Height", 1, 10, 80, 1, slider_scanline_height, (void*)d3d); tailptr = &(*tailptr)->next;
*tailptr = slider_alloc(d3d->window->machine(), "Scanline Brightness", 0, 20, 40, 1, slider_scanline_bright_scale, (void*)d3d); tailptr = &(*tailptr)->next;
*tailptr = slider_alloc(d3d->window->machine(), "Scanline Brightness Overdrive", 0, 12, 20, 1, slider_scanline_bright_offset, (void*)d3d); tailptr = &(*tailptr)->next;
*tailptr = slider_alloc(d3d->window->machine(), "Scanline Jitter", 0, 0, 40, 1, slider_scanline_offset, (void*)d3d); tailptr = &(*tailptr)->next;
@@ -939,6 +1059,8 @@ static void drawd3d_exit(void);
static int drawd3d_window_init(win_window_info *window);
static void drawd3d_window_destroy(win_window_info *window);
static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window);
+static void drawd3d_window_save(win_window_info *window);
+static void drawd3d_window_record(win_window_info *window);
static int drawd3d_window_draw(win_window_info *window, HDC dc, int update);
// devices
@@ -972,6 +1094,12 @@ static void texture_prescale(d3d_info *d3d, texture_info *texture);
static texture_info *texture_find(d3d_info *d3d, const render_primitive *prim);
static void texture_update(d3d_info *d3d, const render_primitive *prim);
+// logging
+static void end_hlsl_avi_recording(d3d_info *d3d);
+static void hlsl_render_snapshot(d3d_info *d3d, d3d_surface *surface);
+static void begin_hlsl_avi_recording(d3d_info *d3d, const char *name);
+static void hlsl_record_texture(d3d_info *d3d, d3d_surface *surface);
+static file_error open_next(d3d_info *d3d, emu_file &file, const char *extension, int idx);
//============================================================
@@ -1005,6 +1133,8 @@ int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks)
callbacks->window_init = drawd3d_window_init;
callbacks->window_get_primitives = drawd3d_window_get_primitives;
callbacks->window_draw = drawd3d_window_draw;
+ callbacks->window_save = drawd3d_window_save;
+ callbacks->window_record = drawd3d_window_record;
callbacks->window_destroy = drawd3d_window_destroy;
return 0;
}
@@ -1035,6 +1165,7 @@ static int drawd3d_window_init(win_window_info *window)
d3d = global_alloc_clear(d3d_info);
window->drawdata = d3d;
d3d->window = window;
+ d3d->hlsl_options = NULL;
// experimental: load a PNG to use for vector rendering; it is treated
// as a brightness map
@@ -1070,6 +1201,61 @@ error:
//============================================================
+// drawd3d_window_save
+//============================================================
+
+static void drawd3d_window_save(win_window_info *window)
+{
+ d3d_info *d3d = (d3d_info *)window->drawdata;
+
+ if (!d3d->hlsl_enable || !d3dintf->post_fx_available)
+ return;
+
+ HRESULT result = (*d3dintf->device.create_texture)(d3d->device, d3d->hlsl_snap_width, d3d->hlsl_snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &d3d->hlsl_snap_copy_texture);
+ if (result != D3D_OK)
+ {
+ mame_printf_verbose("Direct3D: Unable to init system-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
+ return;
+ }
+ (*d3dintf->texture.get_surface_level)(d3d->hlsl_snap_copy_texture, 0, &d3d->hlsl_snap_copy_target);
+
+ result = (*d3dintf->device.create_texture)(d3d->device, d3d->hlsl_snap_width, d3d->hlsl_snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsl_snap_texture);
+ if (result != D3D_OK)
+ {
+ mame_printf_verbose("Direct3D: Unable to init video-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
+ return;
+ }
+ (*d3dintf->texture.get_surface_level)(d3d->hlsl_snap_texture, 0, &d3d->hlsl_snap_target);
+
+ d3d->hlsl_render_snap = true;
+ d3d->hlsl_snap_rendered = false;
+}
+
+static void drawd3d_window_record(win_window_info *window)
+{
+ d3d_info *d3d = (d3d_info *)window->drawdata;
+
+ if (!d3d->hlsl_enable || !d3dintf->post_fx_available)
+ return;
+
+ windows_options &options = downcast<windows_options &>(window->machine().options());
+ const char *filename = options.d3d_hlsl_write();
+
+ if(d3d->hlsl_avi_file != NULL)
+ {
+ end_hlsl_avi_recording(d3d);
+ }
+ else
+ {
+ if (filename[0] != 0)
+ {
+ begin_hlsl_avi_recording(d3d, filename);
+ }
+ }
+}
+
+
+//============================================================
// drawd3d_window_destroy
//============================================================
@@ -1077,6 +1263,8 @@ static void drawd3d_window_destroy(win_window_info *window)
{
d3d_info *d3d = (d3d_info *)window->drawdata;
+ end_hlsl_avi_recording(d3d);
+
// skip if nothing
if (d3d == NULL)
return;
@@ -1164,6 +1352,8 @@ mtlog_add("drawd3d_window_draw: begin");
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
+ hlsl_record_texture(d3d, d3d->hlsl_avi_final_target);
+
// first update any textures
window->primlist->acquire_lock();
for (prim = window->primlist->first(); prim != NULL; prim = prim->next())
@@ -1218,6 +1408,11 @@ mtlog_add("drawd3d_window_draw: present begin");
mtlog_add("drawd3d_window_draw: present end");
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result);
+ if(d3d->hlsl_render_snap && d3d->hlsl_snap_rendered)
+ {
+ hlsl_render_snapshot(d3d, d3d->hlsl_snap_target);
+ }
+
return 0;
}
@@ -1326,6 +1521,11 @@ try_again:
d3d->create_error_count = 0;
mame_printf_verbose("Direct3D: Device created at %dx%d\n", d3d->width, d3d->height);
+ d3d->oversample_x = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_x();
+ d3d->oversample_y = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_y();
+ d3d->hlsl_snap_width = downcast<windows_options &>(d3d->window->machine().options()).d3d_snap_width();
+ d3d->hlsl_snap_height = downcast<windows_options &>(d3d->window->machine().options()).d3d_snap_height();
+
// set the max texture size
window->target->set_max_texture_size(d3d->texture_max_width, d3d->texture_max_height);
mame_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)d3d->texture_max_width, (int)d3d->texture_max_height);
@@ -1362,6 +1562,7 @@ try_again:
const char *fx_dir = downcast<windows_options &>(window->machine().options()).screen_post_fx_dir();
char primary_name_cstr[1024];
char post_name_cstr[1024];
+ char prescale_name_cstr[1024];
char pincushion_name_cstr[1024];
char phosphor_name_cstr[1024];
char focus_name_cstr[1024];
@@ -1376,6 +1577,9 @@ try_again:
sprintf(post_name_cstr, "%s\\post.fx", fx_dir);
TCHAR *post_name = tstring_from_utf8(post_name_cstr);
+ sprintf(prescale_name_cstr, "%s\\prescale.fx", fx_dir);
+ TCHAR *prescale_name = tstring_from_utf8(prescale_name_cstr);
+
sprintf(pincushion_name_cstr, "%s\\pincushion.fx", fx_dir);
TCHAR *pincushion_name = tstring_from_utf8(pincushion_name_cstr);
@@ -1401,7 +1605,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, primary_name, &d3d->effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load primary.fx\n");
+ printf("Direct3D: Unable to load primary.fx\n");
return 1;
}
@@ -1409,7 +1613,15 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, post_name, &d3d->post_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load post.fx\n");
+ printf("Direct3D: Unable to load post.fx\n");
+ return 1;
+ }
+
+ // create the prescaling shader
+ result = (*d3dintf->device.create_effect)(d3d->device, prescale_name, &d3d->prescale_effect);
+ if(result != D3D_OK)
+ {
+ printf("Direct3D: Unable to load prescale.fx\n");
return 1;
}
@@ -1417,7 +1629,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, pincushion_name, &d3d->pincushion_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load pincushion.fx\n");
+ printf("Direct3D: Unable to load pincushion.fx\n");
return 1;
}
@@ -1425,7 +1637,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, phosphor_name, &d3d->phosphor_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load phosphor.fx\n");
+ printf("Direct3D: Unable to load phosphor.fx\n");
return 1;
}
@@ -1433,7 +1645,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, focus_name, &d3d->focus_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load focus.fx\n");
+ printf("Direct3D: Unable to load focus.fx\n");
return 1;
}
@@ -1441,7 +1653,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, deconverge_name, &d3d->deconverge_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load deconverge.fx\n");
+ printf("Direct3D: Unable to load deconverge.fx\n");
return 1;
}
@@ -1449,7 +1661,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, color_name, &d3d->color_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load color.fx\n");
+ printf("Direct3D: Unable to load color.fx\n");
return 1;
}
@@ -1457,7 +1669,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, yiq_encode_name, &d3d->yiq_encode_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load yiq_encode.fx\n");
+ printf("Direct3D: Unable to load yiq_encode.fx\n");
return 1;
}
@@ -1465,7 +1677,7 @@ try_again:
result = (*d3dintf->device.create_effect)(d3d->device, yiq_decode_name, &d3d->yiq_decode_effect);
if(result != D3D_OK)
{
- mame_printf_verbose("Direct3D: Unable to load yiq_decode.fx\n");
+ printf("Direct3D: Unable to load yiq_decode.fx\n");
return 1;
}
@@ -1473,6 +1685,8 @@ try_again:
osd_free(primary_name);
if (post_name)
osd_free(post_name);
+ if (prescale_name)
+ osd_free(prescale_name);
if (pincushion_name)
osd_free(pincushion_name);
if (phosphor_name)
@@ -1590,6 +1804,22 @@ static int device_create_resources(d3d_info *d3d)
// experimental: initialize some more things if we're using HLSL
if(d3d->hlsl_enable && d3dintf->post_fx_available)
{
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &d3d->hlsl_avi_copy_texture);
+ if (result != D3D_OK)
+ {
+ mame_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
+ return 1;
+ }
+ (*d3dintf->texture.get_surface_level)(d3d->hlsl_avi_copy_texture, 0, &d3d->hlsl_avi_copy_surface);
+
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsl_avi_final_texture);
+ if (result != D3D_OK)
+ {
+ mame_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
+ return 1;
+ }
+ (*d3dintf->texture.get_surface_level)(d3d->hlsl_avi_final_texture, 0, &d3d->hlsl_avi_final_target);
+
windows_options &options = downcast<windows_options &>(d3d->window->machine().options());
// experimental: load a PNG to use for vector rendering; it is treated
@@ -1615,57 +1845,66 @@ static int device_create_resources(d3d_info *d3d)
}
d3d->hlsl_options = (d3d_options*)global_alloc_clear(d3d_options);
- d3d->hlsl_options->screen_shadow_mask_alpha = options.screen_shadow_mask_alpha();
- d3d->hlsl_options->screen_shadow_mask_count_x = options.screen_shadow_mask_count_x();
- d3d->hlsl_options->screen_shadow_mask_count_y = options.screen_shadow_mask_count_y();
- d3d->hlsl_options->screen_shadow_mask_u_size = options.screen_shadow_mask_u_size();
- d3d->hlsl_options->screen_shadow_mask_v_size = options.screen_shadow_mask_v_size();
- d3d->hlsl_options->screen_curvature = options.screen_curvature();
- d3d->hlsl_options->screen_pincushion = options.screen_pincushion();
- d3d->hlsl_options->screen_scanline_alpha = options.screen_scanline_amount();
- d3d->hlsl_options->screen_scanline_scale = options.screen_scanline_scale();
- d3d->hlsl_options->screen_scanline_bright_scale = options.screen_scanline_bright_scale();
- d3d->hlsl_options->screen_scanline_bright_offset = options.screen_scanline_bright_offset();
- d3d->hlsl_options->screen_scanline_offset = options.screen_scanline_offset();
- d3d->hlsl_options->screen_defocus_x = options.screen_defocus_x();
- d3d->hlsl_options->screen_defocus_y = options.screen_defocus_y();
- d3d->hlsl_options->screen_red_converge_x = options.screen_red_converge_x();
- d3d->hlsl_options->screen_red_converge_y = options.screen_red_converge_y();
- d3d->hlsl_options->screen_green_converge_x = options.screen_green_converge_x();
- d3d->hlsl_options->screen_green_converge_y = options.screen_green_converge_y();
- d3d->hlsl_options->screen_blue_converge_x = options.screen_blue_converge_x();
- d3d->hlsl_options->screen_blue_converge_y = options.screen_blue_converge_y();
- d3d->hlsl_options->screen_red_radial_converge_x = options.screen_red_radial_converge_x();
- d3d->hlsl_options->screen_red_radial_converge_y = options.screen_red_radial_converge_y();
- d3d->hlsl_options->screen_green_radial_converge_x = options.screen_green_radial_converge_x();
- d3d->hlsl_options->screen_green_radial_converge_y = options.screen_green_radial_converge_y();
- d3d->hlsl_options->screen_blue_radial_converge_x = options.screen_blue_radial_converge_x();
- d3d->hlsl_options->screen_blue_radial_converge_y = options.screen_blue_radial_converge_y();
- d3d->hlsl_options->screen_red_from_red = options.screen_red_from_red();
- d3d->hlsl_options->screen_red_from_green = options.screen_red_from_green();
- d3d->hlsl_options->screen_red_from_blue = options.screen_red_from_blue();
- d3d->hlsl_options->screen_green_from_red = options.screen_green_from_red();
- d3d->hlsl_options->screen_green_from_green = options.screen_green_from_green();
- d3d->hlsl_options->screen_green_from_blue = options.screen_green_from_blue();
- d3d->hlsl_options->screen_blue_from_red = options.screen_blue_from_red();
- d3d->hlsl_options->screen_blue_from_green = options.screen_blue_from_green();
- d3d->hlsl_options->screen_blue_from_blue = options.screen_blue_from_blue();
- d3d->hlsl_options->screen_red_offset = options.screen_red_offset();
- d3d->hlsl_options->screen_green_offset = options.screen_green_offset();
- d3d->hlsl_options->screen_blue_offset = options.screen_blue_offset();
- d3d->hlsl_options->screen_red_scale = options.screen_red_scale();
- d3d->hlsl_options->screen_green_scale = options.screen_green_scale();
- d3d->hlsl_options->screen_blue_scale = options.screen_blue_scale();
- d3d->hlsl_options->screen_red_power = options.screen_red_power();
- d3d->hlsl_options->screen_green_power = options.screen_green_power();
- d3d->hlsl_options->screen_blue_power = options.screen_blue_power();
- d3d->hlsl_options->screen_red_floor = options.screen_red_floor();
- d3d->hlsl_options->screen_green_floor = options.screen_green_floor();
- d3d->hlsl_options->screen_blue_floor = options.screen_blue_floor();
- d3d->hlsl_options->screen_red_phosphor_life = options.screen_red_phosphor();
- d3d->hlsl_options->screen_green_phosphor_life = options.screen_green_phosphor();
- d3d->hlsl_options->screen_blue_phosphor_life = options.screen_blue_phosphor();
- d3d->hlsl_options->screen_saturation = options.screen_saturation();
+
+ if(d3d->hlsl_preset == -1)
+ {
+ d3d->hlsl_options->screen_shadow_mask_alpha = options.screen_shadow_mask_alpha();
+ d3d->hlsl_options->screen_shadow_mask_count_x = options.screen_shadow_mask_count_x();
+ d3d->hlsl_options->screen_shadow_mask_count_y = options.screen_shadow_mask_count_y();
+ d3d->hlsl_options->screen_shadow_mask_u_size = options.screen_shadow_mask_u_size();
+ d3d->hlsl_options->screen_shadow_mask_v_size = options.screen_shadow_mask_v_size();
+ d3d->hlsl_options->screen_curvature = options.screen_curvature();
+ d3d->hlsl_options->screen_pincushion = options.screen_pincushion();
+ d3d->hlsl_options->screen_scanline_alpha = options.screen_scanline_amount();
+ d3d->hlsl_options->screen_scanline_scale = options.screen_scanline_scale();
+ d3d->hlsl_options->screen_scanline_height = options.screen_scanline_height();
+ d3d->hlsl_options->screen_scanline_bright_scale = options.screen_scanline_bright_scale();
+ d3d->hlsl_options->screen_scanline_bright_offset = options.screen_scanline_bright_offset();
+ d3d->hlsl_options->screen_scanline_offset = options.screen_scanline_offset();
+ d3d->hlsl_options->screen_defocus_x = options.screen_defocus_x();
+ d3d->hlsl_options->screen_defocus_y = options.screen_defocus_y();
+ d3d->hlsl_options->screen_red_converge_x = options.screen_red_converge_x();
+ d3d->hlsl_options->screen_red_converge_y = options.screen_red_converge_y();
+ d3d->hlsl_options->screen_green_converge_x = options.screen_green_converge_x();
+ d3d->hlsl_options->screen_green_converge_y = options.screen_green_converge_y();
+ d3d->hlsl_options->screen_blue_converge_x = options.screen_blue_converge_x();
+ d3d->hlsl_options->screen_blue_converge_y = options.screen_blue_converge_y();
+ d3d->hlsl_options->screen_red_radial_converge_x = options.screen_red_radial_converge_x();
+ d3d->hlsl_options->screen_red_radial_converge_y = options.screen_red_radial_converge_y();
+ d3d->hlsl_options->screen_green_radial_converge_x = options.screen_green_radial_converge_x();
+ d3d->hlsl_options->screen_green_radial_converge_y = options.screen_green_radial_converge_y();
+ d3d->hlsl_options->screen_blue_radial_converge_x = options.screen_blue_radial_converge_x();
+ d3d->hlsl_options->screen_blue_radial_converge_y = options.screen_blue_radial_converge_y();
+ d3d->hlsl_options->screen_red_from_red = options.screen_red_from_red();
+ d3d->hlsl_options->screen_red_from_green = options.screen_red_from_green();
+ d3d->hlsl_options->screen_red_from_blue = options.screen_red_from_blue();
+ d3d->hlsl_options->screen_green_from_red = options.screen_green_from_red();
+ d3d->hlsl_options->screen_green_from_green = options.screen_green_from_green();
+ d3d->hlsl_options->screen_green_from_blue = options.screen_green_from_blue();
+ d3d->hlsl_options->screen_blue_from_red = options.screen_blue_from_red();
+ d3d->hlsl_options->screen_blue_from_green = options.screen_blue_from_green();
+ d3d->hlsl_options->screen_blue_from_blue = options.screen_blue_from_blue();
+ d3d->hlsl_options->screen_red_offset = options.screen_red_offset();
+ d3d->hlsl_options->screen_green_offset = options.screen_green_offset();
+ d3d->hlsl_options->screen_blue_offset = options.screen_blue_offset();
+ d3d->hlsl_options->screen_red_scale = options.screen_red_scale();
+ d3d->hlsl_options->screen_green_scale = options.screen_green_scale();
+ d3d->hlsl_options->screen_blue_scale = options.screen_blue_scale();
+ d3d->hlsl_options->screen_red_power = options.screen_red_power();
+ d3d->hlsl_options->screen_green_power = options.screen_green_power();
+ d3d->hlsl_options->screen_blue_power = options.screen_blue_power();
+ d3d->hlsl_options->screen_red_floor = options.screen_red_floor();
+ d3d->hlsl_options->screen_green_floor = options.screen_green_floor();
+ d3d->hlsl_options->screen_blue_floor = options.screen_blue_floor();
+ d3d->hlsl_options->screen_red_phosphor_life = options.screen_red_phosphor();
+ d3d->hlsl_options->screen_green_phosphor_life = options.screen_green_phosphor();
+ d3d->hlsl_options->screen_blue_phosphor_life = options.screen_blue_phosphor();
+ d3d->hlsl_options->screen_saturation = options.screen_saturation();
+ }
+ else
+ {
+ d3d->hlsl_options = &g_d3d_hlsl_presets[d3d->hlsl_preset];
+ }
slider_list = init_slider_list(d3d);
}
@@ -1713,30 +1952,6 @@ static void device_delete_resources(d3d_info *d3d)
(*d3dintf->texture.release)(tex->d3dtex);
if (tex->d3dsurface != NULL)
(*d3dintf->surface.release)(tex->d3dsurface);
- if (tex->d3dtexture0 != NULL)
- (*d3dintf->texture.release)(tex->d3dtexture0);
- if (tex->d3dtexture1 != NULL)
- (*d3dintf->texture.release)(tex->d3dtexture1);
- if (tex->d3dtexture2 != NULL)
- (*d3dintf->texture.release)(tex->d3dtexture2);
- if (tex->d3dtexture3 != NULL)
- (*d3dintf->texture.release)(tex->d3dtexture3);
- if (tex->d3dtexture4 != NULL)
- (*d3dintf->texture.release)(tex->d3dtexture4);
- if (tex->d3dsmalltexture0 != NULL)
- (*d3dintf->texture.release)(tex->d3dsmalltexture0);
- if (tex->d3dtarget0 != NULL)
- (*d3dintf->surface.release)(tex->d3dtarget0);
- if (tex->d3dtarget1 != NULL)
- (*d3dintf->surface.release)(tex->d3dtarget1);
- if (tex->d3dtarget2 != NULL)
- (*d3dintf->surface.release)(tex->d3dtarget2);
- if (tex->d3dtarget3 != NULL)
- (*d3dintf->surface.release)(tex->d3dtarget3);
- if (tex->d3dtarget4 != NULL)
- (*d3dintf->surface.release)(tex->d3dtarget4);
- if (tex->d3dsmalltarget0 != NULL)
- (*d3dintf->surface.release)(tex->d3dsmalltarget0);
global_free(tex);
}
@@ -1758,6 +1973,11 @@ static void device_delete_resources(d3d_info *d3d)
(*d3dintf->effect.release)(d3d->post_effect);
d3d->post_effect = NULL;
}
+ if(d3d->prescale_effect != NULL)
+ {
+ (*d3dintf->effect.release)(d3d->prescale_effect);
+ d3d->prescale_effect = NULL;
+ }
if(d3d->pincushion_effect != NULL)
{
(*d3dintf->effect.release)(d3d->pincushion_effect);
@@ -1796,16 +2016,110 @@ static void device_delete_resources(d3d_info *d3d)
for(int index = 0; index < 9; index++)
{
- if(d3d->last_d3dtexture[index] != NULL)
+ if (d3d->hlslprescaletexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlslprescaletexture0[index]);
+ d3d->hlslprescaletexture0[index] = NULL;
+ }
+ if (d3d->hlsltexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture0[index]);
+ d3d->hlsltexture0[index] = NULL;
+ }
+ if (d3d->hlsltexture1[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture1[index]);
+ d3d->hlsltexture1[index] = NULL;
+ }
+ if (d3d->hlsltexture2[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture2[index]);
+ d3d->hlsltexture2[index] = NULL;
+ }
+ if (d3d->hlsltexture3[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture3[index]);
+ d3d->hlsltexture3[index] = NULL;
+ }
+ if (d3d->hlsltexture4[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture4[index]);
+ d3d->hlsltexture4[index] = NULL;
+ }
+ if (d3d->hlslsmalltexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlslsmalltexture0[index]);
+ d3d->hlslsmalltexture0[index] = NULL;
+ }
+ if (d3d->hlslprescaletarget0[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlslprescaletarget0[index]);
+ d3d->hlslprescaletarget0[index] = NULL;
+ }
+ if (d3d->hlsltarget0[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget0[index]);
+ d3d->hlsltarget0[index] = NULL;
+ }
+ if (d3d->hlsltarget1[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget1[index]);
+ d3d->hlsltarget1[index] = NULL;
+ }
+ if (d3d->hlsltarget2[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget2[index]);
+ d3d->hlsltarget2[index] = NULL;
+ }
+ if (d3d->hlsltarget3[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget3[index]);
+ d3d->hlsltarget3[index] = NULL;
+ }
+ if (d3d->hlsltarget4[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget4[index]);
+ d3d->hlsltarget4[index] = NULL;
+ }
+ if (d3d->hlslsmalltarget0[index] != NULL)
{
- (*d3dintf->texture.release)(d3d->last_d3dtexture[index]);
- d3d->last_d3dtexture[index] = NULL;
+ (*d3dintf->surface.release)(d3d->hlslsmalltarget0[index]);
+ d3d->hlslsmalltarget0[index] = NULL;
}
- if(d3d->last_d3dtarget[index] != NULL)
+ if(d3d->last_hlsltexture[index] != NULL)
{
- (*d3dintf->surface.release)(d3d->last_d3dtarget[index]);
- d3d->last_d3dtarget[index] = NULL;
+ (*d3dintf->texture.release)(d3d->last_hlsltexture[index]);
+ d3d->last_hlsltexture[index] = NULL;
}
+ if(d3d->last_hlsltarget[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->last_hlsltarget[index]);
+ d3d->last_hlsltarget[index] = NULL;
+ }
+ }
+
+ if(d3d->hlsl_avi_copy_texture != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsl_avi_copy_texture);
+ d3d->hlsl_avi_copy_texture = NULL;
+ }
+
+ if(d3d->hlsl_avi_copy_surface != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsl_avi_copy_surface);
+ d3d->hlsl_avi_copy_surface = NULL;
+ }
+
+ if(d3d->hlsl_avi_final_texture != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsl_avi_final_texture);
+ d3d->hlsl_avi_final_texture = NULL;
+ }
+
+ if(d3d->hlsl_avi_final_target != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsl_avi_final_target);
+ d3d->hlsl_avi_final_target = NULL;
}
if(d3d->hlsl_options != NULL)
@@ -1846,6 +2160,10 @@ static int device_verify_caps(d3d_info *d3d, win_window_info *window)
d3d->hlsl_enable = downcast<windows_options &>(window->machine().options()).d3d_hlsl_enable() && d3dintf->post_fx_available;
d3d->yiq_enable = downcast<windows_options &>(window->machine().options()).screen_yiq_enable();
+ d3d->hlsl_prescale = downcast<windows_options &>(window->machine().options()).d3d_hlsl_prescale();
+ d3d->hlsl_prescale_size = downcast<windows_options &>(window->machine().options()).d3d_hlsl_prescale_size();
+ d3d->hlsl_preset = downcast<windows_options &>(window->machine().options()).d3d_hlsl_preset();
+
result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
if (result != D3D_OK) mame_printf_verbose("Direct3D Error %08X during get_caps_dword call\n", (int)result);
if(tempcaps < 512 && d3d->hlsl_enable)
@@ -2610,9 +2928,10 @@ static void primitive_flush_pending(d3d_info *d3d)
vertnum = 0;
}
+ bool screen_encountered[9] = { false };
+
d3d_options *options = d3d->hlsl_options;
- int cur_render_screen = 0;
// now do the polys
for (polynum = 0; polynum < d3d->numpolys; polynum++)
{
@@ -2625,6 +2944,9 @@ static void primitive_flush_pending(d3d_info *d3d)
// set filtering if different
if (poly->texture != NULL)
{
+ screen_encountered[poly->texture->target_index] = true;
+ d3d->target_in_use[poly->texture->target_index] = poly->texture;
+
newfilter = FALSE;
if (PRIMFLAG_GET_SCREENTEX(poly->flags))
newfilter = video_config.filter;
@@ -2664,6 +2986,7 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "ShadowHeight", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawheight);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineAmount", options->screen_scanline_alpha);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineScale", options->screen_scanline_scale);
+ (*d3dintf->effect.set_float)(curr_effect, "ScanlineHeight", options->screen_scanline_height);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightScale", options->screen_scanline_bright_scale);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightOffset", options->screen_scanline_bright_offset);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineOffset", (poly->texture->cur_frame == 0) ? 0.0f : options->screen_scanline_offset);
@@ -2688,6 +3011,8 @@ static void primitive_flush_pending(d3d_info *d3d)
if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags) && poly->texture != NULL)
{
+ d3d->target_use_count[poly->texture->target_index] = 60;
+
if(d3d->yiq_enable)
{
/* Convert our signal into YIQ */
@@ -2699,13 +3024,16 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
- (*d3dintf->effect.set_float)(curr_effect, "WValue", winoptions.screen_yiq_w());
+ (*d3dintf->effect.set_float)(curr_effect, "CCValue", winoptions.screen_yiq_cc());
(*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
- (*d3dintf->effect.set_float)(curr_effect, "BValue", (float)poly->texture->cur_frame * winoptions.screen_yiq_b());
- (*d3dintf->effect.set_float)(curr_effect, "FscScale", winoptions.screen_yiq_fsc_scale());
- (*d3dintf->effect.set_float)(curr_effect, "FscValue", winoptions.screen_yiq_fsc());
+ (*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
+ (*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
+ (*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
+ (*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
+ (*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
+ (*d3dintf->effect.set_float)(curr_effect, "ScanTime", winoptions.screen_yiq_scan_time());
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget4);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget4[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@@ -2727,7 +3055,7 @@ static void primitive_flush_pending(d3d_info *d3d)
/* Convert our signal from YIQ */
curr_effect = d3d->yiq_decode_effect;
- (*d3dintf->effect.set_texture)(curr_effect, "Composite", poly->texture->d3dtexture4);
+ (*d3dintf->effect.set_texture)(curr_effect, "Composite", d3d->hlsltexture4[poly->texture->target_index]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dfinaltex);
(*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
(*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
@@ -2735,12 +3063,17 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
- (*d3dintf->effect.set_float)(curr_effect, "WValue", winoptions.screen_yiq_w());
+ (*d3dintf->effect.set_float)(curr_effect, "CCValue", winoptions.screen_yiq_cc());
(*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
- (*d3dintf->effect.set_float)(curr_effect, "BValue", (float)poly->texture->cur_frame * winoptions.screen_yiq_b());
- (*d3dintf->effect.set_float)(curr_effect, "FscValue", winoptions.screen_yiq_fsc());
+ (*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
+ (*d3dintf->effect.set_float)(curr_effect, "OValue", winoptions.screen_yiq_o());
+ (*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
+ (*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
+ (*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
+ (*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
+ (*d3dintf->effect.set_float)(curr_effect, "ScanTime", winoptions.screen_yiq_scan_time());
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget3);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget3[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@@ -2761,7 +3094,7 @@ static void primitive_flush_pending(d3d_info *d3d)
curr_effect = d3d->color_effect;
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture3);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture3[poly->texture->target_index]);
}
curr_effect = d3d->color_effect;
@@ -2797,7 +3130,7 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "BluFloor", options->screen_blue_floor);
(*d3dintf->effect.set_float)(curr_effect, "Saturation", options->screen_saturation);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dsmalltarget0);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlslsmalltarget0[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@@ -2816,9 +3149,48 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.end)(curr_effect);
+ /* Pre-scaling pass (if enabled) */
+ if(d3d->hlsl_prescale)
+ {
+ curr_effect = d3d->prescale_effect;
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlslsmalltexture0[poly->texture->target_index]);
+
+ (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
+ (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
+ (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
+ (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
+ (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f / (poly->texture->ustop - poly->texture->ustart));
+ (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
+
+ (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
+
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlslprescaletarget0[poly->texture->target_index]);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ (*d3dintf->effect.begin_pass)(curr_effect, pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ (*d3dintf->effect.end_pass)(curr_effect);
+ }
+
+ (*d3dintf->effect.end)(curr_effect);
+
+ curr_effect = d3d->deconverge_effect;
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlslprescaletexture0[poly->texture->target_index]);
+ }
+ else
+ {
+ curr_effect = d3d->deconverge_effect;
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlslsmalltexture0[poly->texture->target_index]);
+ }
+
/* Deconverge pass */
curr_effect = d3d->deconverge_effect;
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dsmalltexture0);
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
@@ -2841,7 +3213,7 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget2);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget2[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@@ -2865,7 +3237,7 @@ static void primitive_flush_pending(d3d_info *d3d)
/* Defocus pass 1 */
curr_effect = d3d->focus_effect;
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture2);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture2[poly->texture->target_index]);
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
@@ -2879,7 +3251,7 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget0[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@@ -2897,7 +3269,7 @@ static void primitive_flush_pending(d3d_info *d3d)
/* Defocus pass 2 */
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture0[poly->texture->target_index]);
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
@@ -2911,7 +3283,7 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget1);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget1[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result);
for (UINT pass = 0; pass < num_passes; pass++)
@@ -2939,10 +3311,10 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "GreenPhosphor", options->screen_green_phosphor_life);
(*d3dintf->effect.set_float)(curr_effect, "BluePhosphor", options->screen_blue_phosphor_life);
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
- (*d3dintf->effect.set_texture)(curr_effect, "LastPass", d3d->last_d3dtexture[cur_render_screen]);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? d3d->hlsltexture1[poly->texture->target_index] : d3d->hlsltexture2[poly->texture->target_index]);
+ (*d3dintf->effect.set_texture)(curr_effect, "LastPass", d3d->last_hlsltexture[poly->texture->target_index]);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsltarget0[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@@ -2965,10 +3337,10 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.set_float)(curr_effect, "FixedAlpha", 1.0f);
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
- (*d3dintf->effect.set_texture)(curr_effect, "LastPass", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? d3d->hlsltexture1[poly->texture->target_index] : d3d->hlsltexture2[poly->texture->target_index]);
+ (*d3dintf->effect.set_texture)(curr_effect, "LastPass", focus_enable ? d3d->hlsltexture1[poly->texture->target_index] : d3d->hlsltexture2[poly->texture->target_index]);
- result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->last_d3dtarget[cur_render_screen++]);
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->last_hlsltarget[poly->texture->target_index]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@@ -2986,13 +3358,62 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->effect.end)(curr_effect);
+ /* Scanlines and shadow mask, at high res for AVI logging*/
+ if(d3d->hlsl_avi_file != NULL)
+ {
+ curr_effect = d3d->post_effect;
+
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture0[poly->texture->target_index]);
+
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsl_avi_final_target);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+
+ (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ (*d3dintf->effect.begin_pass)(curr_effect, pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ (*d3dintf->effect.end_pass)(curr_effect);
+ }
+
+ (*d3dintf->effect.end)(curr_effect);
+ }
+
+ if(d3d->hlsl_render_snap)
+ {
+ curr_effect = d3d->post_effect;
+
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture0[poly->texture->target_index]);
+
+ result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->hlsl_snap_target);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+
+ (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ (*d3dintf->effect.begin_pass)(curr_effect, pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ (*d3dintf->effect.end_pass)(curr_effect);
+ }
+
+ (*d3dintf->effect.end)(curr_effect);
+
+ d3d->hlsl_snap_rendered = true;
+ }
+
/* Scanlines and shadow mask */
curr_effect = d3d->post_effect;
- (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0);
+ (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", d3d->hlsltexture0[poly->texture->target_index]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer);
- if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
@@ -3053,12 +3474,428 @@ static void primitive_flush_pending(d3d_info *d3d)
(*d3dintf->surface.release)(backbuffer);
}
+ // Unregister any registered targets we didn't traverse in the past frame. A resolution change must
+ // have occurred.
+ for(int index = 0; index < 9 && d3d->hlsl_enable && d3dintf->post_fx_available; index++)
+ {
+ if(!screen_encountered[index] && d3d->hlslsmalltarget0[index] != NULL)
+ {
+ if(d3d->target_use_count[index] > 0)
+ {
+ d3d->target_use_count[index]--;
+ }
+ else
+ {
+ // free all textures
+ if(d3d->target_in_use[index] != NULL)
+ {
+ texture_info *tex = d3d->target_in_use[index];
+ if(d3d->texlist == tex)
+ {
+ d3d->texlist = tex->next;
+ if(d3d->texlist != NULL)
+ {
+ d3d->texlist->prev = NULL;
+ }
+ }
+ else
+ {
+ if(tex->next != NULL)
+ {
+ tex->next->prev = tex->prev;
+ }
+ if(tex->prev != NULL)
+ {
+ tex->prev->next = tex->next;
+ }
+ }
+
+ if (tex->d3dfinaltex != NULL)
+ (*d3dintf->texture.release)(tex->d3dfinaltex);
+ if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex)
+ (*d3dintf->texture.release)(tex->d3dtex);
+ if (tex->d3dsurface != NULL)
+ (*d3dintf->surface.release)(tex->d3dsurface);
+ global_free(tex);
+ }
+
+ if (d3d->hlslprescaletexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlslprescaletexture0[index]);
+ d3d->hlslprescaletexture0[index] = NULL;
+ }
+ if (d3d->hlsltexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture0[index]);
+ d3d->hlsltexture0[index] = NULL;
+ }
+ if (d3d->hlsltexture1[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture1[index]);
+ d3d->hlsltexture1[index] = NULL;
+ }
+ if (d3d->hlsltexture2[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture2[index]);
+ d3d->hlsltexture2[index] = NULL;
+ }
+ if (d3d->hlsltexture3[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture3[index]);
+ d3d->hlsltexture3[index] = NULL;
+ }
+ if (d3d->hlsltexture4[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsltexture4[index]);
+ d3d->hlsltexture4[index] = NULL;
+ }
+ if (d3d->hlslsmalltexture0[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlslsmalltexture0[index]);
+ d3d->hlslsmalltexture0[index] = NULL;
+ }
+ if (d3d->hlslprescaletarget0[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlslprescaletarget0[index]);
+ d3d->hlslprescaletarget0[index] = NULL;
+ }
+ if (d3d->hlsltarget0[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget0[index]);
+ d3d->hlsltarget0[index] = NULL;
+ }
+ if (d3d->hlsltarget1[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget1[index]);
+ d3d->hlsltarget1[index] = NULL;
+ }
+ if (d3d->hlsltarget2[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget2[index]);
+ d3d->hlsltarget2[index] = NULL;
+ }
+ if (d3d->hlsltarget3[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget3[index]);
+ d3d->hlsltarget3[index] = NULL;
+ }
+ if (d3d->hlsltarget4[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsltarget4[index]);
+ d3d->hlsltarget4[index] = NULL;
+ }
+ if (d3d->hlslsmalltarget0[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlslsmalltarget0[index]);
+ d3d->hlslsmalltarget0[index] = NULL;
+ }
+ if(d3d->last_hlsltexture[index] != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->last_hlsltexture[index]);
+ d3d->last_hlsltexture[index] = NULL;
+ }
+ if(d3d->last_hlsltarget[index] != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->last_hlsltarget[index]);
+ d3d->last_hlsltarget[index] = NULL;
+ }
+ d3d->target_use_count[index] = 0;
+ }
+ }
+ }
+
// reset the vertex count
d3d->numverts = 0;
d3d->numpolys = 0;
}
+//============================================================
+// hlsl_avi_update_snap
+//============================================================
+
+static void hlsl_avi_update_snap(d3d_info *d3d, d3d_surface *surface)
+{
+ D3DLOCKED_RECT rect;
+
+ // if we don't have a bitmap, or if it's not the right size, allocate a new one
+ if (d3d->hlsl_avi_snap == NULL || (int)((float)d3d->width * d3d->oversample_x) != d3d->hlsl_avi_snap->width || (int)((float)d3d->height * d3d->oversample_y) != d3d->hlsl_avi_snap->height)
+ {
+ if (d3d->hlsl_avi_snap != NULL)
+ {
+ auto_free(d3d->window->machine(), d3d->hlsl_avi_snap);
+ }
+ d3d->hlsl_avi_snap = auto_alloc(d3d->window->machine(), bitmap_t((int)((float)d3d->width * d3d->oversample_x), (int)((float)d3d->height * d3d->oversample_y), BITMAP_FORMAT_RGB32));
+ }
+
+ // copy the texture
+ HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->device, surface, d3d->hlsl_avi_copy_surface);
+ if (result != D3D_OK)
+ {
+ printf("Couldn't copy (%08x)\n", (UINT32)result);
+ return;
+ }
+
+ // lock the texture
+ result = (*d3dintf->surface.lock_rect)(d3d->hlsl_avi_copy_surface, &rect, NULL, D3DLOCK_DISCARD);
+ if (result != D3D_OK)
+ {
+ printf("Couldn't lock (%08x)\n", (UINT32)result);
+ return;
+ }
+
+ // loop over Y
+ for (int srcy = 0; srcy < (int)((float)d3d->height * d3d->oversample_y); srcy++)
+ {
+ BYTE *src = (BYTE *)rect.pBits + srcy * rect.Pitch;
+ BYTE *dst = (BYTE *)d3d->hlsl_avi_snap->base + srcy * d3d->hlsl_avi_snap->rowpixels * 4;
+
+ for(int x = 0; x < (int)((float)d3d->width * d3d->oversample_x); x++)
+ {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ }
+ }
+
+ // unlock
+ result = (*d3dintf->surface.unlock_rect)(d3d->hlsl_avi_copy_surface);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
+}
+
+
+
+//============================================================
+// hlsl_render_snapshot
+//============================================================
+
+static void hlsl_render_snapshot(d3d_info *d3d, d3d_surface *surface)
+{
+ D3DLOCKED_RECT rect;
+
+ d3d->hlsl_render_snap = false;
+
+ // if we don't have a bitmap, or if it's not the right size, allocate a new one
+ if (d3d->hlsl_avi_snap == NULL || d3d->hlsl_snap_width != (d3d->hlsl_avi_snap->width / 2) || d3d->hlsl_snap_height != (d3d->hlsl_avi_snap->height / 2))
+ {
+ if (d3d->hlsl_avi_snap != NULL)
+ {
+ auto_free(d3d->window->machine(), d3d->hlsl_avi_snap);
+ }
+ d3d->hlsl_avi_snap = auto_alloc(d3d->window->machine(), bitmap_t(d3d->hlsl_snap_width / 2, d3d->hlsl_snap_height / 2, BITMAP_FORMAT_RGB32));
+ }
+
+ // copy the texture
+ HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->device, surface, d3d->hlsl_snap_copy_target);
+ if (result != D3D_OK)
+ {
+ printf("Couldn't copy (%08x)\n", (UINT32)result);
+ return;
+ }
+
+ // lock the texture
+ result = (*d3dintf->surface.lock_rect)(d3d->hlsl_snap_copy_target, &rect, NULL, D3DLOCK_DISCARD);
+ if (result != D3D_OK)
+ {
+ printf("Couldn't lock (%08x)\n", (UINT32)result);
+ return;
+ }
+
+ for(int cy = 0; cy < 2; cy++)
+ {
+ for(int cx = 0; cx < 2; cx++)
+ {
+ // loop over Y
+ for (int srcy = 0; srcy < d3d->hlsl_snap_height / 2; srcy++)
+ {
+ int toty = (srcy + cy * (d3d->hlsl_snap_height / 2));
+ int totx = cx * (d3d->hlsl_snap_width / 2);
+ BYTE *src = (BYTE *)rect.pBits + toty * rect.Pitch + totx * 4;
+ BYTE *dst = (BYTE *)d3d->hlsl_avi_snap->base + srcy * d3d->hlsl_avi_snap->rowpixels * 4;
+
+ for(int x = 0; x < d3d->hlsl_snap_width / 2; x++)
+ {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ }
+ }
+
+ int idx = cy * 2 + cx;
+
+ emu_file file(d3d->window->machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ file_error filerr = open_next(d3d, file, "png", idx);
+ if (filerr != FILERR_NONE)
+ return;
+
+ // add two text entries describing the image
+ astring text1(APPNAME, " ", build_version);
+ astring text2(d3d->window->machine().system().manufacturer, " ", d3d->window->machine().system().description);
+ png_info pnginfo = { 0 };
+ png_add_text(&pnginfo, "Software", text1);
+ png_add_text(&pnginfo, "System", text2);
+
+ // now do the actual work
+ png_error error = png_write_bitmap(file, &pnginfo, d3d->hlsl_avi_snap, 1 << 24, NULL);
+ if (error != PNGERR_NONE)
+ mame_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error);
+
+ // free any data allocated
+ png_free(&pnginfo);
+ }
+ }
+
+ // unlock
+ result = (*d3dintf->surface.unlock_rect)(d3d->hlsl_snap_copy_target);
+ if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
+
+ if(d3d->hlsl_snap_texture != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsl_snap_texture);
+ d3d->hlsl_snap_texture = NULL;
+ }
+
+ if(d3d->hlsl_snap_target != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsl_snap_target);
+ d3d->hlsl_snap_target = NULL;
+ }
+
+ if(d3d->hlsl_snap_copy_texture != NULL)
+ {
+ (*d3dintf->texture.release)(d3d->hlsl_snap_copy_texture);
+ d3d->hlsl_snap_copy_texture = NULL;
+ }
+
+ if(d3d->hlsl_snap_copy_target != NULL)
+ {
+ (*d3dintf->surface.release)(d3d->hlsl_snap_copy_target);
+ d3d->hlsl_snap_copy_target = NULL;
+ }
+}
+
+
+//============================================================
+// hlsl_record_texture
+//============================================================
+
+static void hlsl_record_texture(d3d_info *d3d, d3d_surface *surface)
+{
+ // ignore if nothing to do
+ if (d3d->hlsl_avi_file == NULL || surface == NULL)
+ {
+ return;
+ }
+
+ // get the current time
+ attotime curtime = d3d->window->machine().time();
+
+ hlsl_avi_update_snap(d3d, surface);
+
+ // loop until we hit the right time
+ while (d3d->hlsl_avi_next_frame_time <= curtime)
+ {
+ // handle an AVI recording
+ // write the next frame
+ avi_error avierr = avi_append_video_frame_rgb32(d3d->hlsl_avi_file, d3d->hlsl_avi_snap);
+ if (avierr != AVIERR_NONE)
+ {
+ end_hlsl_avi_recording(d3d);
+ return;
+ }
+
+ // advance time
+ d3d->hlsl_avi_next_frame_time += d3d->hlsl_avi_frame_period;
+ d3d->hlsl_avi_frame++;
+ }
+}
+
+
+//============================================================
+// end_hlsl_avi_recording
+//============================================================
+
+static void end_hlsl_avi_recording(d3d_info *d3d)
+{
+ if(d3d->hlsl_avi_file != NULL)
+ {
+ avi_close(d3d->hlsl_avi_file);
+ }
+ d3d->hlsl_avi_file = NULL;
+ d3d->hlsl_avi_frame = 0;
+}
+
+
+//============================================================
+// begin_hlsl_avi_recording
+//============================================================
+
+static void begin_hlsl_avi_recording(d3d_info *d3d, const char *name)
+{
+ // stop any existing recording
+ end_hlsl_avi_recording(d3d);
+
+ // reset the state
+ d3d->hlsl_avi_frame = 0;
+ d3d->hlsl_avi_next_frame_time = d3d->window->machine().time();
+
+ // build up information about this new movie
+ avi_movie_info info;
+ info.video_format = 0;
+ info.video_timescale = 1000 * ((d3d->window->machine().primary_screen != NULL) ? ATTOSECONDS_TO_HZ(d3d->window->machine().primary_screen->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE);
+ info.video_sampletime = 1000;
+ info.video_numsamples = 0;
+ info.video_width = d3d->width * d3d->oversample_x;
+ info.video_height = d3d->height * d3d->oversample_y;
+ info.video_depth = 24;
+
+ info.audio_format = 0;
+ info.audio_timescale = d3d->window->machine().sample_rate();
+ info.audio_sampletime = 1;
+ info.audio_numsamples = 0;
+ info.audio_channels = 2;
+ info.audio_samplebits = 16;
+ info.audio_samplerate = d3d->window->machine().sample_rate();
+
+ // create a new temporary movie file
+ file_error filerr;
+ astring fullpath;
+ {
+ emu_file tempfile(d3d->window->machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ if (name != NULL)
+ {
+ filerr = tempfile.open(name);
+ }
+ else
+ {
+ filerr = open_next(d3d, tempfile, "avi", 0);
+ }
+
+ // compute the frame time
+ {
+ d3d->hlsl_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
+ }
+
+ // if we succeeded, make a copy of the name and create the real file over top
+ if (filerr == FILERR_NONE)
+ {
+ fullpath = tempfile.fullpath();
+ }
+ }
+
+ if (filerr == FILERR_NONE)
+ {
+ // create the file and free the string
+ avi_error avierr = avi_create(fullpath, &info, &d3d->hlsl_avi_file);
+ if (avierr != AVIERR_NONE)
+ {
+ mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
+ }
+ }
+}
+
//============================================================
// texture_create
@@ -3082,9 +3919,6 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour
// compute the size
texture_compute_size(d3d, texsource->width, texsource->height, texture);
- d3d->oversample_x = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_x();
- d3d->oversample_y = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_y();
-
// non-screen textures are easy
if (!PRIMFLAG_GET_SCREENTEX(flags))
{
@@ -3143,42 +3977,56 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour
if(d3d->hlsl_enable && d3dintf->post_fx_available)
{
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture0);
+ int idx = d3d->registered_targets;
+
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture0[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture0, 0, &texture->d3dtarget0);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture0[idx], 0, &d3d->hlsltarget0[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_d3dtexture[d3d->registered_targets]);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_hlsltexture[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(d3d->last_d3dtexture[d3d->registered_targets], 0, &d3d->last_d3dtarget[d3d->registered_targets]);
+ (*d3dintf->texture.get_surface_level)(d3d->last_hlsltexture[idx], 0, &d3d->last_hlsltarget[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture1);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture1[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture1, 0, &texture->d3dtarget1);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture1[idx], 0, &d3d->hlsltarget1[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture2);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture2[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture2[idx], 0, &d3d->hlsltarget2[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture3);
+ result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture3[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture3, 0, &texture->d3dtarget3);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture3[idx], 0, &d3d->hlsltarget3[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture4);
+ result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture4[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture4, 0, &texture->d3dtarget4);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture4[idx], 0, &d3d->hlsltarget4[idx]);
+
+ int scale = 1;
+ if(d3d->hlsl_prescale) scale = d3d->hlsl_prescale_size;
- result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0);
+ result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * scale, texture->rawheight * scale, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlslsmalltexture0[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0);
+ (*d3dintf->texture.get_surface_level)(d3d->hlslsmalltexture0[idx], 0, &d3d->hlslsmalltarget0[idx]);
+ result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * scale, texture->rawheight * scale, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlslprescaletexture0[idx]);
+ if (result != D3D_OK)
+ goto error;
+ (*d3dintf->texture.get_surface_level)(d3d->hlslprescaletexture0[idx], 0, &d3d->hlslprescaletarget0[idx]);
+
+ texture->target_index = d3d->registered_targets;
+ d3d->target_use_count[texture->target_index] = 60;
+ d3d->target_in_use[texture->target_index] = texture;
d3d->registered_targets++;
+ d3d->registered_targets %= 9;
}
break;
@@ -3221,41 +4069,56 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour
{
if(d3d->hlsl_enable && d3dintf->post_fx_available)
{
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture0);
+ int idx = d3d->registered_targets;
+
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture0[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture0, 0, &texture->d3dtarget0);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture0[idx], 0, &d3d->hlsltarget0[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_d3dtexture[d3d->registered_targets]);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_hlsltexture[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(d3d->last_d3dtexture[d3d->registered_targets], 0, &d3d->last_d3dtarget[d3d->registered_targets]);
- d3d->registered_targets++;
+ (*d3dintf->texture.get_surface_level)(d3d->last_hlsltexture[idx], 0, &d3d->last_hlsltarget[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture1);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture1[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture1, 0, &texture->d3dtarget1);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture1[idx], 0, &d3d->hlsltarget1[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture2);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture2[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture2[idx], 0, &d3d->hlsltarget2[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture3);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture3[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture3, 0, &texture->d3dtarget3);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture3[idx], 0, &d3d->hlsltarget3[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture4);
+ result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlsltexture4[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dtexture4, 0, &texture->d3dtarget4);
+ (*d3dintf->texture.get_surface_level)(d3d->hlsltexture4[idx], 0, &d3d->hlsltarget4[idx]);
- result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0);
+ int scale = 1;
+ if(d3d->hlsl_prescale) scale = d3d->hlsl_prescale_size;
+
+ result = (*d3dintf->device.create_texture)(d3d->device, scwidth * scale, scheight * scale, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlslsmalltexture0[idx]);
+ if (result != D3D_OK)
+ goto error;
+ (*d3dintf->texture.get_surface_level)(d3d->hlslsmalltexture0[idx], 0, &d3d->hlslsmalltarget0[idx]);
+
+ result = (*d3dintf->device.create_texture)(d3d->device, scwidth * scale, scheight * scale, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->hlslprescaletexture0[idx]);
if (result != D3D_OK)
goto error;
- (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0);
+ (*d3dintf->texture.get_surface_level)(d3d->hlslprescaletexture0[idx], 0, &d3d->hlslprescaletarget0[idx]);
+
+ texture->target_index = d3d->registered_targets;
+ d3d->target_use_count[texture->target_index] = 60;
+ d3d->target_in_use[texture->target_index] = texture;
+ d3d->registered_targets++;
+ d3d->registered_targets %= 9;
}
break;
}
@@ -3269,6 +4132,9 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour
texture_set_data(d3d, texture, texsource, flags);
// add us to the texture list
+ if(d3d->texlist != NULL)
+ d3d->texlist->prev = texture;
+ texture->prev = NULL;
texture->next = d3d->texlist;
d3d->texlist = texture;
return texture;
@@ -4022,3 +4888,130 @@ static void texture_update(d3d_info *d3d, const render_primitive *prim)
texture->texinfo.seqid = prim->texture.seqid;
}
}
+
+
+// NOTE: The function below is taken directly from src/emu/video.c and should likely be moved into a global helper function.
+//-------------------------------------------------
+// open_next - open the next non-existing file of
+// type filetype according to our numbering
+// scheme
+//-------------------------------------------------
+
+static file_error open_next(d3d_info *d3d, emu_file &file, const char *extension, int idx)
+{
+ UINT32 origflags = file.openflags();
+
+ // handle defaults
+ const char *snapname = d3d->window->machine().options().snap_name();
+
+ if (snapname == NULL || snapname[0] == 0)
+ snapname = "%g/%i";
+ astring snapstr(snapname);
+
+ // strip any extension in the provided name
+ int index = snapstr.rchr(0, '.');
+ if (index != -1)
+ snapstr.substr(0, index);
+
+ // handle %d in the template (for image devices)
+ astring snapdev("%d_");
+ int pos = snapstr.find(0, snapdev);
+
+ if (pos != -1)
+ {
+ // if more %d are found, revert to default and ignore them all
+ if (snapstr.find(pos + 3, snapdev) != -1)
+ snapstr.cpy("%g/%i");
+ // else if there is a single %d, try to create the correct snapname
+ else
+ {
+ int name_found = 0;
+
+ // find length of the device name
+ int end1 = snapstr.find(pos + 3, "/");
+ int end2 = snapstr.find(pos + 3, "%");
+ int end = -1;
+
+ if ((end1 != -1) && (end2 != -1))
+ end = MIN(end1, end2);
+ else if (end1 != -1)
+ end = end1;
+ else if (end2 != -1)
+ end = end2;
+ else
+ end = snapstr.len();
+
+ if (end - pos < 3)
+ fatalerror("Something very wrong is going on!!!");
+
+ // copy the device name to an astring
+ astring snapdevname;
+ snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3);
+
+ // verify that there is such a device for this system
+ device_image_interface *image = NULL;
+ for (bool gotone = d3d->window->machine().devicelist().first(image); gotone; gotone = image->next(image))
+ {
+ // get the device name
+ astring tempdevname(image->brief_instance_name());
+
+ if (snapdevname.cmp(tempdevname) == 0)
+ {
+ // verify that such a device has an image mounted
+ if (image->basename() != NULL)
+ {
+ astring filename(image->basename());
+
+ // strip extension
+ filename.substr(0, filename.rchr(0, '.'));
+
+ // setup snapname and remove the %d_
+ snapstr.replace(0, snapdevname, filename);
+ snapstr.del(pos, 3);
+
+ name_found = 1;
+ }
+ }
+ }
+
+ // or fallback to default
+ if (name_found == 0)
+ snapstr.cpy("%g/%i");
+ }
+ }
+
+ // add our own index
+ // add our own extension
+ snapstr.cat(".").cat(extension);
+
+ // substitute path and gamename up front
+ snapstr.replace(0, "/", PATH_SEPARATOR);
+ snapstr.replace(0, "%g", d3d->window->machine().basename());
+
+ // determine if the template has an index; if not, we always use the same name
+ astring fname;
+ if (snapstr.find(0, "%i") == -1)
+ fname.cpy(snapstr);
+
+ // otherwise, we scan for the next available filename
+ else
+ {
+ // try until we succeed
+ astring seqtext;
+ file.set_openflags(OPEN_FLAG_READ);
+ for (int seq = 0; ; seq++)
+ {
+ // build up the filename
+ fname.cpy(snapstr).replace(0, "%i", seqtext.format("%04d_%d", seq, idx).cstr());
+
+ // try to open the file; stop when we fail
+ file_error filerr = file.open(fname);
+ if (filerr != FILERR_NONE)
+ break;
+ }
+ }
+
+ // create the final file
+ file.set_openflags(origflags);
+ return file.open(fname);
+}
diff --git a/src/osd/windows/drawdd.c b/src/osd/windows/drawdd.c
index d1ea6e481d2..dfab66a6830 100644
--- a/src/osd/windows/drawdd.c
+++ b/src/osd/windows/drawdd.c
@@ -251,6 +251,8 @@ int drawdd_init(running_machine &machine, win_draw_callbacks *callbacks)
callbacks->window_init = drawdd_window_init;
callbacks->window_get_primitives = drawdd_window_get_primitives;
callbacks->window_draw = drawdd_window_draw;
+ callbacks->window_save = NULL;
+ callbacks->window_record = NULL;
callbacks->window_destroy = drawdd_window_destroy;
mame_printf_verbose("DirectDraw: Using DirectDraw 7\n");
diff --git a/src/osd/windows/drawgdi.c b/src/osd/windows/drawgdi.c
index 7a7d8cbf1b0..2be9b026684 100644
--- a/src/osd/windows/drawgdi.c
+++ b/src/osd/windows/drawgdi.c
@@ -94,6 +94,8 @@ int drawgdi_init(running_machine &machine, win_draw_callbacks *callbacks)
callbacks->window_init = drawgdi_window_init;
callbacks->window_get_primitives = drawgdi_window_get_primitives;
callbacks->window_draw = drawgdi_window_draw;
+ callbacks->window_save = NULL;
+ callbacks->window_record = NULL;
callbacks->window_destroy = drawgdi_window_destroy;
return 0;
}
diff --git a/src/osd/windows/drawnone.c b/src/osd/windows/drawnone.c
index 89c119052a4..c82740f84ac 100644
--- a/src/osd/windows/drawnone.c
+++ b/src/osd/windows/drawnone.c
@@ -75,6 +75,8 @@ int drawnone_init(running_machine &machine, win_draw_callbacks *callbacks)
callbacks->window_init = drawnone_window_init;
callbacks->window_get_primitives = drawnone_window_get_primitives;
callbacks->window_draw = drawnone_window_draw;
+ callbacks->window_save = NULL;
+ callbacks->window_record = NULL;
callbacks->window_destroy = drawnone_window_destroy;
return 0;
}
diff --git a/src/osd/windows/input.c b/src/osd/windows/input.c
index 0b315aeecd6..512f95e9b08 100644
--- a/src/osd/windows/input.c
+++ b/src/osd/windows/input.c
@@ -781,6 +781,20 @@ void windows_osd_interface::customize_input_type_list(simple_list<input_type_ent
entry->name = "Toggle Fullscreen";
entry->defseq[SEQ_TYPE_STANDARD].set(KEYCODE_LALT, KEYCODE_ENTER);
break;
+
+ // alt-F12 for fullscreen snap
+ case IPT_OSD_2:
+ entry->token = "RENDER_SNAP";
+ entry->name = "Take Rendered Snapshot";
+ entry->defseq[SEQ_TYPE_STANDARD].set(KEYCODE_LALT, KEYCODE_F12);
+ break;
+
+ // alt-F11 for fullscreen video
+ case IPT_OSD_3:
+ entry->token = "RENDER_AVI";
+ entry->name = "Record Rendered Video";
+ entry->defseq[SEQ_TYPE_STANDARD].set(KEYCODE_LALT, KEYCODE_F11);
+ break;
}
}
diff --git a/src/osd/windows/video.c b/src/osd/windows/video.c
index cbe434f0c20..68b2f022a49 100644
--- a/src/osd/windows/video.c
+++ b/src/osd/windows/video.c
@@ -364,6 +364,14 @@ static void check_osd_inputs(running_machine &machine)
// check for toggling fullscreen mode
if (ui_input_pressed(machine, IPT_OSD_1))
winwindow_toggle_full_screen();
+
+ // check for taking fullscreen snap
+ if (ui_input_pressed(machine, IPT_OSD_2))
+ winwindow_take_snap();
+
+ // check for taking fullscreen video
+ if (ui_input_pressed(machine, IPT_OSD_3))
+ winwindow_take_video();
}
diff --git a/src/osd/windows/window.c b/src/osd/windows/window.c
index d92ee5d05e5..2fbacb8b780 100644
--- a/src/osd/windows/window.c
+++ b/src/osd/windows/window.c
@@ -499,6 +499,52 @@ void winwindow_dispatch_message(running_machine &machine, MSG *message)
//============================================================
+// winwindow_take_snap
+// (main thread)
+//============================================================
+
+void winwindow_take_snap(void)
+{
+ if (draw.window_record == NULL)
+ return;
+
+ win_window_info *window;
+
+ assert(GetCurrentThreadId() == main_threadid);
+
+ // iterate over windows and request a snap
+ for (window = win_window_list; window != NULL; window = window->next)
+ {
+ (*draw.window_save)(window);
+ }
+}
+
+
+
+//============================================================
+// winwindow_take_video
+// (main thread)
+//============================================================
+
+void winwindow_take_video(void)
+{
+ if (draw.window_record == NULL)
+ return;
+
+ win_window_info *window;
+
+ assert(GetCurrentThreadId() == main_threadid);
+
+ // iterate over windows and request a snap
+ for (window = win_window_list; window != NULL; window = window->next)
+ {
+ (*draw.window_record)(window);
+ }
+}
+
+
+
+//============================================================
// winwindow_toggle_full_screen
// (main thread)
//============================================================
diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h
index 13d76a6d54d..8b12c38f291 100644
--- a/src/osd/windows/window.h
+++ b/src/osd/windows/window.h
@@ -122,6 +122,8 @@ struct _win_draw_callbacks
int (*window_init)(win_window_info *window);
render_primitive_list *(*window_get_primitives)(win_window_info *window);
int (*window_draw)(win_window_info *window, HDC dc, int update);
+ void (*window_save)(win_window_info *window);
+ void (*window_record)(win_window_info *window);
void (*window_destroy)(win_window_info *window);
};
@@ -155,6 +157,8 @@ LRESULT CALLBACK winwindow_video_window_proc(HWND wnd, UINT message, WPARAM wpar
extern LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
void winwindow_toggle_full_screen(void);
+void winwindow_take_snap(void);
+void winwindow_take_video(void);
void winwindow_process_events_periodic(running_machine &machine);
void winwindow_process_events(running_machine &machine, int ingame);
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index e78d1aa57d2..c1e75aa3d1a 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -328,9 +328,15 @@ const options_entry windows_options::s_option_entries[] =
// post-processing options
{ NULL, NULL, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" },
- { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enable HLSL post-processing (PS3.0 required)" },
- { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" },
- { WINOPTION_SHADOW_MASK_ALPHA";fs_shadwa(0.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask alpha-blend value (1.0 is fully blended, 0.0 is no mask)" },
+ { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enable HLSL post-processing (PS3.0 required)" },
+ { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" },
+ { WINOPTION_HLSL_PRESCALE";hlsl_prescale", "0", OPTION_BOOLEAN, "enable HLSL scaling pre-pass (for 'x' filters)" },
+ { WINOPTION_HLSL_PRESCALE_SIZE, "2", OPTION_INTEGER, "HLSL scaling pre-pass factor (usually 2 or 3)" },
+ { WINOPTION_HLSL_PRESET";(-1-5)", "-1", OPTION_INTEGER, "HLSL preset to use (0-5)" },
+ { WINOPTION_HLSL_WRITE, NULL, OPTION_STRING, "enable HLSL AVI writing (huge disk bandwidth suggested)" },
+ { WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" },
+ { WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
+ { WINOPTION_SHADOW_MASK_ALPHA";fs_shadwa(0.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask alpha-blend value (1.0 is fully blended, 0.0 is no mask)" },
{ WINOPTION_SHADOW_MASK_TEXTURE";fs_shadwt(0.0-1.0)", "aperture.png", OPTION_STRING, "shadow mask texture name" },
{ WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "640", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
{ WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "480", OPTION_INTEGER, "shadow mask height, in phosphor dots" },
@@ -345,6 +351,7 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_PINCUSHION";fs_pin(0.0-4.0)", "0.0", OPTION_FLOAT, "pincushion amount" },
{ 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)", "0.5", OPTION_FLOAT, "individual height scaling value for scanlines" },
{ WINOPTION_SCANLINE_BRIGHT_SCALE";fs_scanbs(0.0-1.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" },
{ WINOPTION_SCANLINE_BRIGHT_OFFSET";fs_scanbo(0.0-1.0)", "0.6", 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" },
@@ -396,12 +403,16 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_BLUE_PHOSPHOR";fs_grnpho(0.0-1.0)", "0.0", OPTION_FLOAT, "blue phosphorescence decay rate (0.0 is instant, 1.0 is forever)" },
/* NTSC simulation below this line */
{ WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enable YIQ-space HLSL post-processing" },
- { WINOPTION_YIQ_WVALUE";yiqw", "4.1187867", OPTION_FLOAT, "W value for YIQ signal processing" },
- { WINOPTION_YIQ_AVALUE";yiqa", "0.5", OPTION_FLOAT, "A value for YIQ signal processing" },
- { WINOPTION_YIQ_BVALUE";yiqb", "0.5", OPTION_FLOAT, "B value for YIQ signal processing" },
- { WINOPTION_YIQ_FSCVALUE";yiqfsc", "1.5", OPTION_FLOAT, "Fsc value for YIQ signal processing" },
- { WINOPTION_YIQ_FSCSCALE";yiqfscs", "1.0", OPTION_FLOAT, "Incoming Fsc scaling value for YIQ signal processing" },
- { WINOPTION_YIQ_PHASE_COUNT";yiqp", "2", OPTION_INTEGER, "Phase Count value for YIQ signal processing" },
+ { WINOPTION_YIQ_CCVALUE";yiqcc", "3.59754545",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", "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_YVALUE";yiqy", "3.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
+ { WINOPTION_YIQ_IVALUE";yiqi", "1.2", OPTION_FLOAT, "I filter cutoff frequency for NTSC signal processing" },
+ { WINOPTION_YIQ_QVALUE";yiqq", "0.6", OPTION_FLOAT, "Q filter cutoff frequency for NTSC signal processing" },
+ { WINOPTION_YIQ_SCAN_TIME";yiqsc", "52.6", OPTION_FLOAT, "Horizontal scanline duration for NTSC signal processing (in usec)" },
+ { WINOPTION_YIQ_PHASE_COUNT";yiqp", "2", OPTION_INTEGER, "Phase Count value for NTSC signal processing" },
// per-window options
{ NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" },
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index 456f6e5c3fc..0040ff91c29 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -81,6 +81,12 @@
// core post-processing options
#define WINOPTION_HLSL_ENABLE "hlsl_enable"
#define WINOPTION_HLSLPATH "hlslpath"
+#define WINOPTION_HLSL_PRESCALE "hlsl_prescale"
+#define WINOPTION_HLSL_PRESCALE_SIZE "hlsl_prescale_size"
+#define WINOPTION_HLSL_PRESET "hlsl_preset"
+#define WINOPTION_HLSL_WRITE "hlsl_write"
+#define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width"
+#define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height"
#define WINOPTION_SHADOW_MASK_ALPHA "shadow_mask_alpha"
#define WINOPTION_SHADOW_MASK_TEXTURE "shadow_mask_texture"
#define WINOPTION_SHADOW_MASK_COUNT_X "shadow_mask_x_count"
@@ -95,6 +101,7 @@
#define WINOPTION_OVERSAMPLE_Y "oversample_y"
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size"
+#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"
@@ -138,11 +145,15 @@
#define WINOPTION_BLUE_PHOSPHOR "blue_phosphor_life"
#define WINOPTION_SATURATION "saturation"
#define WINOPTION_YIQ_ENABLE "yiq_enable"
-#define WINOPTION_YIQ_WVALUE "yiq_w"
+#define WINOPTION_YIQ_CCVALUE "yiq_cc"
#define WINOPTION_YIQ_AVALUE "yiq_a"
#define WINOPTION_YIQ_BVALUE "yiq_b"
-#define WINOPTION_YIQ_FSCVALUE "yiq_fsc"
-#define WINOPTION_YIQ_FSCSCALE "yiq_fsc_scale"
+#define WINOPTION_YIQ_OVALUE "yiq_o"
+#define WINOPTION_YIQ_PVALUE "yiq_p"
+#define WINOPTION_YIQ_YVALUE "yiq_y"
+#define WINOPTION_YIQ_IVALUE "yiq_i"
+#define WINOPTION_YIQ_QVALUE "yiq_q"
+#define WINOPTION_YIQ_SCAN_TIME "yiq_scan_time"
#define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count"
// per-window options
@@ -210,16 +221,23 @@ public:
// core post-processing options
const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); }
bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); }
+ const char *d3d_hlsl_write() const { return value(WINOPTION_HLSL_WRITE); }
+ bool d3d_hlsl_prescale() const { return bool_value(WINOPTION_HLSL_PRESCALE); }
+ int d3d_hlsl_prescale_size() const { return int_value(WINOPTION_HLSL_PRESCALE_SIZE); }
+ int d3d_hlsl_preset() const { return int_value(WINOPTION_HLSL_PRESET); }
+ int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); }
+ int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); }
float screen_shadow_mask_alpha() const { return float_value(WINOPTION_SHADOW_MASK_ALPHA); }
const char *screen_shadow_mask_texture() const { return value(WINOPTION_SHADOW_MASK_TEXTURE); }
- float screen_shadow_mask_count_x() const { return float_value(WINOPTION_SHADOW_MASK_COUNT_X); }
- float screen_shadow_mask_count_y() const { return float_value(WINOPTION_SHADOW_MASK_COUNT_Y); }
+ int screen_shadow_mask_count_x() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_X); }
+ int screen_shadow_mask_count_y() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_Y); }
float screen_shadow_mask_u_size() const { return float_value(WINOPTION_SHADOW_MASK_USIZE); }
float screen_shadow_mask_v_size() const { return float_value(WINOPTION_SHADOW_MASK_VSIZE); }
float screen_oversample_x() const { return float_value(WINOPTION_OVERSAMPLE_X); }
float screen_oversample_y() const { return float_value(WINOPTION_OVERSAMPLE_Y); }
float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); }
float screen_scanline_scale() const { return float_value(WINOPTION_SCANLINE_SCALE); }
+ 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); }
@@ -251,11 +269,15 @@ public:
float screen_blue_from_green() const { return float_value(WINOPTION_BLUE_MATRIX_G); }
float screen_blue_from_blue() const { return float_value(WINOPTION_BLUE_MATRIX_B); }
bool screen_yiq_enable() const { return bool_value(WINOPTION_YIQ_ENABLE); }
- float screen_yiq_w() const { return float_value(WINOPTION_YIQ_WVALUE); }
+ 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); }
- float screen_yiq_fsc() const { return float_value(WINOPTION_YIQ_FSCVALUE); }
- float screen_yiq_fsc_scale() const { return float_value(WINOPTION_YIQ_FSCSCALE); }
+ float screen_yiq_o() const { return float_value(WINOPTION_YIQ_OVALUE); }
+ float screen_yiq_p() const { return float_value(WINOPTION_YIQ_PVALUE); }
+ float screen_yiq_y() const { return float_value(WINOPTION_YIQ_YVALUE); }
+ float screen_yiq_i() const { return float_value(WINOPTION_YIQ_IVALUE); }
+ float screen_yiq_q() const { return float_value(WINOPTION_YIQ_QVALUE); }
+ float screen_yiq_scan_time() const { return float_value(WINOPTION_YIQ_SCAN_TIME); }
int screen_yiq_phase_count() const { return int_value(WINOPTION_YIQ_PHASE_COUNT); }
float screen_red_offset() const { return float_value(WINOPTION_RED_OFFSET); }
float screen_green_offset() const { return float_value(WINOPTION_GREEN_OFFSET); }