mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 15:31:09 +00:00
Introduces S-Video as a video signal type at the interface level.
This commit is contained in:
parent
389979923e
commit
33281b9d89
@ -96,7 +96,7 @@ TMS9918::TMS9918(Personality p) {
|
||||
"{"
|
||||
"return texture(sampler, coordinate).rgb / vec3(255.0);"
|
||||
"}");
|
||||
crt_->set_output_device(Outputs::CRT::OutputDevice::Monitor);
|
||||
crt_->set_video_signal(Outputs::CRT::VideoSignal::RGB);
|
||||
crt_->set_visible_area(Outputs::CRT::Rect(0.055f, 0.025f, 0.9f, 0.9f));
|
||||
crt_->set_input_gamma(2.8f);
|
||||
|
||||
|
@ -317,7 +317,7 @@ class CRTCBusHandler {
|
||||
"return vec3(float((sample >> 4) & 3u), float((sample >> 2) & 3u), float(sample & 3u)) / 2.0;"
|
||||
"}");
|
||||
crt_->set_visible_area(Outputs::CRT::Rect(0.075f, 0.05f, 0.9f, 0.9f));
|
||||
crt_->set_output_device(Outputs::CRT::OutputDevice::Monitor);
|
||||
crt_->set_video_signal(Outputs::CRT::VideoSignal::RGB);
|
||||
}
|
||||
|
||||
/// Destructs the CRT.
|
||||
|
@ -25,7 +25,7 @@ namespace {
|
||||
TIA::TIA(bool create_crt) {
|
||||
if(create_crt) {
|
||||
crt_.reset(new Outputs::CRT::CRT(cycles_per_line * 2 - 1, 1, Outputs::CRT::DisplayType::NTSC60, 1));
|
||||
crt_->set_output_device(Outputs::CRT::OutputDevice::Television);
|
||||
crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite);
|
||||
set_output_mode(OutputMode::NTSC);
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ class ConcreteMachine:
|
||||
|
||||
void setup_output(float aspect_ratio) override {
|
||||
vdp_.reset(new TI::TMS9918(TI::TMS9918::TMS9918A));
|
||||
get_crt()->set_output_device(Outputs::CRT::OutputDevice::Television);
|
||||
get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite);
|
||||
}
|
||||
|
||||
void close_output() override {
|
||||
|
@ -454,7 +454,7 @@ class ConcreteMachine:
|
||||
|
||||
Configurable::Display display;
|
||||
if(Configurable::get_display(selections_by_option, display)) {
|
||||
get_crt()->set_output_device((display == Configurable::Display::RGB) ? Outputs::CRT::OutputDevice::Monitor : Outputs::CRT::OutputDevice::Television);
|
||||
get_crt()->set_video_signal((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ class ConcreteMachine:
|
||||
|
||||
Configurable::Display display;
|
||||
if(Configurable::get_display(selections_by_option, display)) {
|
||||
get_crt()->set_output_device((display == Configurable::Display::RGB) ? Outputs::CRT::OutputDevice::Monitor : Outputs::CRT::OutputDevice::Television);
|
||||
get_crt()->set_video_signal((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ class ConcreteMachine:
|
||||
use_fast_tape_hack_ = activate;
|
||||
}
|
||||
|
||||
void set_output_device(Outputs::CRT::OutputDevice output_device) {
|
||||
void set_output_device(Outputs::CRT::VideoSignal output_device) {
|
||||
video_output_->set_output_device(output_device);
|
||||
}
|
||||
|
||||
@ -392,7 +392,7 @@ class ConcreteMachine:
|
||||
|
||||
video_output_.reset(new VideoOutput(ram_));
|
||||
if(!colour_rom_.empty()) video_output_->set_colour_rom(colour_rom_);
|
||||
set_output_device(Outputs::CRT::OutputDevice::Monitor);
|
||||
set_output_device(Outputs::CRT::VideoSignal::RGB);
|
||||
}
|
||||
|
||||
void close_output() override final {
|
||||
@ -465,7 +465,7 @@ class ConcreteMachine:
|
||||
|
||||
Configurable::Display display;
|
||||
if(Configurable::get_display(selections_by_option, display)) {
|
||||
set_output_device((display == Configurable::Display::RGB) ? Outputs::CRT::OutputDevice::Monitor : Outputs::CRT::OutputDevice::Television);
|
||||
set_output_device((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,13 @@ VideoOutput::VideoOutput(uint8_t *memory) :
|
||||
);
|
||||
crt_->set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 0.0f);
|
||||
|
||||
set_output_device(Outputs::CRT::OutputDevice::Television);
|
||||
set_output_device(Outputs::CRT::VideoSignal::Composite);
|
||||
crt_->set_visible_area(crt_->get_rect_for_area(53, 224, 16 * 6, 40 * 6, 4.0f / 3.0f));
|
||||
}
|
||||
|
||||
void VideoOutput::set_output_device(Outputs::CRT::OutputDevice output_device) {
|
||||
void VideoOutput::set_output_device(Outputs::CRT::VideoSignal output_device) {
|
||||
output_device_ = output_device;
|
||||
crt_->set_output_device(output_device);
|
||||
crt_->set_video_signal(output_device);
|
||||
}
|
||||
|
||||
void VideoOutput::set_colour_rom(const std::vector<uint8_t> &rom) {
|
||||
@ -129,7 +129,7 @@ void VideoOutput::run_for(const Cycles cycles) {
|
||||
if(control_byte & 0x60) {
|
||||
if(pixel_target_) {
|
||||
uint16_t colours[2];
|
||||
if(output_device_ == Outputs::CRT::OutputDevice::Monitor) {
|
||||
if(output_device_ == Outputs::CRT::VideoSignal::RGB) {
|
||||
colours[0] = static_cast<uint8_t>(paper_ ^ inverse_mask);
|
||||
colours[1] = static_cast<uint8_t>(ink_ ^ inverse_mask);
|
||||
} else {
|
||||
@ -183,7 +183,7 @@ void VideoOutput::run_for(const Cycles cycles) {
|
||||
pixel_target_[0] = pixel_target_[1] =
|
||||
pixel_target_[2] = pixel_target_[3] =
|
||||
pixel_target_[4] = pixel_target_[5] =
|
||||
(output_device_ == Outputs::CRT::OutputDevice::Monitor) ? paper_ ^ inverse_mask : colour_forms_[paper_ ^ inverse_mask];
|
||||
(output_device_ == Outputs::CRT::VideoSignal::RGB) ? paper_ ^ inverse_mask : colour_forms_[paper_ ^ inverse_mask];
|
||||
}
|
||||
}
|
||||
if(pixel_target_) pixel_target_ += 6;
|
||||
|
@ -20,7 +20,7 @@ class VideoOutput {
|
||||
Outputs::CRT::CRT *get_crt();
|
||||
void run_for(const Cycles cycles);
|
||||
void set_colour_rom(const std::vector<uint8_t> &rom);
|
||||
void set_output_device(Outputs::CRT::OutputDevice output_device);
|
||||
void set_output_device(Outputs::CRT::VideoSignal output_device);
|
||||
|
||||
private:
|
||||
uint8_t *ram_;
|
||||
@ -33,7 +33,7 @@ class VideoOutput {
|
||||
// Output target and device
|
||||
uint16_t *pixel_target_;
|
||||
uint16_t colour_forms_[8];
|
||||
Outputs::CRT::OutputDevice output_device_;
|
||||
Outputs::CRT::VideoSignal output_device_;
|
||||
|
||||
// Registers
|
||||
uint8_t ink_, paper_;
|
||||
|
@ -306,10 +306,27 @@ class CRT {
|
||||
*/
|
||||
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 s-video signal.
|
||||
|
||||
If the output mode is composite then a default mapping from RGB to the display's
|
||||
output mode will be applied.
|
||||
|
||||
@param shader A GLSL fragment including a function with the signature
|
||||
`vec2 svideo_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase)`
|
||||
that evaluates to the s-video signal level, luminance as the first component and chrominance
|
||||
as the second, as a function of a source buffer, sampling location and colour
|
||||
carrier phase.
|
||||
*/
|
||||
inline void set_svideo_sampling_function(const std::string &shader) {
|
||||
enqueue_openGL_function([shader, this] {
|
||||
openGL_output_builder_.set_svideo_sampling_function(shader);
|
||||
});
|
||||
}
|
||||
|
||||
/*! 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
|
||||
format will be applied.
|
||||
If the output mode is composite or svideo then a default mapping from RGB to the display's
|
||||
output mode will be applied.
|
||||
|
||||
@param shader A GLSL fragent including a function with the signature
|
||||
`vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)` that evaluates to an RGB colour
|
||||
@ -329,9 +346,9 @@ class CRT {
|
||||
openGL_output_builder_.texture_builder.set_bookender(std::move(bookender));
|
||||
}
|
||||
|
||||
inline void set_output_device(OutputDevice output_device) {
|
||||
enqueue_openGL_function([output_device, this] {
|
||||
openGL_output_builder_.set_output_device(output_device);
|
||||
inline void set_video_signal(VideoSignal video_signal) {
|
||||
enqueue_openGL_function([video_signal, this] {
|
||||
openGL_output_builder_.set_video_signal(video_signal);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -36,9 +36,10 @@ enum class ColourSpace {
|
||||
YUV
|
||||
};
|
||||
|
||||
enum class OutputDevice {
|
||||
Monitor,
|
||||
Television
|
||||
enum class VideoSignal {
|
||||
RGB,
|
||||
SVideo,
|
||||
Composite
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ OpenGLOutputBuilder::~OpenGLOutputBuilder() {
|
||||
}
|
||||
|
||||
bool OpenGLOutputBuilder::get_is_television_output() {
|
||||
return output_device_ == OutputDevice::Television || !rgb_input_shader_program_;
|
||||
return video_signal_ == VideoSignal::Composite || !rgb_input_shader_program_;
|
||||
}
|
||||
|
||||
void OpenGLOutputBuilder::set_target_framebuffer(GLint target_framebuffer) {
|
||||
@ -363,9 +363,9 @@ void OpenGLOutputBuilder::prepare_output_vertex_array() {
|
||||
|
||||
// MARK: - Public Configuration
|
||||
|
||||
void OpenGLOutputBuilder::set_output_device(OutputDevice output_device) {
|
||||
if(output_device_ != output_device) {
|
||||
output_device_ = output_device;
|
||||
void OpenGLOutputBuilder::set_video_signal(VideoSignal video_signal) {
|
||||
if(video_signal_ != video_signal) {
|
||||
video_signal_ = video_signal;
|
||||
composite_src_output_y_ = 0;
|
||||
last_output_width_ = 0;
|
||||
last_output_height_ = 0;
|
||||
|
@ -33,7 +33,7 @@ class OpenGLOutputBuilder {
|
||||
ColourSpace colour_space_;
|
||||
unsigned int colour_cycle_numerator_;
|
||||
unsigned int colour_cycle_denominator_;
|
||||
OutputDevice output_device_;
|
||||
VideoSignal video_signal_;
|
||||
float gamma_;
|
||||
|
||||
// timing information to allow reasoning about input information
|
||||
@ -73,6 +73,8 @@ class OpenGLOutputBuilder {
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_separation_filter_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_chrominance_filter_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::IntermediateShader> svideo_input_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::IntermediateShader> rgb_input_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> rgb_filter_shader_program_;
|
||||
|
||||
@ -130,8 +132,8 @@ class OpenGLOutputBuilder {
|
||||
return std::unique_lock<std::mutex>(output_mutex_);
|
||||
}
|
||||
|
||||
inline OutputDevice get_output_device() {
|
||||
return output_device_;
|
||||
inline VideoSignal get_output_device() {
|
||||
return video_signal_;
|
||||
}
|
||||
|
||||
inline uint16_t get_composite_output_y() {
|
||||
@ -147,12 +149,13 @@ class OpenGLOutputBuilder {
|
||||
composite_src_output_y_++;
|
||||
}
|
||||
|
||||
void set_target_framebuffer(GLint target_framebuffer);
|
||||
void set_target_framebuffer(GLint);
|
||||
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
||||
void set_openGL_context_will_change(bool should_delete_resources);
|
||||
void set_composite_sampling_function(const std::string &shader);
|
||||
void set_rgb_sampling_function(const std::string &shader);
|
||||
void set_output_device(OutputDevice output_device);
|
||||
void set_composite_sampling_function(const std::string &);
|
||||
void set_svideo_sampling_function(const std::string &);
|
||||
void set_rgb_sampling_function(const std::string &);
|
||||
void set_video_signal(VideoSignal);
|
||||
void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user