diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index d41e52de8..cd223088b 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -172,10 +172,12 @@ class AYDeferrer { class CRTCBusHandler { public: CRTCBusHandler(uint8_t *ram, InterruptTimer &interrupt_timer) : + crt_(1024, 16, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red2Green2Blue2), ram_(ram), interrupt_timer_(interrupt_timer) { establish_palette_hits(); build_mode_table(); + crt_.set_visible_area(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f)); } /*! @@ -218,12 +220,12 @@ class CRTCBusHandler { if(cycles_) { switch(previous_output_mode_) { default: - case OutputMode::Blank: crt_->output_blank(cycles_ * 16); break; - case OutputMode::Sync: crt_->output_sync(cycles_ * 16); break; + case OutputMode::Blank: crt_.output_blank(cycles_ * 16); break; + case OutputMode::Sync: crt_.output_sync(cycles_ * 16); break; case OutputMode::Border: output_border(cycles_); break; - case OutputMode::ColourBurst: crt_->output_default_colour_burst(cycles_ * 16); break; + case OutputMode::ColourBurst: crt_.output_default_colour_burst(cycles_ * 16); break; case OutputMode::Pixels: - crt_->output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_)); + crt_.output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_)); pixel_pointer_ = pixel_data_ = nullptr; break; } @@ -239,7 +241,7 @@ class CRTCBusHandler { // collect some more pixels if output is ongoing if(previous_output_mode_ == OutputMode::Pixels) { if(!pixel_data_) { - pixel_pointer_ = pixel_data_ = crt_->begin_data(320, 8); + pixel_pointer_ = pixel_data_ = crt_.begin_data(320, 8); } if(pixel_pointer_) { // the CPC shuffles output lines as: @@ -284,7 +286,7 @@ class CRTCBusHandler { // widths so it's not necessarily possible to predict the correct number in advance // and using the upper bound could lead to inefficient behaviour if(pixel_pointer_ == pixel_data_ + 320) { - crt_->output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_)); + crt_.output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_)); pixel_pointer_ = pixel_data_ = nullptr; cycles_ = 0; } @@ -326,27 +328,9 @@ class CRTCBusHandler { /// Constructs an appropriate CRT for video output. void set_scan_target(Outputs::Display::ScanTarget *scan_target) { -// crt_.reset(new Outputs::CRT::CRT(1024, 16, Outputs::Display::Type::PAL50, 1)); -// crt_->set_rgb_sampling_function( -// "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)" -// "{" -// "uint sample = texture(texID, coordinate).r;" -// "return vec3(float((sample >> 4) & 3u), float((sample >> 2) & 3u), float(sample & 3u)) / 2.0;" -// "}"); - crt_->set_visible_area(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f)); -// crt_->set_video_signal(Outputs::Display::VideoSignal::RGB); + crt_.set_scan_target(scan_target); } - /// Destructs the CRT. -// void close_output() { -// crt_.reset(); -// } - - /// @returns the CRT. -// Outputs::CRT::CRT *get_crt() { -// return crt_.get(); -// } - /*! Sets the next video mode. Per the documentation, mode changes take effect only at the end of line, not immediately. So next means "as of the end of this line". @@ -378,9 +362,9 @@ class CRTCBusHandler { private: void output_border(int length) { - uint8_t *colour_pointer = static_cast(crt_->begin_data(1)); + uint8_t *colour_pointer = static_cast(crt_.begin_data(1)); if(colour_pointer) *colour_pointer = border_; - crt_->output_level(length * 16); + crt_.output_level(length * 16); } #define Mode0Colour0(c) ((c & 0x80) >> 7) | ((c & 0x20) >> 3) | ((c & 0x08) >> 2) | ((c & 0x02) << 2) @@ -534,7 +518,7 @@ class CRTCBusHandler { bool was_hsync_ = false, was_vsync_ = false; int cycles_into_hsync_ = 0; - std::unique_ptr crt_; + Outputs::CRT::CRT crt_; uint8_t *pixel_data_ = nullptr, *pixel_pointer_ = nullptr; uint8_t *ram_ = nullptr; @@ -987,16 +971,6 @@ template class ConcreteMachine: crtc_bus_handler_.set_scan_target(scan_target); } - /// A CRTMachine function; indicates that outputs should be destroyed now. -// void close_output() override final { -// crtc_bus_handler_.close_output(); -// } - - /// @returns the CRT in use. -// Outputs::CRT::CRT *get_crt() override final { -// return crtc_bus_handler_.get_crt(); -// } - /// @returns the speaker in use. Outputs::Speaker::Speaker *get_speaker() override final { return ay_.get_speaker(); diff --git a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp index 4943bc9ab..80ad6fb95 100644 --- a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp +++ b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp @@ -196,8 +196,9 @@ std::unique_ptr ScanTarget::input_shader(InputDataType input_data_type, // fragment_shader += "}"; // break; + // TODO: write encoding functions for RGB -> composite/s-video for the RGB inputs. + case InputDataType::Red1Green1Blue1: - // TODO: write encoding functions for RGB -> composite/s-video. fragment_shader += "uniform usampler2D textureName;" "void main(void) {" @@ -207,6 +208,12 @@ std::unique_ptr ScanTarget::input_shader(InputDataType input_data_type, break; case InputDataType::Red2Green2Blue2: + fragment_shader += + "uniform usampler2D textureName;" + "void main(void) {" + "uint textureValue = texture(textureName, textureCoordinate).r;" + "fragColour = vec4(vec3(float((textureValue >> 4) & 3u), float((textureValue >> 2) & 3u), float(textureValue & 3u)) / 3.0, 1.0);" + "}"; break; case InputDataType::Red4Green4Blue4: