1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Causes the s-video path correctly to function.

This commit is contained in:
Thomas Harte 2018-03-30 18:24:18 -04:00
parent 163a61dd63
commit 912791d3d4
5 changed files with 35 additions and 11 deletions

View File

@ -65,6 +65,9 @@ template <class T> class MOS6560 {
"return vec2(yc.x, chroma);" "return vec2(yc.x, chroma);"
"}"); "}");
// default to s-video output
crt_->set_video_signal(Outputs::CRT::VideoSignal::SVideo);
// default to NTSC // default to NTSC
set_output_mode(OutputMode::NTSC); set_output_mode(OutputMode::NTSC);
} }

View File

@ -149,6 +149,8 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) {
"}"); "}");
display_type = Outputs::CRT::DisplayType::PAL50; display_type = Outputs::CRT::DisplayType::PAL50;
} }
crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite);
// line number of cycles in a line of video is one less than twice the number of clock cycles per line; the Atari // line number of cycles in a line of video is one less than twice the number of clock cycles per line; the Atari
// outputs 228 colour cycles of material per line when an NTSC line 227.5. Since all clock numbers will be doubled // outputs 228 colour cycles of material per line when an NTSC line 227.5. Since all clock numbers will be doubled
// later, cycles_per_line * 2 - 1 is therefore the real length of an NTSC line, even though we're going to supply // later, cycles_per_line * 2 - 1 is therefore the real length of an NTSC line, even though we're going to supply

View File

@ -159,7 +159,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// for s-video, there are two steps — it's like composite but skips separation // for s-video, there are two steps — it's like composite but skips separation
const RenderStage svideo_render_stages[] = { const RenderStage svideo_render_stages[] = {
{composite_input_shader_program_.get(), separated_texture_.get(), {0.0, 0.5, 0.5}}, {svideo_input_shader_program_.get(), separated_texture_.get(), {0.0, 0.5, 0.5}},
{composite_chrominance_filter_shader_program_.get(), filtered_texture_.get(), {0.0, 0.0, 0.0}}, {composite_chrominance_filter_shader_program_.get(), filtered_texture_.get(), {0.0, 0.0, 0.0}},
{nullptr, nullptr} {nullptr, nullptr}
}; };
@ -364,6 +364,11 @@ void OpenGLOutputBuilder::prepare_source_vertex_array() {
Shader::get_input_name(Shader::Input::PhaseTimeAndAmplitude), Shader::get_input_name(Shader::Input::PhaseTimeAndAmplitude),
3, GL_UNSIGNED_BYTE, GL_FALSE, SourceVertexSize, 3, GL_UNSIGNED_BYTE, GL_FALSE, SourceVertexSize,
(void *)SourceVertexOffsetOfPhaseTimeAndAmplitude, 1); (void *)SourceVertexOffsetOfPhaseTimeAndAmplitude, 1);
svideo_input_shader_program_->enable_vertex_attribute_with_pointer(
Shader::get_input_name(Shader::Input::InputStart),
2, GL_UNSIGNED_SHORT, GL_FALSE, SourceVertexSize,
(void *)SourceVertexOffsetOfInputStart, 1);
} }
} }
@ -444,6 +449,7 @@ void OpenGLOutputBuilder::set_colour_space_uniforms() {
if(composite_input_shader_program_) composite_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB); if(composite_input_shader_program_) composite_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB);
if(composite_separation_filter_program_) composite_separation_filter_program_->set_colour_conversion_matrices(fromRGB, toRGB); if(composite_separation_filter_program_) composite_separation_filter_program_->set_colour_conversion_matrices(fromRGB, toRGB);
if(composite_chrominance_filter_shader_program_) composite_chrominance_filter_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB); if(composite_chrominance_filter_shader_program_) composite_chrominance_filter_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB);
if(svideo_input_shader_program_) svideo_input_shader_program_->set_colour_conversion_matrices(fromRGB, toRGB);
} }
void OpenGLOutputBuilder::set_gamma() { void OpenGLOutputBuilder::set_gamma() {
@ -496,6 +502,10 @@ void OpenGLOutputBuilder::set_timing_uniforms() {
composite_input_shader_program_->set_width_scalers(1.0f, output_width); composite_input_shader_program_->set_width_scalers(1.0f, output_width);
composite_input_shader_program_->set_extension(0.0f); composite_input_shader_program_->set_extension(0.0f);
} }
if(svideo_input_shader_program_) {
svideo_input_shader_program_->set_width_scalers(1.0f, output_width);
svideo_input_shader_program_->set_extension(0.0f);
}
if(rgb_input_shader_program_) { if(rgb_input_shader_program_) {
rgb_input_shader_program_->set_width_scalers(1.0f, 1.0f); rgb_input_shader_program_->set_width_scalers(1.0f, 1.0f);
} }

View File

@ -124,12 +124,12 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_composite_source_sh
"out vec4 fragColour;" "out vec4 fragColour;"
"uniform usampler2D texID;"; "uniform usampler2D texID;"
<< composite_shader;
if(!composite_shader.size()) { if(composite_shader.empty()) {
std::ostringstream derived_composite_sample;
if(!svideo_shader.empty()) { if(!svideo_shader.empty()) {
derived_composite_sample << fragment_shader <<
svideo_shader << svideo_shader <<
"float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)"
"{" "{"
@ -137,7 +137,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_composite_source_sh
"return mix(svideoColour.x, svideoColour.y, amplitude);" "return mix(svideoColour.x, svideoColour.y, amplitude);"
"}"; "}";
} else { } else {
derived_composite_sample << fragment_shader <<
rgb_shader << rgb_shader <<
"uniform mat3 rgbToLumaChroma;" "uniform mat3 rgbToLumaChroma;"
"float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)"
@ -148,9 +148,6 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_composite_source_sh
"return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));" "return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));"
"}"; "}";
} }
fragment_shader << derived_composite_sample.str();
} else {
fragment_shader << composite_shader;
} }
fragment_shader << fragment_shader <<
@ -185,7 +182,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_svideo_source_shade
"vec3 rgbColour = clamp(rgb_sample(texID, coordinate, iCoordinate), vec3(0.0), vec3(1.0));" "vec3 rgbColour = clamp(rgb_sample(texID, coordinate, iCoordinate), vec3(0.0), vec3(1.0));"
"vec3 lumaChromaColour = rgbToLumaChroma * rgbColour;" "vec3 lumaChromaColour = rgbToLumaChroma * rgbColour;"
"vec2 quadrature = vec2(cos(phase), -sin(phase));" "vec2 quadrature = vec2(cos(phase), -sin(phase));"
"return vec2(lumaChromaColour, quadrature);" "return vec2(lumaChromaColour.x, 0.5 + dot(quadrature, lumaChromaColour.yz) * 0.5);"
"}"; "}";
} }
@ -193,7 +190,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_svideo_source_shade
"void main(void)" "void main(void)"
"{" "{"
"vec2 sample = svideo_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x);" "vec2 sample = svideo_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x);"
"vec2 quadrature = vec2(cos(phaseAndAmplitudeVarying.x), -sin(phaseAndAmplitudeVarying.x));" "vec2 quadrature = vec2(cos(phaseAndAmplitudeVarying.x), -sin(phaseAndAmplitudeVarying.x)) * 0.5 * phaseAndAmplitudeVarying.z;"
"fragColour = vec3(sample.x, vec2(0.5) + (sample.y * quadrature));" "fragColour = vec3(sample.x, vec2(0.5) + (sample.y * quadrature));"
"}"; "}";

View File

@ -46,6 +46,8 @@ public:
converting them to single-channel composite values using @c composite_shader if non-empty converting them to single-channel composite values using @c composite_shader if non-empty
or a reference composite conversion of @c svideo_shader (first preference) or or a reference composite conversion of @c svideo_shader (first preference) or
@c rgb_shader (second preference) otherwise. @c rgb_shader (second preference) otherwise.
[input format] => one-channel composite.
*/ */
static std::unique_ptr<IntermediateShader> make_composite_source_shader(const std::string &composite_shader, const std::string &svideo_shader, const std::string &rgb_shader); static std::unique_ptr<IntermediateShader> make_composite_source_shader(const std::string &composite_shader, const std::string &svideo_shader, const std::string &rgb_shader);
@ -53,28 +55,38 @@ public:
Constructs and returns an intermediate shader that will take runs from the inputPositions, Constructs and returns an intermediate shader that will take runs from the inputPositions,
converting them to two-channel svideo values using @c svideo_shader if non-empty converting them to two-channel svideo values using @c svideo_shader if non-empty
or a reference svideo conversion of @c rgb_shader otherwise. or a reference svideo conversion of @c rgb_shader otherwise.
[input format] => three-channel Y, noisy (m, n).
*/ */
static std::unique_ptr<IntermediateShader> make_svideo_source_shader(const std::string &svideo_shader, const std::string &rgb_shader); static std::unique_ptr<IntermediateShader> make_svideo_source_shader(const std::string &svideo_shader, const std::string &rgb_shader);
/*! /*!
Constructs and returns an intermediate shader that will take runs from the inputPositions, Constructs and returns an intermediate shader that will take runs from the inputPositions,
converting them to RGB values using @c rgb_shader. converting them to RGB values using @c rgb_shader.
[input format] => three-channel RGB.
*/ */
static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const std::string &rgb_shader); static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const std::string &rgb_shader);
/*! /*!
Constructs and returns an intermediate shader that will read composite samples from the R channel, Constructs and returns an intermediate shader that will read composite samples from the R channel,
filter then to obtain luminance, stored to R, and to separate out unfiltered chrominance, store to G and B. filter then to obtain luminance, stored to R, and to separate out unfiltered chrominance, store to G and B.
one-channel composite => three-channel Y, noisy (m, n).
*/ */
static std::unique_ptr<IntermediateShader> make_chroma_luma_separation_shader(); static std::unique_ptr<IntermediateShader> make_chroma_luma_separation_shader();
/*! /*!
Constructs and returns an intermediate shader that will pass R through unchanged while filtering G and B. Constructs and returns an intermediate shader that will pass R through unchanged while filtering G and B.
three-channel Y, noisy (m, n) => three-channel RGB.
*/ */
static std::unique_ptr<IntermediateShader> make_chroma_filter_shader(); static std::unique_ptr<IntermediateShader> make_chroma_filter_shader();
/*! /*!
Constructs and returns an intermediate shader that will filter R, G and B. Constructs and returns an intermediate shader that will filter R, G and B.
three-channel RGB => frequency-limited three-channel RGB.
*/ */
static std::unique_ptr<IntermediateShader> make_rgb_filter_shader(); static std::unique_ptr<IntermediateShader> make_rgb_filter_shader();