mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-11 15:49:38 +00:00
102 lines
3.1 KiB
C++
102 lines
3.1 KiB
C++
//
|
|
// ScanProducer.hpp
|
|
// Clock Signal
|
|
//
|
|
// Created by Thomas Harte on 31/03/2020.
|
|
// Copyright 2020 Thomas Harte. All rights reserved.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include "../Outputs/ScanTarget.hpp"
|
|
#include "../Configurable/StandardOptions.hpp"
|
|
|
|
#include "TimedMachine.hpp"
|
|
|
|
namespace MachineTypes {
|
|
|
|
/*!
|
|
A ScanProducer::Producer is any machine that produces video output of the form accepted
|
|
by a ScanTarget.
|
|
*/
|
|
class ScanProducer {
|
|
public:
|
|
/*!
|
|
Causes the machine to set up its display and, if it has one, speaker.
|
|
|
|
The @c scan_target will receive all video output; the caller guarantees
|
|
that it is non-null.
|
|
*/
|
|
virtual void set_scan_target(Outputs::Display::ScanTarget *) = 0;
|
|
|
|
/*!
|
|
@returns The current scan status.
|
|
*/
|
|
virtual Outputs::Display::ScanStatus get_scan_status() const {
|
|
// There's an implicit assumption here that anything which produces scans
|
|
// is also a timed machine. And, also, that this function will be called infrequently.
|
|
const TimedMachine *timed_machine = dynamic_cast<const TimedMachine *>(this);
|
|
return get_scaled_scan_status() / float(timed_machine->get_clock_rate());
|
|
}
|
|
|
|
protected:
|
|
virtual Outputs::Display::ScanStatus get_scaled_scan_status() const {
|
|
// This deliberately sets up an infinite loop if the user hasn't
|
|
// overridden at least one of this or get_scan_status.
|
|
//
|
|
// Most likely you want to override this, and let the base class
|
|
// throw in a divide-by-clock-rate at the end for you.
|
|
return get_scan_status();
|
|
}
|
|
|
|
/*!
|
|
Maps from Configurable::Display to Outputs::Display::VideoSignal and calls
|
|
@c set_display_type with the result.
|
|
*/
|
|
void set_video_signal_configurable(const Configurable::Display type) {
|
|
Outputs::Display::DisplayType display_type;
|
|
switch(type) {
|
|
default:
|
|
case Configurable::Display::RGB:
|
|
display_type = Outputs::Display::DisplayType::RGB;
|
|
break;
|
|
case Configurable::Display::SVideo:
|
|
display_type = Outputs::Display::DisplayType::SVideo;
|
|
break;
|
|
case Configurable::Display::CompositeColour:
|
|
display_type = Outputs::Display::DisplayType::CompositeColour;
|
|
break;
|
|
case Configurable::Display::CompositeMonochrome:
|
|
display_type = Outputs::Display::DisplayType::CompositeMonochrome;
|
|
break;
|
|
}
|
|
set_display_type(display_type);
|
|
}
|
|
|
|
/*!
|
|
Maps back from Outputs::Display::VideoSignal to Configurable::Display,
|
|
calling @c get_display_type for the input.
|
|
*/
|
|
Configurable::Display get_video_signal_configurable() const {
|
|
switch(get_display_type()) {
|
|
default:
|
|
case Outputs::Display::DisplayType::RGB: return Configurable::Display::RGB;
|
|
case Outputs::Display::DisplayType::SVideo: return Configurable::Display::SVideo;
|
|
case Outputs::Display::DisplayType::CompositeColour: return Configurable::Display::CompositeColour;
|
|
case Outputs::Display::DisplayType::CompositeMonochrome: return Configurable::Display::CompositeMonochrome;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Sets the display type.
|
|
*/
|
|
virtual void set_display_type(Outputs::Display::DisplayType) {}
|
|
|
|
/*!
|
|
Gets the display type.
|
|
*/
|
|
virtual Outputs::Display::DisplayType get_display_type() const { return Outputs::Display::DisplayType::RGB; }
|
|
};
|
|
|
|
}
|