2016-06-01 01:23:44 +00:00
|
|
|
//
|
|
|
|
// CRTMachine.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 31/05/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef CRTMachine_hpp
|
|
|
|
#define CRTMachine_hpp
|
|
|
|
|
|
|
|
#include "../Outputs/CRT/CRT.hpp"
|
|
|
|
#include "../Outputs/Speaker.hpp"
|
2017-07-26 00:20:55 +00:00
|
|
|
#include "../ClockReceiver/ClockReceiver.hpp"
|
2016-06-01 01:23:44 +00:00
|
|
|
|
|
|
|
namespace CRTMachine {
|
|
|
|
|
2016-06-30 12:46:29 +00: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.
|
|
|
|
*/
|
2016-06-01 01:23:44 +00:00
|
|
|
class Machine {
|
|
|
|
public:
|
2017-08-01 02:46:06 +00:00
|
|
|
Machine() : clock_is_unlimited_(false), delegate_(nullptr) {}
|
2016-09-13 02:06:03 +00:00
|
|
|
|
2017-07-22 21:31:12 +00:00
|
|
|
/*!
|
|
|
|
Causes the machine to set up its CRT and, if it has one, speaker. The caller guarantees
|
|
|
|
that an OpenGL context is bound.
|
|
|
|
*/
|
2016-06-01 01:23:44 +00:00
|
|
|
virtual void setup_output(float aspect_ratio) = 0;
|
2017-07-22 21:31:12 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Gives the machine a chance to release all owned resources. The caller guarantees that the
|
|
|
|
OpenGL context is bound.
|
|
|
|
*/
|
2016-06-01 01:23:44 +00:00
|
|
|
virtual void close_output() = 0;
|
2017-11-06 01:12:01 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Provides the machine with a way to obtain such ROMs as it needs.
|
|
|
|
*/
|
|
|
|
virtual bool install_roms(const std::function<std::unique_ptr<std::vector<uint8_t>>(const std::string &machine, const std::string &name)> &rom_with_name) { return true; }
|
2016-06-01 01:23:44 +00:00
|
|
|
|
2017-07-22 21:31:12 +00:00
|
|
|
/// @returns The CRT this machine is drawing to. Should not be @c nullptr.
|
2016-07-04 23:33:55 +00:00
|
|
|
virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() = 0;
|
2017-07-22 21:31:12 +00:00
|
|
|
|
|
|
|
/// @returns The speaker that receives this machine's output, or @c nullptr if this machine is mute.
|
2016-07-04 23:33:55 +00:00
|
|
|
virtual std::shared_ptr<Outputs::Speaker> get_speaker() = 0;
|
2016-06-01 01:23:44 +00:00
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
/// Runs the machine for @c cycles.
|
2017-07-28 02:05:29 +00:00
|
|
|
virtual void run_for(const Cycles cycles) = 0;
|
2016-06-17 00:39:46 +00:00
|
|
|
|
2016-06-30 12:46:29 +00:00
|
|
|
// TODO: sever the clock-rate stuff.
|
2016-08-14 17:33:20 +00:00
|
|
|
double get_clock_rate() {
|
|
|
|
return clock_rate_;
|
|
|
|
}
|
2016-09-13 02:06:03 +00:00
|
|
|
bool get_clock_is_unlimited() {
|
|
|
|
return clock_is_unlimited_;
|
|
|
|
}
|
2016-06-17 00:39:46 +00:00
|
|
|
class Delegate {
|
|
|
|
public:
|
|
|
|
virtual void machine_did_change_clock_rate(Machine *machine) = 0;
|
2016-09-13 02:06:03 +00:00
|
|
|
virtual void machine_did_change_clock_is_unlimited(Machine *machine) = 0;
|
2016-06-17 00:39:46 +00:00
|
|
|
};
|
2017-08-01 11:07:43 +00:00
|
|
|
void set_delegate(Delegate *delegate) { delegate_ = delegate; }
|
2016-06-17 00:39:46 +00:00
|
|
|
|
|
|
|
protected:
|
2016-08-14 17:33:20 +00:00
|
|
|
void set_clock_rate(double clock_rate) {
|
|
|
|
if(clock_rate_ != clock_rate) {
|
|
|
|
clock_rate_ = clock_rate;
|
|
|
|
if(delegate_) delegate_->machine_did_change_clock_rate(this);
|
|
|
|
}
|
|
|
|
}
|
2016-09-13 02:06:03 +00:00
|
|
|
void set_clock_is_unlimited(bool clock_is_unlimited) {
|
|
|
|
if(clock_is_unlimited != clock_is_unlimited_) {
|
|
|
|
clock_is_unlimited_ = clock_is_unlimited;
|
|
|
|
if(delegate_) delegate_->machine_did_change_clock_is_unlimited(this);
|
|
|
|
}
|
|
|
|
}
|
2016-08-14 17:33:20 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Delegate *delegate_;
|
2016-09-13 02:06:03 +00:00
|
|
|
double clock_rate_;
|
|
|
|
bool clock_is_unlimited_;
|
2016-06-01 01:23:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* CRTMachine_hpp */
|