mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Treads water.
Difficult current question: why does the Atari 2600's display change colours as the display tries to achieve horizontal lock? Phase should be unchanged. Ergo something is amiss.
This commit is contained in:
parent
56c7bd242a
commit
7ca0362f23
@ -359,8 +359,9 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
#endif
|
||||
|
||||
// Build the composition pipeline if one is in use.
|
||||
const bool isSVideoOutput = modals.display_type == Outputs::Display::DisplayType::SVideo;
|
||||
if(_isUsingCompositionPipeline) {
|
||||
const bool isSVideoOutput = modals.display_type == Outputs::Display::DisplayType::SVideo;
|
||||
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = _compositionTexture.pixelFormat;
|
||||
pipelineDescriptor.vertexFunction = [library newFunctionWithName:@"scanToComposition"];
|
||||
pipelineDescriptor.fragmentFunction =
|
||||
@ -374,7 +375,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
_compositionRenderPass.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
_compositionRenderPass.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.5, 0.5, 1.0);
|
||||
|
||||
simd::float3 *const firCoefficients = uniforms()->firCoefficients;
|
||||
auto *const firCoefficients = uniforms()->firCoefficients;
|
||||
const float cyclesPerLine = float(modals.cycles_per_line);
|
||||
const float colourCyclesPerLine = float(modals.colour_cycle_numerator) / float(modals.colour_cycle_denominator);
|
||||
|
||||
@ -386,7 +387,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
firCoefficients[7].x = 1.0f;
|
||||
} else {
|
||||
// In composite, filter luminance gently.
|
||||
SignalProcessing::FIRFilter luminancefilter(15, cyclesPerLine, 0.0f, colourCyclesPerLine * 0.75f);
|
||||
SignalProcessing::FIRFilter luminancefilter(15, cyclesPerLine, 0.0f, colourCyclesPerLine * 0.5f);
|
||||
const auto calculatedCoefficients = luminancefilter.get_coefficients();
|
||||
for(size_t c = 0; c < 8; ++c) {
|
||||
firCoefficients[c].x = calculatedCoefficients[c];
|
||||
@ -394,7 +395,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
}
|
||||
|
||||
// Whether S-Video or composite, apply the same relatively strong filter to colour channels.
|
||||
SignalProcessing::FIRFilter chrominancefilter(15, cyclesPerLine, 0.0f, colourCyclesPerLine * 0.33f);
|
||||
SignalProcessing::FIRFilter chrominancefilter(15, cyclesPerLine, 0.0f, colourCyclesPerLine * 0.5f);
|
||||
const auto calculatedCoefficients = chrominancefilter.get_coefficients();
|
||||
for(size_t c = 0; c < 8; ++c) {
|
||||
firCoefficients[c].y = firCoefficients[c].z = calculatedCoefficients[c];
|
||||
|
@ -123,23 +123,23 @@ template <typename Input> SourceInterpolator toDisplay(
|
||||
float(inputs[instanceID].endPoints[0].compositeAngle),
|
||||
float(inputs[instanceID].endPoints[1].compositeAngle),
|
||||
float((vertexID&2) >> 1)
|
||||
) / 32.0;
|
||||
) / 32.0f;
|
||||
|
||||
// Hence determine this quad's real shape, using vertexID to pick a corner.
|
||||
|
||||
// position2d is now in the range [0, 1].
|
||||
float2 position2d = start + (float(vertexID&2) * 0.5) * tangent + (float(vertexID&1) - 0.5) * normal * uniforms.lineWidth;
|
||||
float2 position2d = start + (float(vertexID&2) * 0.5f) * tangent + (float(vertexID&1) - 0.5f) * normal * uniforms.lineWidth;
|
||||
|
||||
// Apply the requested offset and zoom, to map the desired area to the range [0, 1].
|
||||
position2d = (position2d + uniforms.offset) * uniforms.zoom;
|
||||
|
||||
// Remap from [0, 1] to Metal's [-1, 1] and then apply the aspect ratio correction.
|
||||
position2d = (position2d * float2(2.0, -2.0) + float2(-1.0, 1.0)) * float2(uniforms.aspectRatioMultiplier, 1.0);
|
||||
position2d = (position2d * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f)) * float2(uniforms.aspectRatioMultiplier, 1.0f);
|
||||
|
||||
output.position = float4(
|
||||
position2d,
|
||||
0.0,
|
||||
1.0
|
||||
0.0f,
|
||||
1.0f
|
||||
);
|
||||
output.textureCoordinates = textureLocation(&inputs[instanceID], float((vertexID&2) >> 1));
|
||||
|
||||
@ -175,14 +175,14 @@ vertex SourceInterpolator scanToComposition( constant Uniforms &uniforms [[buffe
|
||||
// Populate result as if direct texture access were available.
|
||||
result.position.x = mix(scans[instanceID].endPoints[0].cyclesSinceRetrace, scans[instanceID].endPoints[1].cyclesSinceRetrace, float(vertexID));
|
||||
result.position.y = scans[instanceID].line;
|
||||
result.position.zw = float2(0.0, 1.0);
|
||||
result.position.zw = float2(0.0f, 1.0f);
|
||||
result.textureCoordinates.x = mix(scans[instanceID].endPoints[0].dataOffset, scans[instanceID].endPoints[1].dataOffset, float(vertexID));
|
||||
result.textureCoordinates.y = scans[instanceID].dataY;
|
||||
result.colourPhase = 3.141592654f * mix(
|
||||
float(scans[instanceID].endPoints[0].compositeAngle),
|
||||
float(scans[instanceID].endPoints[1].compositeAngle),
|
||||
float(vertexID)
|
||||
) / 32.0;
|
||||
) / 32.0f;
|
||||
result.colourAmplitude = float(scans[instanceID].compositeAmplitude) / 255.0f;
|
||||
|
||||
// Map position into eye space, allowing for target texture dimensions.
|
||||
@ -221,7 +221,13 @@ fragment float4 compositeSampleLuminance8Phase8(SourceInterpolator vert [[stage_
|
||||
const auto luminancePhase = texture.sample(standardSampler, vert.textureCoordinates).rg;
|
||||
const float phaseOffset = 3.141592654 * 4.0 * luminancePhase.g;
|
||||
const float rawChroma = step(luminancePhase.g, 0.75) * cos(vert.colourPhase + phaseOffset);
|
||||
return float4(float3(mix(luminancePhase.r, rawChroma, vert.colourAmplitude)), 1.0f);
|
||||
const float level = mix(luminancePhase.r, rawChroma, vert.colourAmplitude);
|
||||
return float4(
|
||||
level,
|
||||
0.5 + 0.5*level*cos(vert.colourPhase),
|
||||
0.5 + 0.5*level*sin(vert.colourPhase),
|
||||
1.0
|
||||
);
|
||||
}
|
||||
|
||||
// All the RGB formats can produce RGB, composite or S-Video.
|
||||
@ -258,10 +264,10 @@ float3 convertRed1Green1Blue1(SourceInterpolator vert, texture2d<ushort> texture
|
||||
\
|
||||
fragment float4 svideoSample##name(SourceInterpolator vert [[stage_in]], texture2d<pixelType> texture [[texture(0)]], constant Uniforms &uniforms [[buffer(0)]]) { \
|
||||
const auto colour = uniforms.fromRGB * convert##name(vert, texture); \
|
||||
const float2 colourSubcarrier = float2(sin(vert.colourPhase), cos(vert.colourPhase))*0.5 + float2(0.5); \
|
||||
const float2 colourSubcarrier = float2(cos(vert.colourPhase), sin(vert.colourPhase)); \
|
||||
return float4( \
|
||||
colour.r, \
|
||||
dot(colour.gb, colourSubcarrier), \
|
||||
dot(colour.gb, colourSubcarrier)*0.5 + 0.5, \
|
||||
0.0, \
|
||||
1.0 \
|
||||
); \
|
||||
@ -269,12 +275,12 @@ float3 convertRed1Green1Blue1(SourceInterpolator vert, texture2d<ushort> texture
|
||||
\
|
||||
fragment float4 compositeSample##name(SourceInterpolator vert [[stage_in]], texture2d<pixelType> texture [[texture(0)]], constant Uniforms &uniforms [[buffer(0)]]) { \
|
||||
const auto colour = uniforms.fromRGB * convert##name(vert, texture); \
|
||||
const float2 colourSubcarrier = float2(sin(vert.colourPhase), cos(vert.colourPhase)); \
|
||||
const float2 colourSubcarrier = float2(cos(vert.colourPhase), sin(vert.colourPhase)); \
|
||||
const float level = mix(colour.r, dot(colour.gb, colourSubcarrier), vert.colourAmplitude); \
|
||||
return float4( \
|
||||
level, \
|
||||
0.5 + 0.5*level*sin(vert.colourPhase),\
|
||||
0.5 + 0.5*level*cos(vert.colourPhase),\
|
||||
0.5 + 0.5*level*sin(vert.colourPhase),\
|
||||
1.0 \
|
||||
); \
|
||||
}
|
||||
@ -322,7 +328,7 @@ fragment float4 clearFragment() {
|
||||
// MARK: - Conversion fragment shaders
|
||||
|
||||
fragment float4 filterFragment(SourceInterpolator vert [[stage_in]], texture2d<float> texture [[texture(0)]], constant Uniforms &uniforms [[buffer(0)]]) {
|
||||
#define Sample(x) texture.sample(standardSampler, vert.textureCoordinates + float2(x, 0.0)).rgb
|
||||
#define Sample(x) texture.sample(standardSampler, vert.textureCoordinates + float2(x, 0.0f)).rgb
|
||||
const float3 rawSamples[] = {
|
||||
Sample(-7), Sample(-6), Sample(-5), Sample(-4), Sample(-3), Sample(-2), Sample(-1),
|
||||
Sample(0),
|
||||
@ -342,5 +348,5 @@ fragment float4 filterFragment(SourceInterpolator vert [[stage_in]], texture2d<f
|
||||
|
||||
#undef Sample
|
||||
|
||||
return float4(uniforms.toRGB * ((colour - float3(0.0, 0.5, 0.5)) * float3(1.0, 2.0 / vert.colourAmplitude, 2.0 / vert.colourAmplitude)), 1.0);
|
||||
return float4(uniforms.toRGB * ((colour - float3(0.0f, 0.5f, 0.5f)) * float3(1.0f, 2.0f / vert.colourAmplitude, 2.0f / vert.colourAmplitude)), 1.0f);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user