diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index 48999b4ca..9a19d9369 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -219,14 +219,6 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_ // Announce horizontal retrace events. if(next_run_length == time_until_horizontal_sync_event && next_horizontal_sync_event != Flywheel::SyncEvent::None) { - const auto event = - (next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace) - ? Outputs::Display::ScanTarget::Event::BeginHorizontalRetrace : Outputs::Display::ScanTarget::Event::EndHorizontalRetrace; - scan_target_->announce( - event, - !(horizontal_flywheel_->is_in_retrace() || vertical_flywheel_->is_in_retrace()), - end_point(uint16_t((total_cycles - number_of_cycles) * number_of_samples / total_cycles))); - // Prepare for the next line. if(next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace) { is_alernate_line_ ^= phase_alternates_; @@ -234,6 +226,15 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_ } else { cycles_since_horizontal_sync_ = 0; } + + // Announce event. + const auto event = + (next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace) + ? Outputs::Display::ScanTarget::Event::BeginHorizontalRetrace : Outputs::Display::ScanTarget::Event::EndHorizontalRetrace; + scan_target_->announce( + event, + !(horizontal_flywheel_->is_in_retrace() || vertical_flywheel_->is_in_retrace()), + end_point(uint16_t((total_cycles - number_of_cycles) * number_of_samples / total_cycles))); } // Also announce vertical retrace events. diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 0eab6bff8..932f91f8d 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -257,12 +257,14 @@ void ScanTarget::announce(Event event, bool is_visible, const Outputs::Display:: if(active_line_) { active_line_->end_points[0].x = location.x; active_line_->end_points[0].y = location.y; + active_line_->end_points[0].cycles_since_end_of_horizontal_retrace = location.cycles_since_end_of_horizontal_retrace; active_line_->line = write_pointers_.line; } } else { if(active_line_) { active_line_->end_points[1].x = location.x; active_line_->end_points[1].y = location.y; + active_line_->end_points[1].cycles_since_end_of_horizontal_retrace = location.cycles_since_end_of_horizontal_retrace; } } output_is_visible_ = is_visible; diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index 22ad7c390..8e60775a2 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -95,6 +95,7 @@ class ScanTarget: public Outputs::Display::ScanTarget { struct Line { struct EndPoint { uint16_t x, y; + uint16_t cycles_since_end_of_horizontal_retrace; } end_points[2]; uint16_t line; }; diff --git a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp index e33177639..09a725471 100644 --- a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp +++ b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp @@ -28,10 +28,12 @@ std::string ScanTarget::glsl_globals(ShaderType type) { "in vec2 startPoint;" "in float startDataX;" "in float startCompositeAngle;" + "in float startClock;" "in vec2 endPoint;" "in float endDataX;" "in float endCompositeAngle;" + "in float endClock;" "in float dataY;" "in float lineY;" @@ -48,6 +50,9 @@ std::string ScanTarget::glsl_globals(ShaderType type) { "in vec2 startPoint;" "in vec2 endPoint;" + "in float startClock;" + "in float endClock;" + "in float lineY;" "uniform sampler2D textureName;" @@ -64,19 +69,23 @@ std::vector ScanTarget::attribute_bindings(ShaderType {"startPoint", 0}, {"startDataX", 1}, {"startCompositeAngle", 2}, - {"endPoint", 3}, - {"endDataX", 4}, - {"endCompositeAngle", 5}, - {"dataY", 6}, - {"lineY", 7}, - {"compositeAmplitude", 8}, + {"startClock", 3}, + {"endPoint", 4}, + {"endDataX", 5}, + {"endCompositeAngle", 6}, + {"endClock", 7}, + {"dataY", 8}, + {"lineY", 9}, + {"compositeAmplitude", 10}, }; case ShaderType::Line: return { {"startPoint", 0}, {"endPoint", 1}, - {"lineY", 2}, + {"startClock", 2}, + {"endClock", 3}, + {"lineY", 4}, }; } } @@ -115,7 +124,7 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) { if(type == ShaderType::InputScan) { result += "textureCoordinate = vec2(mix(startDataX, endDataX, lateral), dataY + 0.5) / textureSize(textureName, 0);" - "vec2 eyePosition = vec2(mix(startPoint.x, endPoint.x, lateral) * processingWidth, lineY + longitudinal) / vec2(scale.x, 2048.0);"; + "vec2 eyePosition = vec2(mix(startClock, endClock, lateral), lineY + longitudinal) / vec2(2048.0, 2048.0);"; } else { result += "vec2 sourcePosition = vec2(mix(startPoint.x, endPoint.x, lateral) * processingWidth, lineY + 0.5);" @@ -161,7 +170,7 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) { "float lateral = float(gl_VertexID & 1);" "float longitudinal = float((gl_VertexID & 2) >> 1);" - "textureCoordinate = vec2(lateral * processingWidth, lineY + 0.5) / vec2(1.0, textureSize(textureName, 0).y);" + "textureCoordinate = vec2(mix(startClock, endClock, lateral), lineY + 0.5) / textureSize(textureName, 0);" "vec2 centrePoint = mix(startPoint, endPoint, lateral) / scale;" "vec2 height = normalize(endPoint - startPoint).yx * (longitudinal - 0.5) * rowHeight;" @@ -196,6 +205,12 @@ void ScanTarget::enable_vertex_attributes(ShaderType type, Shader &target) { sizeof(Scan), reinterpret_cast(offsetof(Scan, scan.end_points[c].composite_angle)), 1); + target.enable_vertex_attribute_with_pointer( + prefix + "Clock", + 1, GL_UNSIGNED_SHORT, GL_FALSE, + sizeof(Scan), + reinterpret_cast(offsetof(Scan, scan.end_points[c].cycles_since_end_of_horizontal_retrace)), + 1); } target.enable_vertex_attribute_with_pointer( @@ -228,6 +243,13 @@ void ScanTarget::enable_vertex_attributes(ShaderType type, Shader &target) { sizeof(Line), reinterpret_cast(offsetof(Line, end_points[c].x)), 1); + + target.enable_vertex_attribute_with_pointer( + prefix + "Clock", + 1, GL_UNSIGNED_SHORT, GL_FALSE, + sizeof(Line), + reinterpret_cast(offsetof(Line, end_points[c].cycles_since_end_of_horizontal_retrace)), + 1); } target.enable_vertex_attribute_with_pointer(