1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-21 02:37:44 +00:00

Starts to bend 'CRTMachine' to a world farther from owning the GPU relationship.

This commit is contained in:
Thomas Harte 2018-11-03 21:54:25 -04:00
parent da4d883321
commit b40211d2c0
33 changed files with 222 additions and 274 deletions

@ -53,24 +53,13 @@ void MultiCRTMachine::perform_serial(const std::function<void (::CRTMachine::Mac
}
}
void MultiCRTMachine::setup_output(float aspect_ratio) {
void MultiCRTMachine::setup_output(Outputs::Display::ScanTarget *scan_target) {
perform_serial([=](::CRTMachine::Machine *machine) {
machine->setup_output(aspect_ratio);
// TODO.
// machine->setup_output(aspect_ratio);
});
}
void MultiCRTMachine::close_output() {
perform_serial([=](::CRTMachine::Machine *machine) {
machine->close_output();
});
}
Outputs::CRT::CRT *MultiCRTMachine::get_crt() {
std::lock_guard<std::mutex> machines_lock(machines_mutex_);
CRTMachine::Machine *crt_machine = machines_.front()->crt_machine();
return crt_machine ? crt_machine->get_crt() : nullptr;
}
Outputs::Speaker::Speaker *MultiCRTMachine::get_speaker() {
return speaker_;
}

@ -53,9 +53,7 @@ class MultiCRTMachine: public CRTMachine::Machine {
}
// Below is the standard CRTMachine::Machine interface; see there for documentation.
void setup_output(float aspect_ratio) override;
void close_output() override;
Outputs::CRT::CRT *get_crt() override;
void setup_output(Outputs::Display::ScanTarget *scan_target) override;
Outputs::Speaker::Speaker *get_speaker() override;
void run_for(Time::Seconds duration) override;

@ -9,6 +9,7 @@
#ifndef ClockDeferrer_h
#define ClockDeferrer_h
#include <functional>
#include <vector>
/*!

@ -64,7 +64,7 @@ template <class BusHandler> class MOS6560 {
public:
MOS6560(BusHandler &bus_handler) :
bus_handler_(bus_handler),
crt_(new Outputs::CRT::CRT(65*4, 4, Outputs::CRT::DisplayType::NTSC60, 2)),
crt_(new Outputs::CRT::CRT(65*4, 4, Outputs::Display::Type::NTSC60, 2)),
audio_generator_(audio_queue_),
speaker_(audio_generator_)
{
@ -80,7 +80,7 @@ template <class BusHandler> class MOS6560 {
// "}");
// default to s-video output
// crt_->set_video_signal(Outputs::CRT::VideoSignal::SVideo);
// crt_->set_video_signal(Outputs::Display::VideoSignal::SVideo);
// default to NTSC
set_output_mode(OutputMode::NTSC);
@ -131,12 +131,12 @@ template <class BusHandler> class MOS6560 {
103, 42, 80, 16,
};
const uint8_t *chrominances;
Outputs::CRT::DisplayType display_type;
Outputs::Display::Type display_type;
switch(output_mode) {
default:
chrominances = pal_chrominances;
display_type = Outputs::CRT::DisplayType::PAL50;
display_type = Outputs::Display::Type::PAL50;
timing_.cycles_per_line = 71;
timing_.line_counter_increment_offset = 4;
timing_.final_line_increment_position = timing_.cycles_per_line - timing_.line_counter_increment_offset;
@ -146,7 +146,7 @@ template <class BusHandler> class MOS6560 {
case OutputMode::NTSC:
chrominances = ntsc_chrominances;
display_type = Outputs::CRT::DisplayType::NTSC60;
display_type = Outputs::Display::Type::NTSC60;
timing_.cycles_per_line = 65;
timing_.line_counter_increment_offset = 40;
timing_.final_line_increment_position = 58;
@ -159,10 +159,10 @@ template <class BusHandler> class MOS6560 {
switch(output_mode) {
case OutputMode::PAL:
crt_->set_visible_area(Outputs::CRT::Rect(0.1f, 0.07f, 0.9f, 0.9f));
crt_->set_visible_area(Outputs::Display::Rect(0.1f, 0.07f, 0.9f, 0.9f));
break;
case OutputMode::NTSC:
crt_->set_visible_area(Outputs::CRT::Rect(0.05f, 0.05f, 0.9f, 0.9f));
crt_->set_visible_area(Outputs::Display::Rect(0.05f, 0.05f, 0.9f, 0.9f));
break;
}

@ -50,7 +50,7 @@ struct ReverseTable {
Base::Base(Personality p) :
personality_(p),
crt_(new Outputs::CRT::CRT(CRTCyclesPerLine, CRTCyclesDivider, Outputs::CRT::DisplayType::NTSC60, 4)) {
crt_(new Outputs::CRT::CRT(CRTCyclesPerLine, CRTCyclesDivider, Outputs::Display::Type::NTSC60, 4)) {
switch(p) {
case TI::TMS::TMS9918A:
@ -91,8 +91,8 @@ TMS9918::TMS9918(Personality p):
// "{"
// "return texture(sampler, coordinate).rgb / vec3(255.0);"
// "}");
// 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_video_signal(Outputs::Display::VideoSignal::RGB);
crt_->set_visible_area(Outputs::Display::Rect(0.055f, 0.025f, 0.9f, 0.9f));
// The TMS remains in-phase with the NTSC colour clock; this is an empirical measurement
// intended to produce the correct relationship between the hard edges between pixels and
@ -107,12 +107,12 @@ void TMS9918::set_tv_standard(TVStandard standard) {
case TVStandard::PAL:
mode_timing_.total_lines = 313;
mode_timing_.first_vsync_line = 253;
crt_->set_new_display_type(CRTCyclesPerLine, Outputs::CRT::DisplayType::PAL50);
crt_->set_new_display_type(CRTCyclesPerLine, Outputs::Display::Type::PAL50);
break;
default:
mode_timing_.total_lines = 262;
mode_timing_.first_vsync_line = 227;
crt_->set_new_display_type(CRTCyclesPerLine, Outputs::CRT::DisplayType::NTSC60);
crt_->set_new_display_type(CRTCyclesPerLine, Outputs::Display::Type::NTSC60);
break;
}
}

@ -30,6 +30,7 @@
#include "../../ClockReceiver/ForceInline.hpp"
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
#include "../../Outputs/CRT/CRT.hpp"
#include "../../Analyser/Static/AmstradCPC/Target.hpp"
@ -324,27 +325,27 @@ class CRTCBusHandler {
}
/// Constructs an appropriate CRT for video output.
void setup_output(float aspect_ratio) {
crt_.reset(new Outputs::CRT::CRT(1024, 16, Outputs::CRT::DisplayType::PAL50, 1));
void setup_output(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::CRT::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f));
// crt_->set_video_signal(Outputs::CRT::VideoSignal::RGB);
crt_->set_visible_area(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f));
// crt_->set_video_signal(Outputs::Display::VideoSignal::RGB);
}
/// Destructs the CRT.
void close_output() {
crt_.reset();
}
// void close_output() {
// crt_.reset();
// }
/// @returns the CRT.
Outputs::CRT::CRT *get_crt() {
return crt_.get();
}
// 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,
@ -982,19 +983,19 @@ template <bool has_fdc> class ConcreteMachine:
}
/// A CRTMachine function; indicates that outputs should be created now.
void setup_output(float aspect_ratio) override final {
crtc_bus_handler_.setup_output(aspect_ratio);
void setup_output(Outputs::Display::ScanTarget *scan_target) override final {
crtc_bus_handler_.setup_output(scan_target);
}
/// A CRTMachine function; indicates that outputs should be destroyed now.
void close_output() override final {
crtc_bus_handler_.close_output();
}
// 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();
}
// 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 {

@ -396,18 +396,18 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
audio_queue_.flush();
}
void setup_output(float aspect_ratio) override {
void setup_output(Outputs::Display::ScanTarget *scan_target) override {
video_.reset(new AppleII::Video::Video<VideoBusHandler, is_iie()>(video_bus_handler_));
video_->set_character_rom(character_rom_);
}
void close_output() override {
video_.reset();
}
Outputs::CRT::CRT *get_crt() override {
return video_->get_crt();
}
// void close_output() override {
// video_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override {
// return video_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override {
return &speaker_;

@ -11,7 +11,7 @@
using namespace AppleII::Video;
VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
crt_(new Outputs::CRT::CRT(910, 1, Outputs::CRT::DisplayType::NTSC60, 1)),
crt_(new Outputs::CRT::CRT(910, 1, Outputs::Display::Type::NTSC60, 1)),
is_iie_(is_iie),
deferrer_(std::move(target)) {
@ -24,8 +24,8 @@ VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
// "}");
// Show only the centre 75% of the TV frame.
// crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite);
crt_->set_visible_area(Outputs::CRT::Rect(0.118f, 0.122f, 0.77f, 0.77f));
// crt_->set_video_signal(Outputs::Display::VideoSignal::Composite);
crt_->set_visible_area(Outputs::Display::Rect(0.118f, 0.122f, 0.77f, 0.77f));
crt_->set_immediate_default_phase(0.0f);
character_zones[0].xor_mask = 0;

@ -123,7 +123,7 @@ class ConcreteMachine:
}
~ConcreteMachine() {
close_output();
// close_output();
}
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
@ -157,19 +157,19 @@ class ConcreteMachine:
}
// to satisfy CRTMachine::Machine
void setup_output(float aspect_ratio) override {
void setup_output(Outputs::Display::ScanTarget *scan_target) override {
bus_->tia_.reset(new TIA);
bus_->speaker_.set_input_rate(static_cast<float>(get_clock_rate() / static_cast<double>(CPUTicksPerAudioTick)));
bus_->tia_->get_crt()->set_delegate(this);
}
void close_output() override {
bus_.reset();
}
Outputs::CRT::CRT *get_crt() override {
return bus_->tia_->get_crt();
}
// void close_output() override {
// bus_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override {
// return bus_->tia_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override {
return &bus_->speaker_;

@ -24,8 +24,8 @@ 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_video_signal(Outputs::CRT::VideoSignal::Composite);
crt_.reset(new Outputs::CRT::CRT(cycles_per_line * 2 - 1, 1, Outputs::Display::Type::NTSC60, 1));
// crt_->set_video_signal(Outputs::Display::VideoSignal::Composite);
set_output_mode(OutputMode::NTSC);
}
@ -120,7 +120,7 @@ TIA::TIA(std::function<void(uint8_t *output_buffer)> line_end_function) : TIA(fa
}
void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) {
Outputs::CRT::DisplayType display_type;
Outputs::Display::Type display_type;
if(output_mode == OutputMode::NTSC) {
// crt_->set_svideo_sampling_function(
@ -133,7 +133,7 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) {
// "float phaseOffset = 6.283185308 * float(iPhase) / 13.0 + 5.074880441076923;"
// "return vec2(float(y) / 14.0, step(1, iPhase) * cos(phase - phaseOffset));"
// "}");
display_type = Outputs::CRT::DisplayType::NTSC60;
display_type = Outputs::Display::Type::NTSC60;
} else {
// crt_->set_svideo_sampling_function(
// "vec2 svideo_sample(usampler2D texID, vec2 coordinate, float phase, float amplitude)"
@ -147,9 +147,9 @@ void TIA::set_output_mode(Atari2600::TIA::OutputMode output_mode) {
// "phaseOffset *= 6.283185308 / 12.0;"
// "return vec2(float(y) / 14.0, step(4, (iPhase + 2u) & 15u) * cos(phase + phaseOffset));"
// "}");
display_type = Outputs::CRT::DisplayType::PAL50;
display_type = Outputs::Display::Type::PAL50;
}
// crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite);
// crt_->set_video_signal(Outputs::Display::VideoSignal::Composite);
// line number of cycles in a line of video is one less than twice the number of clock cycles per line; the Atari
// outputs 228 colour cycles of material per line when an NTSC line 227.5. Since all clock numbers will be doubled

@ -9,9 +9,12 @@
#ifndef TIA_hpp
#define TIA_hpp
#include <algorithm>
#include <cstdint>
#include <functional>
#include "../CRTMachine.hpp"
#include "../../Outputs/CRT/CRT.hpp"
#include "../../ClockReceiver/ClockReceiver.hpp"
namespace Atari2600 {

@ -9,7 +9,7 @@
#ifndef CRTMachine_hpp
#define CRTMachine_hpp
#include "../Outputs/CRT/CRT.hpp"
#include "../Outputs/ScanTarget.hpp"
#include "../Outputs/Speaker/Speaker.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"
#include "../ClockReceiver/TimeTypes.hpp"
@ -19,6 +19,7 @@
#include <cmath>
// TODO: rename.
namespace CRTMachine {
/*!
@ -29,19 +30,12 @@ namespace CRTMachine {
class Machine {
public:
/*!
Causes the machine to set up its CRT and, if it has one, speaker. The caller guarantees
that an OpenGL context is bound.
*/
virtual void setup_output(float aspect_ratio) = 0;
Causes the machine to set up its display and, if it has one, speaker.
/*!
Gives the machine a chance to release all owned resources. The caller guarantees that the
OpenGL context is bound.
The @c scan_target will receive all video output; the caller guarantees
that it is non-null.
*/
virtual void close_output() = 0;
/// @returns The CRT this machine is drawing to. Should not be @c nullptr.
virtual Outputs::CRT::CRT *get_crt() = 0;
virtual void setup_output(Outputs::Display::ScanTarget *scan_target) = 0;
/// @returns The speaker that receives this machine's output, or @c nullptr if this machine is mute.
virtual Outputs::Speaker::Speaker *get_speaker() = 0;
@ -68,21 +62,21 @@ class Machine {
}
/*!
Maps from Configurable::Display to Outputs::CRT::VideoSignal and calls
Maps from Configurable::Display to Outputs::Display::VideoSignal and calls
@c set_video_signal with the result.
*/
void set_video_signal_configurable(Configurable::Display type) {
Outputs::CRT::VideoSignal signal;
Outputs::Display::VideoSignal signal;
switch(type) {
default:
case Configurable::Display::RGB:
signal = Outputs::CRT::VideoSignal::RGB;
signal = Outputs::Display::VideoSignal::RGB;
break;
case Configurable::Display::SVideo:
signal = Outputs::CRT::VideoSignal::SVideo;
signal = Outputs::Display::VideoSignal::SVideo;
break;
case Configurable::Display::Composite:
signal = Outputs::CRT::VideoSignal::Composite;
signal = Outputs::Display::VideoSignal::Composite;
break;
}
set_video_signal(signal);
@ -91,7 +85,7 @@ class Machine {
/*!
Forwards the video signal to the CRT returned by get_crt().
*/
virtual void set_video_signal(Outputs::CRT::VideoSignal video_signal) {
virtual void set_video_signal(Outputs::Display::VideoSignal video_signal) {
// get_crt()->set_video_signal(video_signal);
}

@ -169,18 +169,18 @@ class ConcreteMachine:
return joysticks_;
}
void setup_output(float aspect_ratio) override {
void setup_output(Outputs::Display::ScanTarget *scan_target) override {
vdp_.reset(new TI::TMS::TMS9918(TI::TMS::TMS9918A));
// get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite);
// get_crt()->set_video_signal(Outputs::Display::VideoSignal::Composite);
}
void close_output() override {
vdp_.reset();
}
Outputs::CRT::CRT *get_crt() override {
return vdp_->get_crt();
}
// void close_output() override {
// vdp_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override {
// return vdp_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override {
return &speaker_;

@ -620,20 +620,20 @@ class ConcreteMachine:
m6502_.run_for(cycles);
}
void setup_output(float aspect_ratio) override final {
void setup_output(Outputs::Display::ScanTarget *scan_target) override final {
mos6560_.reset(new MOS::MOS6560::MOS6560<Vic6560BusHandler>(mos6560_bus_handler_));
mos6560_->set_high_frequency_cutoff(1600); // There is a 1.6Khz low-pass filter in the Vic-20.
mos6560_->set_output_mode(output_mode_);
mos6560_->set_clock_rate(get_clock_rate());
}
void close_output() override final {
mos6560_ = nullptr;
}
Outputs::CRT::CRT *get_crt() override final {
return mos6560_->get_crt();
}
// void close_output() override final {
// mos6560_ = nullptr;
// }
//
// Outputs::CRT::CRT *get_crt() override final {
// return mos6560_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override final {
return mos6560_->get_speaker();

@ -373,17 +373,17 @@ class ConcreteMachine:
audio_queue_.perform();
}
void setup_output(float aspect_ratio) override final {
void setup_output(Outputs::Display::ScanTarget *scan_target) override final {
video_output_.reset(new VideoOutput(ram_));
}
void close_output() override final {
video_output_.reset();
}
Outputs::CRT::CRT *get_crt() override final {
return video_output_->get_crt();
}
// void close_output() override final {
// video_output_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override final {
// return video_output_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override final {
return &speaker_;

@ -43,7 +43,7 @@ VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory) {
setup_screen_map();
setup_base_address();
crt_.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1));
crt_.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::Display::Type::PAL50, 1));
// crt_->set_rgb_sampling_function(
// "vec3 rgb_sample(usampler2D sampler, vec2 coordinate)"
// "{"

@ -13,6 +13,8 @@
#include "../../ClockReceiver/ClockReceiver.hpp"
#include "Interrupts.hpp"
#include <vector>
namespace Electron {
/*!

@ -218,17 +218,17 @@ class ConcreteMachine:
audio_queue_.flush();
}
void setup_output(float aspect_ratio) override {
void setup_output(Outputs::Display::ScanTarget *scan_target) override {
vdp_.reset(new TI::TMS::TMS9918(TI::TMS::TMS9918A));
}
void close_output() override {
vdp_.reset();
}
Outputs::CRT::CRT *get_crt() override {
return vdp_->get_crt();
}
// void close_output() override {
// vdp_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override {
// return vdp_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override {
return &speaker_;

@ -161,7 +161,7 @@ class ConcreteMachine:
audio_queue_.flush();
}
void setup_output(float aspect_ratio) override {
void setup_output(Outputs::Display::ScanTarget *scan_target) override {
TI::TMS::Personality personality = TI::TMS::TMS9918A;
switch(model_) {
case Target::Model::SG1000: personality = TI::TMS::TMS9918A; break;
@ -172,18 +172,18 @@ class ConcreteMachine:
vdp_->set_tv_standard(
(region_ == Target::Region::Europe) ?
TI::TMS::TVStandard::PAL : TI::TMS::TVStandard::NTSC);
// get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite);
// get_crt()->set_video_signal(Outputs::Display::VideoSignal::Composite);
time_until_debounce_ = vdp_->get_time_until_line(-1);
}
void close_output() override {
vdp_.reset();
}
Outputs::CRT::CRT *get_crt() override {
return vdp_->get_crt();
}
// void close_output() override {
// vdp_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override {
// return vdp_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override {
return &speaker_;

@ -456,21 +456,21 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
}
// to satisfy CRTMachine::Machine
void setup_output(float aspect_ratio) override final {
void setup_output(Outputs::Display::ScanTarget *scan_target) override final {
speaker_.set_input_rate(1000000.0f);
video_output_.reset(new VideoOutput(ram_));
if(!colour_rom_.empty()) video_output_->set_colour_rom(colour_rom_);
set_video_signal(Outputs::CRT::VideoSignal::RGB);
set_video_signal(Outputs::Display::VideoSignal::RGB);
}
void close_output() override final {
video_output_.reset();
}
Outputs::CRT::CRT *get_crt() override final {
return video_output_->get_crt();
}
// void close_output() override final {
// video_output_.reset();
// }
//
// Outputs::CRT::CRT *get_crt() override final {
// return video_output_->get_crt();
// }
Outputs::Speaker::Speaker *get_speaker() override final {
return &speaker_;
@ -537,7 +537,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
}
}
void set_video_signal(Outputs::CRT::VideoSignal video_signal) override {
void set_video_signal(Outputs::Display::VideoSignal video_signal) override {
video_output_->set_video_signal(video_signal);
}

@ -8,6 +8,8 @@
#include "Video.hpp"
#include <algorithm>
using namespace Oric;
namespace {
@ -21,7 +23,7 @@ namespace {
VideoOutput::VideoOutput(uint8_t *memory) :
ram_(memory),
crt_(new Outputs::CRT::CRT(64*6, 6, Outputs::CRT::DisplayType::PAL50, 2)),
crt_(new Outputs::CRT::CRT(64*6, 6, Outputs::Display::Type::PAL50, 2)),
v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition),
counter_period_(PAL50Period) {
// crt_->set_rgb_sampling_function(
@ -41,11 +43,11 @@ VideoOutput::VideoOutput(uint8_t *memory) :
// );
crt_->set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 0.0f);
set_video_signal(Outputs::CRT::VideoSignal::Composite);
set_video_signal(Outputs::Display::VideoSignal::Composite);
crt_->set_visible_area(crt_->get_rect_for_area(54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f));
}
void VideoOutput::set_video_signal(Outputs::CRT::VideoSignal video_signal) {
void VideoOutput::set_video_signal(Outputs::Display::VideoSignal video_signal) {
video_signal_ = video_signal;
// crt_->set_video_signal(video_signal);
}
@ -129,7 +131,7 @@ void VideoOutput::run_for(const Cycles cycles) {
if(control_byte & 0x60) {
if(pixel_target_) {
uint16_t colours[2];
if(video_signal_ == Outputs::CRT::VideoSignal::RGB) {
if(video_signal_ == Outputs::Display::VideoSignal::RGB) {
colours[0] = static_cast<uint8_t>(paper_ ^ inverse_mask);
colours[1] = static_cast<uint8_t>(ink_ ^ inverse_mask);
} else {
@ -183,7 +185,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] =
(video_signal_ == Outputs::CRT::VideoSignal::RGB) ? paper_ ^ inverse_mask : colour_forms_[paper_ ^ inverse_mask];
(video_signal_ == Outputs::Display::VideoSignal::RGB) ? paper_ ^ inverse_mask : colour_forms_[paper_ ^ inverse_mask];
}
}
if(pixel_target_) pixel_target_ += 6;

@ -12,6 +12,10 @@
#include "../../Outputs/CRT/CRT.hpp"
#include "../../ClockReceiver/ClockReceiver.hpp"
#include <cstdint>
#include <memory>
#include <vector>
namespace Oric {
class VideoOutput {
@ -20,7 +24,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_video_signal(Outputs::CRT::VideoSignal output_device);
void set_video_signal(Outputs::Display::VideoSignal output_device);
private:
uint8_t *ram_;
@ -33,7 +37,7 @@ class VideoOutput {
// Output target and device
uint16_t *pixel_target_;
uint16_t colour_forms_[8];
Outputs::CRT::VideoSignal video_signal_;
Outputs::Display::VideoSignal video_signal_;
// Registers
uint8_t ink_, paper_;

@ -8,6 +8,8 @@
#include "Video.hpp"
#include <algorithm>
using namespace ZX8081;
namespace {
@ -21,7 +23,7 @@ const std::size_t StandardAllocationSize = 320;
}
Video::Video() :
crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1)) {
crt_(new Outputs::CRT::CRT(207 * 2, 1, Outputs::Display::Type::PAL50, 1)) {
// Set a composite sampling function that assumes two-level input; either a byte is 0, which is black,
// or it is non-zero, which is white.
@ -32,8 +34,8 @@ Video::Video() :
// "}");
// Show only the centre 80% of the TV frame.
// crt_->set_video_signal(Outputs::CRT::VideoSignal::Composite);
crt_->set_visible_area(Outputs::CRT::Rect(0.1f, 0.1f, 0.8f, 0.8f));
// crt_->set_video_signal(Outputs::Display::VideoSignal::Composite);
crt_->set_visible_area(Outputs::Display::Rect(0.1f, 0.1f, 0.8f, 0.8f));
}
void Video::run_for(const HalfCycles half_cycles) {

@ -310,18 +310,10 @@ template<bool is_zx81> class ConcreteMachine:
}
}
void setup_output(float aspect_ratio) override final {
void setup_output(Outputs::Display::ScanTarget *scan_target) override final {
video_.reset(new Video);
}
void close_output() override final {
video_.reset();
}
Outputs::CRT::CRT *get_crt() override final {
return video_->get_crt();
}
Outputs::Speaker::Speaker *get_speaker() override final {
return is_zx81 ? &speaker_ : nullptr;
}

@ -94,13 +94,6 @@
4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B83348B1F5DB99C0097E338 /* 6522Base.cpp */; };
4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334891F5DB94B0097E338 /* IRQDelegatePortHandler.cpp */; };
4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; };
4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */; };
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */; };
4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */; };
4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */; };
4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */; };
4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; };
4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
4B055AE91FAE9B990060FFFF /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; };
4B055AEA1FAE9B990060FFFF /* 6502Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334851F5DA3780097E338 /* 6502Storage.cpp */; };
@ -203,7 +196,6 @@
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
4B5073071DDD3B9400C48FBD /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; };
4B50730A1DDFCFDF00C48FBD /* ArrayBuilderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */; };
4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; };
4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */; };
@ -600,29 +592,21 @@
4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BB73EAA1B587A5100552FC2 /* MainMenu.xib */; };
4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */; };
4BB73EC21B587A5100552FC2 /* Clock_SignalUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EC11B587A5100552FC2 /* Clock_SignalUITests.swift */; };
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */; };
4BBB70A4202011C2002FE009 /* MultiMediaTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A3202011C2002FE009 /* MultiMediaTarget.cpp */; };
4BBB70A5202011C2002FE009 /* MultiMediaTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A3202011C2002FE009 /* MultiMediaTarget.cpp */; };
4BBB70A8202014E2002FE009 /* MultiCRTMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A6202014E2002FE009 /* MultiCRTMachine.cpp */; };
4BBB70A9202014E2002FE009 /* MultiCRTMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB70A6202014E2002FE009 /* MultiCRTMachine.cpp */; };
4BBC951E1F368D83008F4C34 /* i8272.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC951C1F368D83008F4C34 /* i8272.cpp */; };
4BBF49AF1ED2880200AB3669 /* FUSETests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF49AE1ED2880200AB3669 /* FUSETests.swift */; };
4BBF99141C8FBA6F0075DAFB /* TextureBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* TextureBuilder.cpp */; };
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */; };
4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */; };
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */; };
4BBFE83D21015D9C00BF1C40 /* CSJoystickManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFE83C21015D9C00BF1C40 /* CSJoystickManager.m */; };
4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBFFEE51F7B27F1005F3FEB /* TrackSerialiser.cpp */; };
4BC39568208EE6CF0044766B /* DiskIICard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC39566208EE6CF0044766B /* DiskIICard.cpp */; };
4BC39569208EE6CF0044766B /* DiskIICard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC39566208EE6CF0044766B /* DiskIICard.cpp */; };
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; };
4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */; };
4BC5FC3020CDDDEF00410AA0 /* AppleIIOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BC5FC2E20CDDDEE00410AA0 /* AppleIIOptions.xib */; };
4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B11D157E61006C31D9 /* 6522Tests.swift */; };
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
4BC891AD20F6EAB300EDE5B3 /* Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC891AB20F6EAB300EDE5B3 /* Rectangle.cpp */; };
4BC891AE20F6EAB300EDE5B3 /* Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC891AB20F6EAB300EDE5B3 /* Rectangle.cpp */; };
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
@ -718,7 +702,6 @@
4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTConstants.hpp; sourceTree = "<group>"; };
4B0CCC421C62D0B3001CAC5F /* CRT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRT.cpp; sourceTree = "<group>"; };
4B0CCC431C62D0B3001CAC5F /* CRT.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRT.hpp; sourceTree = "<group>"; };
4B0CD7252189117C00665042 /* ScanTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
4B0E04E81FC9E5DA00F43484 /* CAS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CAS.cpp; sourceTree = "<group>"; };
4B0E04E91FC9E5DA00F43484 /* CAS.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CAS.hpp; sourceTree = "<group>"; };
4B0E04F81FC9FA3000F43484 /* 9918.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = 9918.hpp; path = 9918/9918.hpp; sourceTree = "<group>"; };
@ -1358,7 +1341,6 @@
4BBF990F1C8FBA6F0075DAFB /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = "<group>"; };
4BBF99131C8FBA6F0075DAFB /* TextureTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureTarget.hpp; sourceTree = "<group>"; };
4BBF99191C8FC2750075DAFB /* CRTTypes.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTTypes.hpp; sourceTree = "<group>"; };
4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ZX8081.cpp; path = Parsers/ZX8081.cpp; sourceTree = "<group>"; };
4BBFBB6B1EE8401E00C01E7A /* ZX8081.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ZX8081.hpp; path = Parsers/ZX8081.hpp; sourceTree = "<group>"; };
4BBFE83C21015D9C00BF1C40 /* CSJoystickManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSJoystickManager.m; sourceTree = "<group>"; };
@ -1455,6 +1437,7 @@
4BF437ED209D0F7E008CBD6B /* SegmentParser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SegmentParser.hpp; sourceTree = "<group>"; };
4BF437F0209D112F008CBD6B /* Sector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sector.hpp; sourceTree = "<group>"; };
4BF4A2D91F534DB300B171F4 /* TargetPlatforms.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TargetPlatforms.hpp; sourceTree = "<group>"; };
4BF52672218E752E00313227 /* ScanTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScanTarget.hpp; path = ../../Outputs/ScanTarget.hpp; sourceTree = "<group>"; };
4BF6606A1F281573002CB053 /* ClockReceiver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClockReceiver.hpp; sourceTree = "<group>"; };
4BF8295F1D8F3C87001BAE39 /* CRC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRC.hpp; path = ../../NumberTheory/CRC.hpp; sourceTree = "<group>"; };
4BFCA1211ECBDCAF00AC40C1 /* AllRAMProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllRAMProcessor.cpp; sourceTree = "<group>"; };
@ -1528,10 +1511,8 @@
4B0CCC411C62D0B3001CAC5F /* CRT */ = {
isa = PBXGroup;
children = (
4B0CD7252189117C00665042 /* ScanTarget.hpp */,
4B0CCC421C62D0B3001CAC5F /* CRT.cpp */,
4B0CCC431C62D0B3001CAC5F /* CRT.hpp */,
4BBF99191C8FC2750075DAFB /* CRTTypes.hpp */,
4BBF99071C8FBA6F0075DAFB /* Internals */,
);
name = CRT;
@ -1793,9 +1774,10 @@
4B366DFD1B5C165F0026627B /* Outputs */ = {
isa = PBXGroup;
children = (
4BD601A920D89F2A00CBCE57 /* Log.hpp */,
4BF52672218E752E00313227 /* ScanTarget.hpp */,
4B0CCC411C62D0B3001CAC5F /* CRT */,
4BD060A41FE49D3C006E14BE /* Speaker */,
4BD601A920D89F2A00CBCE57 /* Log.hpp */,
);
name = Outputs;
sourceTree = "<group>";
@ -3657,11 +3639,9 @@
4B055A9A1FAE85CB0060FFFF /* MFMDiskController.cpp in Sources */,
4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */,
4B055AA41FAE85E50060FFFF /* DigitalPhaseLockedLoop.cpp in Sources */,
4B055AE61FAE9B6F0060FFFF /* OutputShader.cpp in Sources */,
4B055A9B1FAE85DA0060FFFF /* AcornADF.cpp in Sources */,
4B0E04F11FC9EA9500F43484 /* MSX.cpp in Sources */,
4B055AD51FAE9B0B0060FFFF /* Video.cpp in Sources */,
4B055AE11FAE9B6F0060FFFF /* ArrayBuilder.cpp in Sources */,
4B894521201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B7F188F2154825E00388727 /* MasterSystem.cpp in Sources */,
4B055AA51FAE85EF0060FFFF /* Encoder.cpp in Sources */,
@ -3675,10 +3655,8 @@
4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */,
4B89452F201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B894531201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BC891AE20F6EAB300EDE5B3 /* Rectangle.cpp in Sources */,
4B894539201967B4007DE474 /* Tape.cpp in Sources */,
4B7F1898215486A200388727 /* StaticAnalyser.cpp in Sources */,
4B055AE51FAE9B6F0060FFFF /* IntermediateShader.cpp in Sources */,
4B15A9FD208249BB005E6C8D /* StaticAnalyser.cpp in Sources */,
4B055AD31FAE9B0B0060FFFF /* Microdisc.cpp in Sources */,
4B055AB41FAE860F0060FFFF /* OricTAP.cpp in Sources */,
@ -3702,7 +3680,6 @@
4B89452B201967B4007DE474 /* File.cpp in Sources */,
4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */,
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */,
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */,
@ -3723,7 +3700,6 @@
4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */,
4B055AC51FAE9AEE0060FFFF /* Atari2600.cpp in Sources */,
4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */,
4B055AE41FAE9B6F0060FFFF /* TextureTarget.cpp in Sources */,
4B055ABA1FAE86170060FFFF /* Commodore.cpp in Sources */,
4B9BE401203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */,
4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */,
@ -3785,12 +3761,10 @@
4B894537201967B4007DE474 /* Z80.cpp in Sources */,
4B055A9F1FAE85DA0060FFFF /* HFE.cpp in Sources */,
4B07835B1FC11D42001D12BB /* Configurable.cpp in Sources */,
4B055AE71FAE9B6F0060FFFF /* Shader.cpp in Sources */,
4B894523201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B055AEC1FAE9BA20060FFFF /* Z80Base.cpp in Sources */,
4B0F94FF208C1A1600FE41D9 /* NIB.cpp in Sources */,
4B0E04EB1FC9E78800F43484 /* CAS.cpp in Sources */,
4B055AE31FAE9B6F0060FFFF /* TextureBuilder.cpp in Sources */,
4BB0A65D2045009000FB3688 /* ColecoVision.cpp in Sources */,
4BB0A65C2044FD3000FB3688 /* SN76489.cpp in Sources */,
4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
@ -3823,7 +3797,6 @@
4B58601E1F806AB200AEE2E3 /* MFMSectorDump.cpp in Sources */,
4B448E841F1C4C480009ABD6 /* PulseQueuedTape.cpp in Sources */,
4B0E61071FF34737002A9DBD /* MSX.cpp in Sources */,
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */,
4B4518A01F75FD1C00926311 /* CPCDSK.cpp in Sources */,
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
4B322E041F5A2E3C004EB04C /* Z80Base.cpp in Sources */,
@ -3852,14 +3825,12 @@
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */,
4BAE49582032881E004BE78E /* CSZX8081.mm in Sources */,
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */,
4B894518201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */,
4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */,
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */,
4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4BB0A65B2044FD3000FB3688 /* SN76489.cpp in Sources */,
4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.mm in Sources */,
@ -3867,7 +3838,6 @@
4BDB61EC203285AE0048AF91 /* Atari2600OptionsPanel.swift in Sources */,
4BBB70A8202014E2002FE009 /* MultiCRTMachine.cpp in Sources */,
4B8805F71DCFF6C9003085B1 /* Commodore.cpp in Sources */,
4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */,
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */,
4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */,
4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */,
@ -3903,9 +3873,7 @@
4BD468F71D8DF41D0084958B /* 1770.cpp in Sources */,
4B7F1897215486A200388727 /* StaticAnalyser.cpp in Sources */,
4BD3A30B1EE755C800B5B501 /* Video.cpp in Sources */,
4BBF99141C8FBA6F0075DAFB /* TextureBuilder.cpp in Sources */,
4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */,
4BC891AD20F6EAB300EDE5B3 /* Rectangle.cpp in Sources */,
4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */,
4B1497881EE4A1DA00CE2596 /* ZX80O81P.cpp in Sources */,
4B894520201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
@ -3951,8 +3919,6 @@
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */,
4BFDD78C1F7F2DB4008579B9 /* ImplicitSectors.cpp in Sources */,
4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */,
4B5073071DDD3B9400C48FBD /* ArrayBuilder.cpp in Sources */,
4B894526201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */,
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */,

@ -26,6 +26,9 @@
#include <bitset>
#import <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h>
@interface CSMachine() <CSFastLoading>
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
- (void)speakerDidChangeInputClock:(Outputs::Speaker::Speaker *)speaker;
@ -131,11 +134,11 @@ struct ActivityObserver: public Activity::Observer {
_speakerDelegate.machine = nil;
[_delegateMachineAccessLock unlock];
[_view performWithGLContext:^{
@synchronized(self) {
self->_machine->crt_machine()->close_output();
}
}];
// [_view performWithGLContext:^{
// @synchronized(self) {
// self->_machine->crt_machine()->close_output();
// }
// }];
}
- (float)idealSamplingRateFromRange:(NSRange)range {
@ -228,7 +231,7 @@ struct ActivityObserver: public Activity::Observer {
}
- (void)setupOutputWithAspectRatio:(float)aspectRatio {
_machine->crt_machine()->setup_output(aspectRatio);
// _machine->crt_machine()->setup_output(aspectRatio);
// Since OS X v10.6, Macs have had a gamma of 2.2.
// _machine->crt_machine()->get_crt()->set_output_gamma(2.2f);

@ -7,7 +7,7 @@
//
#include "CRT.hpp"
#include "Internals/CRTOpenGL.hpp"
#include <cstdarg>
#include <cmath>
#include <algorithm>
@ -15,7 +15,7 @@
using namespace Outputs::CRT;
void CRT::set_new_timing(int cycles_per_line, int height_of_display, ColourSpace colour_space, int colour_cycle_numerator, int colour_cycle_denominator, int vertical_sync_half_lines, bool should_alternate) {
void CRT::set_new_timing(int cycles_per_line, int height_of_display, Outputs::Display::ColourSpace colour_space, int colour_cycle_numerator, int colour_cycle_denominator, int vertical_sync_half_lines, bool should_alternate) {
// openGL_output_builder_.set_colour_format(colour_space, colour_cycle_numerator, colour_cycle_denominator);
const int millisecondsHorizontalRetraceTime = 7; // source: Dictionary of Video and Television Technology, p. 234
@ -28,7 +28,8 @@ void CRT::set_new_timing(int cycles_per_line, int height_of_display, ColourSpace
// 7 microseconds for horizontal retrace and 500 to 750 microseconds for vertical retrace
// in NTSC and PAL TV."
time_multiplier_ = IntermediateBufferWidth / cycles_per_line;
// time_multiplier_ = IntermediateBufferWidth / cycles_per_line;
time_multiplier_ = 2048 / cycles_per_line; // TODO
phase_denominator_ = cycles_per_line * colour_cycle_denominator * time_multiplier_;
phase_numerator_ = 0;
colour_cycle_numerator_ = colour_cycle_numerator;
@ -63,15 +64,15 @@ void CRT::set_new_timing(int cycles_per_line, int height_of_display, ColourSpace
// TODO: set scan_target modals.
}
void CRT::set_new_display_type(int cycles_per_line, DisplayType displayType) {
void CRT::set_new_display_type(int cycles_per_line, Outputs::Display::Type displayType) {
switch(displayType) {
case DisplayType::PAL50:
set_new_timing(cycles_per_line, 312, ColourSpace::YUV, 709379, 2500, 5, true); // i.e. 283.7516; 2.5 lines = vertical sync
case Outputs::Display::Type::PAL50:
set_new_timing(cycles_per_line, 312, Outputs::Display::ColourSpace::YUV, 709379, 2500, 5, true); // i.e. 283.7516; 2.5 lines = vertical sync
set_input_gamma(2.8f);
break;
case DisplayType::NTSC60:
set_new_timing(cycles_per_line, 262, ColourSpace::YIQ, 455, 2, 6, false); // i.e. 227.5, 3 lines = vertical sync
case Outputs::Display::Type::NTSC60:
set_new_timing(cycles_per_line, 262, Outputs::Display::ColourSpace::YIQ, 455, 2, 6, false); // i.e. 227.5, 3 lines = vertical sync
set_input_gamma(2.2f);
break;
}
@ -96,7 +97,7 @@ CRT::CRT(int common_output_divisor, int buffer_depth) :
CRT::CRT( int cycles_per_line,
int common_output_divisor,
int height_of_display,
ColourSpace colour_space,
Outputs::Display::ColourSpace colour_space,
int colour_cycle_numerator, int colour_cycle_denominator,
int vertical_sync_half_lines,
bool should_alternate,
@ -105,7 +106,7 @@ CRT::CRT( int cycles_per_line,
set_new_timing(cycles_per_line, height_of_display, colour_space, colour_cycle_numerator, colour_cycle_denominator, vertical_sync_half_lines, should_alternate);
}
CRT::CRT(int cycles_per_line, int common_output_divisor, DisplayType displayType, int buffer_depth) :
CRT::CRT(int cycles_per_line, int common_output_divisor, Outputs::Display::Type displayType, int buffer_depth) :
CRT(common_output_divisor, buffer_depth) {
set_new_display_type(cycles_per_line, displayType);
}
@ -141,7 +142,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_
// Determine whether to output any data for this portion of the output; if so then grab somewhere to put it.
bool is_output_segment = ((is_output_run && next_run_length) && !horizontal_flywheel_->is_in_retrace() && !vertical_flywheel_->is_in_retrace());
ScanTarget::Scan *const next_scan = is_output_segment ? scan_target_->get_scan() : nullptr;
Outputs::Display::ScanTarget::Scan *const next_scan = is_output_segment ? scan_target_->get_scan() : nullptr;
// If outputting, store the start location and
if(next_scan) {
@ -171,14 +172,14 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_
// If this is horizontal retrace then announce as such, and prepare for the next line.
if(next_run_length == time_until_horizontal_sync_event && next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace) {
scan_target_->announce(Outputs::CRT::ScanTarget::Event::HorizontalRetrace);
scan_target_->announce(Outputs::Display::ScanTarget::Event::HorizontalRetrace);
is_alernate_line_ ^= phase_alternates_;
colour_burst_amplitude_ = 0;
}
// Also announce if this is vertical retrace.
if(next_run_length == time_until_vertical_sync_event && next_horizontal_sync_event == Flywheel::SyncEvent::StartRetrace) {
scan_target_->announce(Outputs::CRT::ScanTarget::Event::VerticalRetrace);
scan_target_->announce(Outputs::Display::ScanTarget::Event::VerticalRetrace);
}
// if this is vertical retrace then adcance a field
@ -314,7 +315,7 @@ void CRT::output_data(int number_of_cycles, size_t number_of_samples) {
output_scan(&scan);
}
Outputs::CRT::Rect CRT::get_rect_for_area(int first_line_after_sync, int number_of_lines, int first_cycle_after_sync, int number_of_cycles, float aspect_ratio) {
Outputs::Display::Rect CRT::get_rect_for_area(int first_line_after_sync, int number_of_lines, int first_cycle_after_sync, int number_of_cycles, float aspect_ratio) {
first_cycle_after_sync *= time_multiplier_;
number_of_cycles *= time_multiplier_;
@ -359,5 +360,5 @@ Outputs::CRT::Rect CRT::get_rect_for_area(int first_line_after_sync, int number_
height = ideal_height;
}
return Rect(start_x, start_y, width, height);
return Outputs::Display::Rect(start_x, start_y, width, height);
}

@ -10,14 +10,10 @@
#define CRT_hpp
#include <cstdint>
#include <memory>
#include "CRTTypes.hpp"
#include "../ScanTarget.hpp"
#include "Internals/Flywheel.hpp"
#include "Internals/CRTOpenGL.hpp"
#include "Internals/ArrayBuilder.hpp"
#include "Internals/TextureBuilder.hpp"
#include "ScanTarget.hpp"
namespace Outputs {
namespace CRT {
@ -85,7 +81,7 @@ class CRT {
int cycles_per_line_ = 1;
ScanTarget *scan_target_ = nullptr;
Outputs::Display::ScanTarget *scan_target_ = nullptr;
public:
/*! Constructs the CRT with a specified clock rate, height and colour subcarrier frequency.
@ -122,7 +118,7 @@ class CRT {
CRT(int cycles_per_line,
int common_output_divisor,
int height_of_display,
ColourSpace colour_space,
Outputs::Display::ColourSpace colour_space,
int colour_cycle_numerator, int colour_cycle_denominator,
int vertical_sync_half_lines,
bool should_alternate,
@ -137,16 +133,23 @@ class CRT {
*/
CRT(int cycles_per_line,
int common_output_divisor,
DisplayType displayType,
Outputs::Display::Type display_type,
int buffer_depth);
/*! Resets the CRT with new timing information. The CRT then continues as though the new timing had
been provided at construction. */
void set_new_timing(int cycles_per_line, int height_of_display, ColourSpace colour_space, int colour_cycle_numerator, int colour_cycle_denominator, int vertical_sync_half_lines, bool should_alternate);
void set_new_timing(
int cycles_per_line,
int height_of_display,
Outputs::Display::ColourSpace colour_space,
int colour_cycle_numerator,
int colour_cycle_denominator,
int vertical_sync_half_lines,
bool should_alternate);
/*! Resets the CRT with new timing information derived from a new display type. The CRT then continues
as though the new timing had been provided at construction. */
void set_new_display_type(int cycles_per_line, DisplayType displayType);
void set_new_display_type(int cycles_per_line, Outputs::Display::Type display_type);
/*! Output at the sync level.
@ -246,10 +249,15 @@ class CRT {
*/
void set_composite_function_type(CompositeSourceType type, float offset_of_first_sample = 0.0f);
inline void set_visible_area(Rect visible_area) {
inline void set_visible_area(Outputs::Display::Rect visible_area) {
}
Rect get_rect_for_area(int first_line_after_sync, int number_of_lines, int first_cycle_after_sync, int number_of_cycles, float aspect_ratio);
Outputs::Display::Rect get_rect_for_area(
int first_line_after_sync,
int number_of_lines,
int first_cycle_after_sync,
int number_of_cycles,
float aspect_ratio);
inline void set_delegate(Delegate *delegate) {
delegate_ = delegate;

@ -1,29 +0,0 @@
//
// CRTTypes.hpp
// Clock Signal
//
// Created by Thomas Harte on 08/03/2016.
// Copyright 2016 Thomas Harte. All rights reserved.
//
#ifndef CRTTypes_h
#define CRTTypes_h
namespace Outputs {
namespace CRT {
enum class DisplayType {
PAL50,
NTSC60
};
enum class VideoSignal {
RGB,
SVideo,
Composite
};
}
}
#endif /* CRTTypes_h */

@ -9,7 +9,6 @@
#ifndef CRTOpenGL_h
#define CRTOpenGL_h
#include "../CRTTypes.hpp"
#include "CRTConstants.hpp"
#include "OpenGL.hpp"
#include "TextureTarget.hpp"

@ -92,7 +92,7 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
}));
}
void OutputShader::set_output_size(unsigned int output_width, unsigned int output_height, Outputs::CRT::Rect visible_area) {
void OutputShader::set_output_size(unsigned int output_width, unsigned int output_height, Outputs::Display::Rect visible_area) {
GLfloat outputAspectRatioMultiplier = (static_cast<float>(output_width) / static_cast<float>(output_height)) / (4.0f / 3.0f);
GLfloat bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width;

@ -10,7 +10,6 @@
#define OutputShader_hpp
#include "Shader.hpp"
#include "../../CRTTypes.hpp"
#include "../../ScanTarget.hpp"
#include <memory>
@ -64,7 +63,7 @@ public:
the largest possible drawing size that allows everything within `visible_area` to be visible, to
occur upon the next `bind`.
*/
void set_output_size(unsigned int output_width, unsigned int output_height, Outputs::CRT::Rect visible_area);
void set_output_size(unsigned int output_width, unsigned int output_height, Outputs::Display::Rect visible_area);
/*!
Queues setting of the texture unit (as an enum, e.g. `GL_TEXTURE0`) for source data upon the next `bind`.

@ -6,11 +6,24 @@
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef Outputs_CRT_ScanTarget_h
#define Outputs_CRT_ScanTarget_h
#ifndef Outputs_Display_ScanTarget_h
#define Outputs_Display_ScanTarget_h
#include <cstddef>
namespace Outputs {
namespace CRT {
namespace Display {
enum class Type {
PAL50,
NTSC60
};
enum class VideoSignal {
RGB,
SVideo,
Composite
};
struct Rect {
struct Point {
@ -161,11 +174,11 @@ struct ScanTarget {
/// Calls will be paired off with calls to @c reduce_previous_allocation_to.
///
/// @returns a pointer to the allocated space if any was available; @c nullptr otherwise.
virtual uint8_t *allocate_write_area(std::size_t required_length, std::size_t required_alignment = 1) = 0;
virtual uint8_t *allocate_write_area(size_t required_length, size_t required_alignment = 1) = 0;
/// Announces that the owner is finished with the region created by the most recent @c allocate_write_area
/// and indicates that its actual final size was @c actual_length.
virtual void reduce_previous_allocation_to(std::size_t actual_length) = 0;
virtual void reduce_previous_allocation_to(size_t actual_length) = 0;
/// Announces that all endpoint pairs and write areas obtained since the last @c submit have now been
/// populated with appropriate data.
@ -202,4 +215,4 @@ struct ScanTarget {
}
}
#endif /* Outputs_CRT_ScanTarget_h */
#endif /* Outputs_Display_ScanTarget_h */