diff --git a/Machines/Oric/Video.cpp b/Machines/Oric/Video.cpp index bfb857782..a4107101a 100644 --- a/Machines/Oric/Video.cpp +++ b/Machines/Oric/Video.cpp @@ -42,6 +42,7 @@ VideoOutput::VideoOutput(uint8_t *memory) : "return (float(texValue) - 4.0) / 20.0;" "}" ); + crt_->set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 0.0f); set_output_device(Outputs::CRT::Television); crt_->set_visible_area(crt_->get_rect_for_area(50, 224, 16 * 6, 40 * 6, 4.0f / 3.0f)); diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index cb0aed7cd..5b4cf0cdc 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -62,6 +62,14 @@ void CRT::set_new_display_type(unsigned int cycles_per_line, DisplayType display } } +void CRT::set_composite_function_type(CompositeSourceType type, float offset_of_first_sample) { + if(type == DiscreteFourSamplesPerCycle) { + colour_burst_phase_adjustment_ = (uint8_t)(offset_of_first_sample * 256.0f) & 63; + } else { + colour_burst_phase_adjustment_ = 0xff; + } +} + CRT::CRT(unsigned int common_output_divisor, unsigned int buffer_depth) : sync_capacitor_charge_level_(0), is_receiving_sync_(false), @@ -272,7 +280,8 @@ void CRT::output_scan(const Scan *const scan) { colour_burst_phase_ = (position_phase + scan->phase) & 255; colour_burst_amplitude_ = scan->amplitude; - colour_burst_phase_ = (colour_burst_phase_ & ~63) + 32; + if(colour_burst_phase_adjustment_ != 0xff) + colour_burst_phase_ = (colour_burst_phase_ & ~63) + colour_burst_phase_adjustment_; } } diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index f9025f740..3f3847cf8 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -59,7 +59,7 @@ class CRT { }; void output_scan(const Scan *scan); - uint8_t colour_burst_phase_, colour_burst_amplitude_; + uint8_t colour_burst_phase_, colour_burst_amplitude_, colour_burst_phase_adjustment_; bool is_writing_composite_run_; unsigned int phase_denominator_, phase_numerator_, colour_cycle_numerator_; @@ -252,6 +252,26 @@ class CRT { }); } + enum CompositeSourceType { + /// The composite function provides continuous output. + Continuous, + /// The composite function provides discrete output with four unique values per colour cycle. + DiscreteFourSamplesPerCycle + }; + + /*! Provides information about the type of output the composite sampling function provides — discrete or continuous. + + This is necessary because the CRT implementation samples discretely and therefore can use fewer intermediate + samples if it can exactly duplicate the sampling rate and placement of the composite sampling function. + + A continuous function is assumed by default. + + @param type The type of output provided by the function supplied to `set_composite_sampling_function`. + @param offset_of_first_sample The relative position within a full cycle of the colour subcarrier at which the + first sample falls. E.g. 0.125 means "at 1/8th of the way through the complete cycle". + */ + void set_composite_function_type(CompositeSourceType type, float offset_of_first_sample = 0.0f); + /*! Sets a function that will map from whatever data the machine provided to an RGB signal. If the output mode is composite then a default mapping from RGB to the display's composite