diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 9243c8c45..c84e16219 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -352,7 +352,6 @@ class ConcreteMachine: } } - void reset_all_keys(Inputs::Keyboard *) override { } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index a11b4f6da..9cf344462 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -530,7 +530,7 @@ template class Co } void set_display_type(Outputs::Display::DisplayType display_type) override { -// video_output_.set_display_type(display_type); + video_output_.set_display_type(display_type); } Configurable::SelectionSet get_accurate_selections() override { diff --git a/Machines/Oric/Video.cpp b/Machines/Oric/Video.cpp index f64fb35e1..0595b6673 100644 --- a/Machines/Oric/Video.cpp +++ b/Machines/Oric/Video.cpp @@ -21,37 +21,26 @@ namespace { const unsigned int PAL60Period = 262*64; } - -// crt_->set_rgb_sampling_function( -// "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" -// "{" -// "uint texValue = texture(sampler, coordinate).r;" -// "return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));" -// "}"); -// crt_->set_composite_sampling_function( -// "float composite_sample(usampler2D sampler, vec2 coordinate, float phase, float amplitude)" -// "{" -// "uint texValue = uint(dot(texture(sampler, coordinate).rg, uvec2(1, 256)));" -// "uint iPhase = uint((phase + 3.141592654 + 0.39269908175) * 2.0 / 3.141592654) & 3u;" -// "texValue = (texValue >> (4u*(3u - iPhase))) & 15u;" -// "return (float(texValue) - 4.0) / 20.0;" -// "}" -// ); - VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory), - crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::PhaseLinkedLuminance8), + crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red1Green1Blue1), v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition), counter_period_(PAL50Period) { - crt_.set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 1.0f / 8.0f); - - set_display_type(Outputs::Display::DisplayType::CompositeColour); crt_.set_visible_area(crt_.get_rect_for_area(54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f)); + crt_.set_phase_linked_luminance_offset(-1.0f / 8.0f); + display_type_ = Outputs::Display::DisplayType::RGB; } void VideoOutput::set_display_type(Outputs::Display::DisplayType display_type) { - display_type_ = display_type; - crt_.set_display_type(display_type); + if(display_type_ != display_type) { + display_type_ = display_type; + crt_.set_display_type(display_type); + crt_.set_input_data_type( + (display_type == Outputs::Display::DisplayType::RGB) ? + Outputs::Display::InputDataType::Red1Green1Blue1 : + Outputs::Display::InputDataType::PhaseLinkedLuminance8 + ); + } } void VideoOutput::set_scan_target(Outputs::Display::ScanTarget *scan_target) { diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index 1cdb67ed2..0cecfc47d 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -88,6 +88,16 @@ void CRT::set_display_type(Outputs::Display::DisplayType display_type) { scan_target_->set_modals(scan_target_modals_); } +void CRT::set_phase_linked_luminance_offset(float offset) { + scan_target_modals_.input_data_tweaks.phase_linked_luminance_offset = offset; + scan_target_->set_modals(scan_target_modals_); +} + +void CRT::set_input_data_type(Outputs::Display::InputDataType input_data_type) { + scan_target_modals_.input_data_type = input_data_type; + scan_target_->set_modals(scan_target_modals_); +} + void CRT::set_new_display_type(int cycles_per_line, Outputs::Display::Type displayType) { switch(displayType) { case Outputs::Display::Type::PAL50: diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index 1dcbc55f1..c0ecc6b0d 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -265,6 +265,12 @@ class CRT { /*! Sets the display type that will be nominated to the scan target. */ void set_display_type(Outputs::Display::DisplayType); + + /*! Sets the offset to apply to phase when using the PhaseLinkedLuminance8 input data type. */ + void set_phase_linked_luminance_offset(float); + + /*! Sets the input data type. */ + void set_input_data_type(Outputs::Display::InputDataType); }; } diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 48c81f668..b60f61cca 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -100,8 +100,6 @@ ScanTarget::~ScanTarget() { } void ScanTarget::set_modals(Modals modals) { - modals.display_type = DisplayType::CompositeColour; - modals_ = modals; const auto data_type_size = Outputs::Display::size_for_data_type(modals.input_data_type); @@ -213,6 +211,7 @@ void Outputs::Display::OpenGL::ScanTarget::set_uniforms(ShaderType type, Shader target.set_uniform("rowHeight", GLfloat(1.05f / modals_.expected_vertical_lines)); target.set_uniform("scale", GLfloat(modals_.output_scale.x), GLfloat(modals_.output_scale.y)); target.set_uniform("processingWidth", GLfloat(processing_width_) / 2048.0f); + target.set_uniform("phaseOffset", GLfloat(modals_.input_data_tweaks.phase_linked_luminance_offset)); } Outputs::Display::ScanTarget::Scan *ScanTarget::begin_scan() { diff --git a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp index b69961e47..261b6d94f 100644 --- a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp +++ b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp @@ -247,6 +247,7 @@ std::unique_ptr ScanTarget::input_shader(InputDataType input_data_type, "uniform mat3 lumaChromaToRGB;" "uniform mat3 rgbToLumaChroma;" "uniform usampler2D textureName;" + "uniform float phaseOffset;" "void main(void) {"; @@ -269,7 +270,7 @@ std::unique_ptr ScanTarget::input_shader(InputDataType input_data_type, case InputDataType::PhaseLinkedLuminance8: computed_display_type = DisplayType::CompositeMonochrome; fragment_shader += - "uint iPhase = uint(compositeAngle * 2.0 / 3.141592654) & 3u;" + "uint iPhase = uint((compositeAngle * 2.0 / 3.141592654) + phaseOffset*4.0) & 3u;" "fragColour = vec3(texture(textureName, textureCoordinate)[iPhase] / 255.0);"; break; diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index ed591c978..28c4c151e 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -142,6 +142,13 @@ struct ScanTarget { /// Describes the format of input data. InputDataType input_data_type; + struct InputDataTweaks { + /// If using the PhaseLinkedLuminance8 data type, this value provides an offset + /// to add to phase before indexing the supplied luminances. + float phase_linked_luminance_offset = 0.0f; + + } input_data_tweaks; + /// Describes the type of display that the data is being shown on. DisplayType display_type = DisplayType::SVideo; @@ -172,6 +179,9 @@ struct ScanTarget { /// Describes the usual gamma of the output device these scans would appear on. float intended_gamma = 2.2f; + /// Provides a brightness multiplier for the display output. + float brightness = 1.0f; + /// Specifies the range of values that will be output for x and y coordinates. struct { uint16_t x, y;