2016-05-31 21:23:44 -04:00
|
|
|
//
|
|
|
|
// CRTMachine.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 31/05/2016.
|
2018-05-13 15:19:52 -04:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-05-31 21:23:44 -04:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef CRTMachine_hpp
|
|
|
|
#define CRTMachine_hpp
|
|
|
|
|
2018-11-03 21:54:25 -04:00
|
|
|
#include "../Outputs/ScanTarget.hpp"
|
2017-12-17 21:26:06 -05:00
|
|
|
#include "../Outputs/Speaker/Speaker.hpp"
|
2017-07-25 20:20:55 -04:00
|
|
|
#include "../ClockReceiver/ClockReceiver.hpp"
|
2018-03-21 22:18:13 -04:00
|
|
|
#include "../ClockReceiver/TimeTypes.hpp"
|
2017-11-07 21:19:51 -05:00
|
|
|
#include "ROMMachine.hpp"
|
2016-05-31 21:23:44 -04:00
|
|
|
|
2018-03-31 22:14:34 -04:00
|
|
|
#include "../Configurable/StandardOptions.hpp"
|
|
|
|
|
2018-03-21 22:18:13 -04:00
|
|
|
#include <cmath>
|
|
|
|
|
2018-11-03 21:54:25 -04:00
|
|
|
// TODO: rename.
|
2016-05-31 21:23:44 -04:00
|
|
|
namespace CRTMachine {
|
|
|
|
|
2016-06-30 08:46:29 -04:00
|
|
|
/*!
|
|
|
|
A CRTMachine::Machine is a mostly-abstract base class for machines that connect to a CRT,
|
|
|
|
that optionally provide a speaker, and that nominate a clock rate and can announce to a delegate
|
|
|
|
should that clock rate change.
|
|
|
|
*/
|
2018-07-10 20:00:46 -04:00
|
|
|
class Machine {
|
2016-05-31 21:23:44 -04:00
|
|
|
public:
|
2017-07-22 17:31:12 -04:00
|
|
|
/*!
|
2018-11-03 21:54:25 -04:00
|
|
|
Causes the machine to set up its display and, if it has one, speaker.
|
2017-07-22 17:31:12 -04:00
|
|
|
|
2018-11-03 21:54:25 -04:00
|
|
|
The @c scan_target will receive all video output; the caller guarantees
|
|
|
|
that it is non-null.
|
2017-07-22 17:31:12 -04:00
|
|
|
*/
|
2018-11-14 21:52:57 -05:00
|
|
|
virtual void set_scan_target(Outputs::Display::ScanTarget *scan_target) = 0;
|
2017-07-22 17:31:12 -04:00
|
|
|
|
|
|
|
/// @returns The speaker that receives this machine's output, or @c nullptr if this machine is mute.
|
2017-12-17 21:26:06 -05:00
|
|
|
virtual Outputs::Speaker::Speaker *get_speaker() = 0;
|
2016-05-31 21:23:44 -04:00
|
|
|
|
2018-02-01 07:53:52 -05:00
|
|
|
/// @returns The confidence that this machine is running content it understands.
|
|
|
|
virtual float get_confidence() { return 0.5f; }
|
2019-03-02 18:07:05 -05:00
|
|
|
virtual std::string debug_type() { return ""; }
|
2018-02-01 07:53:52 -05:00
|
|
|
|
2018-03-21 22:18:13 -04:00
|
|
|
/// Runs the machine for @c duration seconds.
|
|
|
|
virtual void run_for(Time::Seconds duration) {
|
|
|
|
const double cycles = (duration * clock_rate_) + clock_conversion_error_;
|
|
|
|
clock_conversion_error_ = std::fmod(cycles, 1.0);
|
|
|
|
run_for(Cycles(static_cast<int>(cycles)));
|
2016-08-14 13:33:20 -04:00
|
|
|
}
|
2018-03-21 22:18:13 -04:00
|
|
|
|
2016-06-16 20:39:46 -04:00
|
|
|
protected:
|
2018-03-21 22:18:13 -04:00
|
|
|
/// Runs the machine for @c cycles.
|
|
|
|
virtual void run_for(const Cycles cycles) = 0;
|
2016-08-14 13:33:20 -04:00
|
|
|
void set_clock_rate(double clock_rate) {
|
2018-03-21 22:18:13 -04:00
|
|
|
clock_rate_ = clock_rate;
|
2016-09-12 22:06:03 -04:00
|
|
|
}
|
2018-03-22 10:01:18 -04:00
|
|
|
double get_clock_rate() {
|
|
|
|
return clock_rate_;
|
|
|
|
}
|
2016-08-14 13:33:20 -04:00
|
|
|
|
2018-04-04 19:14:42 -04:00
|
|
|
/*!
|
2018-11-03 21:54:25 -04:00
|
|
|
Maps from Configurable::Display to Outputs::Display::VideoSignal and calls
|
2018-11-28 17:53:33 -08:00
|
|
|
@c set_display_type with the result.
|
2018-04-04 19:14:42 -04:00
|
|
|
*/
|
2018-03-31 22:14:34 -04:00
|
|
|
void set_video_signal_configurable(Configurable::Display type) {
|
2018-11-28 17:53:33 -08:00
|
|
|
Outputs::Display::DisplayType display_type;
|
2018-03-31 22:14:34 -04:00
|
|
|
switch(type) {
|
|
|
|
default:
|
|
|
|
case Configurable::Display::RGB:
|
2018-11-28 17:53:33 -08:00
|
|
|
display_type = Outputs::Display::DisplayType::RGB;
|
2018-03-31 22:14:34 -04:00
|
|
|
break;
|
|
|
|
case Configurable::Display::SVideo:
|
2018-11-28 17:53:33 -08:00
|
|
|
display_type = Outputs::Display::DisplayType::SVideo;
|
2018-03-31 22:14:34 -04:00
|
|
|
break;
|
2018-11-28 17:53:33 -08:00
|
|
|
case Configurable::Display::CompositeColour:
|
|
|
|
display_type = Outputs::Display::DisplayType::CompositeColour;
|
|
|
|
break;
|
|
|
|
case Configurable::Display::CompositeMonochrome:
|
|
|
|
display_type = Outputs::Display::DisplayType::CompositeMonochrome;
|
2018-03-31 22:14:34 -04:00
|
|
|
break;
|
|
|
|
}
|
2018-11-28 17:53:33 -08:00
|
|
|
set_display_type(display_type);
|
2018-04-04 19:14:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2018-11-28 17:53:33 -08:00
|
|
|
Forwards the video signal to the target returned by get_crt().
|
2018-04-04 19:14:42 -04:00
|
|
|
*/
|
2018-11-28 17:53:33 -08:00
|
|
|
virtual void set_display_type(Outputs::Display::DisplayType display_type) {}
|
2018-03-31 22:14:34 -04:00
|
|
|
|
2016-08-14 13:33:20 -04:00
|
|
|
private:
|
2017-11-10 22:08:40 -05:00
|
|
|
double clock_rate_ = 1.0;
|
2018-03-21 22:18:13 -04:00
|
|
|
double clock_conversion_error_ = 0.0;
|
2016-05-31 21:23:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* CRTMachine_hpp */
|