Skip to content
This repository was archived by the owner on Sep 18, 2021. It is now read-only.

Commit 818f002

Browse files
author
mooglyguy
committed
HLSL Updates: [Ryan Holtz, Bat Country Entertainment, austere]
- Reworked default shadow mask settings, eliminating rainbow banding and matching reference shots more closely - Moved color power to occur after shadow mask, as it is intended to simulate nonlinear phosphor response - Added a variable-width notch filter to the Y channel in NTSC post-processing, eliminating luma banding on e.g. CoCo 2 and Apple II
1 parent 14e48f2 commit 818f002

File tree

8 files changed

+71
-46
lines changed

8 files changed

+71
-46
lines changed

artwork/aperture.png

-34 Bytes
Loading

hlsl/color.fx

-8
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,6 @@ uniform float BluFloor = 0.0f;
100100

101101
uniform float Saturation = 1.0f;
102102

103-
uniform float RedPower = 2.2f;
104-
uniform float GrnPower = 2.2f;
105-
uniform float BluPower = 2.2f;
106-
107103
float4 ps_main(PS_INPUT Input) : COLOR
108104
{
109105
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
@@ -126,10 +122,6 @@ float4 ps_main(PS_INPUT Input) : COLOR
126122
float3 OutChroma = OutTexel - OutLuma;
127123
float3 Saturated = OutLuma + OutChroma * Saturation;
128124

129-
OutRGB.r = pow(Saturated.r, RedPower);
130-
OutRGB.g = pow(Saturated.g, GrnPower);
131-
OutRGB.b = pow(Saturated.b, BluPower);
132-
133125
return float4(OutRGB, BaseTexel.a);
134126
}
135127

hlsl/post.fx

+9-1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ uniform float BluFloor = 0.0f;
119119
uniform float SnapX = 0.0f;
120120
uniform float SnapY = 0.0f;
121121

122+
uniform float RedPower = 2.2f;
123+
uniform float GrnPower = 2.2f;
124+
uniform float BluPower = 2.2f;
125+
122126
float4 ps_main(PS_INPUT Input) : COLOR
123127
{
124128
float2 Ratios = float2(WidthRatio, HeightRatio);
@@ -174,13 +178,17 @@ float4 ps_main(PS_INPUT Input) : COLOR
174178
float2 ShadowDims = float2(ShadowWidth, ShadowHeight);
175179
float2 ShadowUV = float2(ShadowU, ShadowV);
176180
float2 ShadowMaskSize = float2(ShadowMaskSizeX, ShadowMaskSizeY);
177-
float2 ShadowFrac = frac(BaseCoord * ShadowMaskSize * 0.5f);
181+
float2 ShadowFrac = frac(BaseCoord * ShadowMaskSize);
178182
float2 ShadowCoord = ShadowFrac * ShadowUV + float2(1.5f / ShadowWidth, 1.5f / ShadowHeight);
179183
float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord).rgb, UseShadow);
180184

181185
// -- Final Pixel --
182186
float4 Output = float4(Scanned * lerp(1.0f, ShadowTexel, ShadowBrightness), BaseTexel.a) * Input.Color;
183187

188+
Output.r = pow(Output.r, RedPower);
189+
Output.g = pow(Output.g, GrnPower);
190+
Output.b = pow(Output.b, BluPower);
191+
184192
return Output;
185193
}
186194

hlsl/yiq_decode.fx

+15-7
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ uniform float PValue = 1.0f;
9191
uniform float OValue = 0.0f;
9292
uniform float ScanTime = 52.6f;
9393

94-
uniform float YFreqResponse = 3.0f;
94+
uniform float NotchHalfWidth = 1.0f;
95+
uniform float YFreqResponse = 6.0f;
9596
uniform float IFreqResponse = 1.2f;
9697
uniform float QFreqResponse = 0.6f;
9798

@@ -108,15 +109,17 @@ float4 ps_main(PS_INPUT Input) : COLOR
108109
float MaxC = 2.1183f;
109110
float MinC = -1.1183f;
110111
float CRange = MaxC - MinC;
111-
float Fc_y = YFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
112+
float Fc_y1 = (CCValue - NotchHalfWidth) * ScanTime / (RawWidth * 4.0f / WidthRatio);
113+
float Fc_y2 = (CCValue + NotchHalfWidth) * ScanTime / (RawWidth * 4.0f / WidthRatio);
114+
float Fc_y3 = YFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
112115
float Fc_i = IFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
113116
float Fc_q = QFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
114117
float PI = 3.1415926535897932384626433832795;
115118
float PI2 = 2.0f * PI;
116-
float PI2Length = PI2 / 42.0f;
119+
float PI2Length = PI2 / 82.0f;
117120
float4 NOffset = float4(0.0f, 1.0f, 2.0f, 3.0f);
118121
float W = PI2 * CCValue * ScanTime;
119-
for(float n = -21.0f; n < 22.0f; n += 4.0f)
122+
for(float n = -41.0f; n < 42.0f; n += 4.0f)
120123
{
121124
float4 n4 = n + NOffset;
122125
float4 CoordX = Input.Coord0.x + Input.Coord0.z * n4 * 0.25f;
@@ -125,9 +128,14 @@ float4 ps_main(PS_INPUT Input) : COLOR
125128
float4 C = tex2D(CompositeSampler, TexCoord + float2(0.625f, 0.4f) / RawDims) * CRange + MinC;
126129
float4 WT = W * (CoordX * WidthRatio + AValue * CoordY * 2.0f * (RawHeight / HeightRatio) + BValue) + OValue;
127130

128-
float4 SincYIn = PI2 * Fc_y * n4;
129-
float4 IdealY = 2.0f * Fc_y * ((SincYIn != 0.0f) ? (sin(SincYIn) / SincYIn) : 1.0f);
130-
float4 FilterY = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealY;
131+
float4 SincYIn1 = PI2 * Fc_y1 * n4;
132+
float4 SincYIn2 = PI2 * Fc_y2 * n4;
133+
float4 SincYIn3 = PI2 * Fc_y3 * n4;
134+
float4 SincY1 = ((SincYIn1 != 0.0f) ? (sin(SincYIn1) / SincYIn1) : 1.0f);
135+
float4 SincY2 = ((SincYIn2 != 0.0f) ? (sin(SincYIn2) / SincYIn2) : 1.0f);
136+
float4 SincY3 = ((SincYIn3 != 0.0f) ? (sin(SincYIn3) / SincYIn3) : 1.0f);
137+
float4 IdealY = (2.0f * Fc_y1 * SincY1 - 2.0f * Fc_y2 * SincY2) + 2.0f * Fc_y3 * SincY3;
138+
float4 FilterY = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealY;
131139

132140
float4 SincIIn = PI2 * Fc_i * n4;
133141
float4 IdealI = 2.0f * Fc_i * ((SincIIn != 0.0f) ? (sin(SincIIn) / SincIIn) : 1.0f);

src/mess/video/apple2.c

+34-22
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
226226
int row, col, b;
227227
int offset;
228228
int columns;
229-
UINT8 vram_row[82];
229+
UINT8 vram_row[81];
230230
UINT16 v;
231231
UINT16 *p;
232232
UINT32 w;
@@ -245,7 +245,7 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
245245
columns = ((effective_a2(state) & (VAR_DHIRES|VAR_80COL)) == (VAR_DHIRES|VAR_80COL)) ? 80 : 40;
246246

247247
vram_row[0] = 0;
248-
vram_row[columns + 1] = 0;
248+
vram_row[columns] = 0;
249249

250250
for (row = beginrow; row <= endrow; row++)
251251
{
@@ -256,12 +256,12 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
256256
switch(columns)
257257
{
258258
case 40:
259-
vram_row[1+col] = vram[offset];
259+
vram_row[col] = vram[offset];
260260
break;
261261

262262
case 80:
263-
vram_row[1+(col*2)+0] = vram[offset + 0x10000];
264-
vram_row[1+(col*2)+1] = vram[offset + 0x00000];
263+
vram_row[(col*2)+0] = vram[offset + 0x10000];
264+
vram_row[(col*2)+1] = vram[offset + 0x00000];
265265
break;
266266

267267
default:
@@ -271,6 +271,8 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
271271
}
272272

273273
p = BITMAP_ADDR16(bitmap, row, 0);
274+
bool artifacting = false;
275+
int x = 0;
274276

275277
for (col = 0; col < columns; col++)
276278
{
@@ -281,6 +283,7 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
281283
switch(columns)
282284
{
283285
case 40:
286+
{
284287
w = vram_row[col+0];
285288
artifact_idx = 0;
286289
for (b = 0; b < 7; b++)
@@ -291,33 +294,42 @@ static void apple2_hires_draw(running_machine &machine, bitmap_t *bitmap, const
291294
artifact_buf[artifact_idx++] = v ? WHITE : BLACK;
292295
}
293296

294-
for(int a = 0; a < 14; a++)
295-
{
296-
int idx = a + (14 - (vram_row[col+0] >> 7));
297-
idx %= 14;
298-
*(p++) = artifact_buf[idx];
299-
}
300-
break;
297+
int start = 0;
301298

302-
case 80:
303-
if (state->m_monochrome_dhr)
299+
if (vram_row[col] & 0x80)
304300
{
305-
for (b = 0; b < 7; b++)
301+
if (x < 560)
306302
{
307-
v = (w & 1);
308-
w >>= 1;
309-
*(p++) = v ? WHITE : BLACK;
303+
UINT16 last = *(p - 1);
304+
*(p++) = last;
305+
x++;
310306
}
307+
artifacting = true;
308+
start = 1;
311309
}
312-
else
310+
311+
for(int a = 0; a < 14 - start; a++)
313312
{
314-
for (b = 0; b < 7; b++)
313+
if(x < 560)
315314
{
316-
v = state->m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F];
317-
*(p++) = v;
315+
*(p++) = artifact_buf[a];
316+
x++;
318317
}
319318
}
320319
break;
320+
}
321+
322+
case 80:
323+
{
324+
w = vram_row[col+0];
325+
for (b = 0; b < 7; b++)
326+
{
327+
v = (w & 1);
328+
w >>= 1;
329+
*(p++) = v ? WHITE : BLACK;
330+
}
331+
break;
332+
}
321333

322334
default:
323335
fatalerror("Invalid column count");

src/osd/windows/d3dhlsl.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,9 @@ void hlsl_info::init_effect_info(d3d_poly_info *poly)
10161016
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightScale", options->scanline_bright_scale);
10171017
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightOffset", options->scanline_bright_offset);
10181018
(*d3dintf->effect.set_float)(curr_effect, "ScanlineOffset", (poly->texture->cur_frame == 0) ? 0.0f : options->scanline_offset);
1019+
(*d3dintf->effect.set_float)(curr_effect, "RedPower", options->red_power);
1020+
(*d3dintf->effect.set_float)(curr_effect, "GrnPower", options->green_power);
1021+
(*d3dintf->effect.set_float)(curr_effect, "BluPower", options->blue_power);
10191022
}
10201023
else
10211024
{
@@ -1062,6 +1065,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
10621065
(*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
10631066
(*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
10641067
(*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
1068+
(*d3dintf->effect.set_float)(curr_effect, "NotchHalfWidth", winoptions.screen_yiq_n());
10651069
(*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
10661070
(*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
10671071
(*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
@@ -1102,6 +1106,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
11021106
(*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
11031107
(*d3dintf->effect.set_float)(curr_effect, "OValue", winoptions.screen_yiq_o());
11041108
(*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
1109+
(*d3dintf->effect.set_float)(curr_effect, "NotchHalfWidth", winoptions.screen_yiq_n());
11051110
(*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
11061111
(*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
11071112
(*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
@@ -1156,9 +1161,6 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
11561161
(*d3dintf->effect.set_float)(curr_effect, "RedScale", options->red_scale);
11571162
(*d3dintf->effect.set_float)(curr_effect, "GrnScale", options->green_scale);
11581163
(*d3dintf->effect.set_float)(curr_effect, "BluScale", options->blue_scale);
1159-
(*d3dintf->effect.set_float)(curr_effect, "RedPower", options->red_power);
1160-
(*d3dintf->effect.set_float)(curr_effect, "GrnPower", options->green_power);
1161-
(*d3dintf->effect.set_float)(curr_effect, "BluPower", options->blue_power);
11621164
(*d3dintf->effect.set_float)(curr_effect, "Saturation", options->saturation);
11631165

11641166
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, smalltarget0[poly->texture->target_index]);

src/osd/windows/winmain.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ const options_entry windows_options::s_option_entries[] =
337337
{ WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
338338
{ 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)" },
339339
{ WINOPTION_SHADOW_MASK_TEXTURE";fs_shadwt(0.0-1.0)", "aperture.png", OPTION_STRING, "shadow mask texture name" },
340-
{ WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "640", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
341-
{ WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "480", OPTION_INTEGER, "shadow mask height, in phosphor dots" },
342-
{ WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in U direction" },
343-
{ WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in V direction" },
340+
{ WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "320", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
341+
{ WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "240", OPTION_INTEGER, "shadow mask height, in phosphor dots" },
342+
{ WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.09375", OPTION_FLOAT, "shadow mask texture size in U direction" },
343+
{ WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.109375", OPTION_FLOAT, "shadow mask texture size in V direction" },
344344
{ WINOPTION_CURVATURE";fs_curv(0.0-4.0)", "0.0", OPTION_FLOAT, "screen curvature amount" },
345345
{ WINOPTION_SCREEN_SCALE_TOP";fs_scalex(0.0-2.0)", "1.0", OPTION_FLOAT, "screen scale, top" },
346346
{ WINOPTION_SCREEN_SCALE_BOTTOM";fs_scaley(0.0-2.0)", "1.0", OPTION_FLOAT, "screen scale, bottom" },
@@ -405,7 +405,8 @@ const options_entry windows_options::s_option_entries[] =
405405
{ WINOPTION_YIQ_BVALUE";yiqb", "0.5", OPTION_FLOAT, "B value for NTSC signal processing" },
406406
{ WINOPTION_YIQ_OVALUE";yiqo", "0.0", OPTION_FLOAT, "Outgoing Color Carrier phase offset for NTSC signal processing" },
407407
{ WINOPTION_YIQ_PVALUE";yiqp", "1.0", OPTION_FLOAT, "Incoming Pixel Clock scaling value for NTSC signal processing" },
408-
{ WINOPTION_YIQ_YVALUE";yiqy", "3.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
408+
{ WINOPTION_YIQ_NVALUE";yiqn", "1.0", OPTION_FLOAT, "Y filter notch width for NTSC signal processing" },
409+
{ WINOPTION_YIQ_YVALUE";yiqy", "6.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
409410
{ WINOPTION_YIQ_IVALUE";yiqi", "1.2", OPTION_FLOAT, "I filter cutoff frequency for NTSC signal processing" },
410411
{ WINOPTION_YIQ_QVALUE";yiqq", "0.6", OPTION_FLOAT, "Q filter cutoff frequency for NTSC signal processing" },
411412
{ WINOPTION_YIQ_SCAN_TIME";yiqsc", "52.6", OPTION_FLOAT, "Horizontal scanline duration for NTSC signal processing (in usec)" },

src/osd/windows/winmain.h

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
#define WINOPTION_YIQ_BVALUE "yiq_b"
148148
#define WINOPTION_YIQ_OVALUE "yiq_o"
149149
#define WINOPTION_YIQ_PVALUE "yiq_p"
150+
#define WINOPTION_YIQ_NVALUE "yiq_n"
150151
#define WINOPTION_YIQ_YVALUE "yiq_y"
151152
#define WINOPTION_YIQ_IVALUE "yiq_i"
152153
#define WINOPTION_YIQ_QVALUE "yiq_q"
@@ -268,6 +269,7 @@ class windows_options : public cli_options
268269
float screen_yiq_b() const { return float_value(WINOPTION_YIQ_BVALUE); }
269270
float screen_yiq_o() const { return float_value(WINOPTION_YIQ_OVALUE); }
270271
float screen_yiq_p() const { return float_value(WINOPTION_YIQ_PVALUE); }
272+
float screen_yiq_n() const { return float_value(WINOPTION_YIQ_NVALUE); }
271273
float screen_yiq_y() const { return float_value(WINOPTION_YIQ_YVALUE); }
272274
float screen_yiq_i() const { return float_value(WINOPTION_YIQ_IVALUE); }
273275
float screen_yiq_q() const { return float_value(WINOPTION_YIQ_QVALUE); }

0 commit comments

Comments
 (0)