1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-10-30 14:16:04 +00:00

Compare commits

..

5 Commits

Author SHA1 Message Date
Thomas Harte
e75c27cb66 Add macOS UI to dynamic cropping option, apply at runtime to CPC. 2025-10-29 21:21:21 -04:00
Thomas Harte
d27f0e3633 Declare that dynamic crop is an option. 2025-10-29 17:43:19 -04:00
Thomas Harte
e19bd0d517 Alphabetise; mark override. 2025-10-29 17:43:05 -04:00
Thomas Harte
3427120b3f Expose dynamic crop option from the CPC. 2025-10-29 17:37:58 -04:00
Thomas Harte
ecc623cd6c Improve option naming, add one for dynamic crop. 2025-10-29 17:19:15 -04:00
44 changed files with 389 additions and 154 deletions

View File

@@ -25,10 +25,12 @@ ReflectableEnum(Display,
// ensure unified property naming.
//===
template <typename Owner> class DisplayOption {
namespace Options {
template <typename Owner> class Display {
public:
Configurable::Display output;
DisplayOption(Configurable::Display output) : output(output) {}
Display(const Configurable::Display output) noexcept : output(output) {}
protected:
void declare_display_option() {
@@ -37,26 +39,38 @@ protected:
}
};
template <typename Owner> class QuickloadOption {
template <typename Owner> class QuickLoad {
public:
bool quickload;
QuickloadOption(bool quickload) : quickload(quickload) {}
bool quick_load;
QuickLoad(const bool quick_load) noexcept : quick_load(quick_load) {}
protected:
void declare_quickload_option() {
static_cast<Owner *>(this)->declare(&quickload, "quickload");
static_cast<Owner *>(this)->declare(&quick_load, "quickload");
}
};
template <typename Owner> class QuickbootOption {
template <typename Owner> class QuickBoot {
public:
bool quickboot;
QuickbootOption(bool quickboot) : quickboot(quickboot) {}
bool quick_boot;
QuickBoot(const bool quick_boot) noexcept : quick_boot(quick_boot) {}
protected:
void declare_quickboot_option() {
static_cast<Owner *>(this)->declare(&quickboot, "quickboot");
static_cast<Owner *>(this)->declare(&quick_boot, "quickboot");
}
};
template <typename Owner> class DynamicCrop {
public:
bool dynamic_crop;
DynamicCrop(const bool dynamic_crop) noexcept : dynamic_crop(dynamic_crop) {}
protected:
void declare_dynamic_crop_option() {
static_cast<Owner *>(this)->declare(&dynamic_crop, "dynamiccrop");
}
};
}
}

View File

@@ -509,13 +509,13 @@ private:
// MARK: - Configuration options.
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->quickload = accelerate_loading_;
options->quick_load = accelerate_loading_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
accelerate_loading_ = options->quickload;
accelerate_loading_ = options->quick_load;
}
// MARK: - AudioProducer

View File

@@ -24,13 +24,13 @@ struct Machine {
const ROMMachine::ROMFetcher &rom_fetcher
);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::QuickLoad<Options> {
friend Configurable::Options::QuickLoad<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
Options(const Configurable::OptionsType type) :
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_quickload_option();

View File

@@ -662,6 +662,7 @@ using CRTC = Motorola::CRTC::CRTC6845<
template <bool has_1770>
class ConcreteMachine:
public Activity::Source,
public Configurable::Device,
public Machine,
public MachineTypes::AudioProducer,
public MachineTypes::JoystickMachine,
@@ -1150,6 +1151,17 @@ private:
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
return joysticks_;
}
// MARK: - Configuration options.
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
(void)options;
}
};
}

View File

@@ -9,6 +9,8 @@
#pragma once
#include "Analyser/Static/StaticAnalyser.hpp"
#include "Configurable/Configurable.hpp"
#include "Configurable/StandardOptions.hpp"
#include "Machines/ROMMachine.hpp"
#include <memory>
@@ -22,6 +24,25 @@ struct Machine {
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
class Options:
public Reflection::StructImpl<Options>,
public Configurable::Options::DynamicCrop<Options>
{
public:
Options(const Configurable::OptionsType type) :
Configurable::Options::DynamicCrop<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
friend Configurable::Options::DynamicCrop<Options>;
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_dynamic_crop_option();
}
};
};
}

View File

@@ -599,7 +599,7 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
return options;
}
@@ -607,7 +607,7 @@ public:
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape_hack();
}

View File

@@ -35,22 +35,22 @@ struct Machine {
/// Defines the runtime options available for an Electron.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
Options(const Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(
Configurable::Options::Display<Options>(
type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour
),
Configurable::QuickloadOption<Options>(
Configurable::Options::QuickLoad<Options>(
type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -175,13 +175,25 @@ public:
interrupt_timer_(interrupt_timer) {
establish_palette_hits();
build_mode_table();
crt_.set_dynamic_framing(
Outputs::Display::Rect(0.16842f, 0.19909f, 0.71579f, 0.67197f),
0.0f, 0.1f);
crt_.set_brightness(3.0f / 2.0f); // As only the values 0, 1 and 2 will be used in each channel,
// whereas Red2Green2Blue2 defines a range of 0-3.
}
void set_dynamic_framing(const bool enable) {
dynamic_framing_ = enable;
if(enable) {
crt_.set_dynamic_framing(
Outputs::Display::Rect(0.16842f, 0.19909f, 0.71579f, 0.67197f),
0.0f, 0.1f);
} else {
crt_.set_fixed_framing(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f));
}
}
bool dynamic_framing() const {
return dynamic_framing_;
}
/*!
The CRTC entry function for the main part of each clock cycle; takes the current
bus state and determines what output to produce based on the current palette and mode.
@@ -543,6 +555,7 @@ private:
int cycles_into_hsync_ = 0;
Outputs::CRT::CRT crt_;
bool dynamic_framing_ = false;
uint8_t *pixel_data_ = nullptr, *pixel_pointer_ = nullptr;
const uint8_t *const ram_ = nullptr;
@@ -1191,15 +1204,17 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
options->dynamic_crop = crtc_bus_handler_.dynamic_framing();
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) {
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape_hack();
crtc_bus_handler_.set_dynamic_framing(options->dynamic_crop);
}
// MARK: - Joysticks

View File

@@ -8,9 +8,9 @@
#pragma once
#include "Analyser/Static/StaticAnalyser.hpp"
#include "Configurable/Configurable.hpp"
#include "Configurable/StandardOptions.hpp"
#include "Analyser/Static/StaticAnalyser.hpp"
#include "Machines/ROMMachine.hpp"
#include <memory>
@@ -32,28 +32,33 @@ struct Machine {
/// Defines the runtime options available for an Amstrad CPC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>,
public Configurable::Options::DynamicCrop<Options>
{
public:
Options(const Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
Configurable::Options::Display<Options>(Configurable::Display::RGB),
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly),
Configurable::Options::DynamicCrop<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
friend Configurable::Options::DynamicCrop<Options>;
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
declare_dynamic_crop_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
};
// Provided for running the SHAKER test suite.
struct SSMDelegate {
virtual void perform(uint16_t) = 0;
};

View File

@@ -24,15 +24,15 @@ struct Machine {
static std::unique_ptr<Machine> AppleII(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
/// Defines the runtime options available for an Apple II.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::Display<Options> {
friend Configurable::Options::Display<Options>;
public:
bool use_square_pixels = false;
Options(Configurable::OptionsType) :
Configurable::DisplayOption<Options>(Configurable::Display::CompositeColour) {}
Options(const Configurable::OptionsType) :
Configurable::Options::Display<Options>(Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -506,7 +506,7 @@ public:
// MARK: - Configuration options.
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->quickboot = quickboot_;
options->quick_boot = quickboot_;
return options;
}
@@ -515,7 +515,7 @@ public:
// It should probably be a construction option.
const auto options = dynamic_cast<Options *>(str.get());
quickboot_ = options->quickboot;
quickboot_ = options->quick_boot;
using Model = Analyser::Static::Macintosh::Target::Model;
const bool is_plus_rom = model == Model::Mac512ke || model == Model::MacPlus;

View File

@@ -21,11 +21,11 @@ struct Machine {
/// Creates and returns a Macintosh.
static std::unique_ptr<Machine> Macintosh(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickbootOption<Options> {
friend Configurable::QuickbootOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::QuickBoot<Options> {
friend Configurable::Options::QuickBoot<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickbootOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
Options(const Configurable::OptionsType type) :
Configurable::Options::QuickBoot<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}

View File

@@ -22,15 +22,15 @@ struct Machine {
static std::unique_ptr<Machine> AtariST(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::Display<Options> {
friend Configurable::Options::Display<Options>;
public:
Options(Configurable::OptionsType type) : Configurable::DisplayOption<Options>(
Options(const Configurable::OptionsType type) : Configurable::Options::Display<Options>(
type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -21,15 +21,15 @@ struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> ColecoVision(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::Display<Options> {
friend Configurable::Options::Display<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::SVideo : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -1173,7 +1173,7 @@ private:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
return options;
}
@@ -1181,7 +1181,7 @@ private:
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape();
}
};

View File

@@ -26,19 +26,19 @@ struct Machine {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::SVideo : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly) {
}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -696,14 +696,14 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape();
}

View File

@@ -28,16 +28,16 @@ struct Machine {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::SVideo : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly) {
}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}

View File

@@ -28,16 +28,16 @@ struct Machine {
static std::unique_ptr<Machine> Enterprise(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
/// Defines the runtime options available for an Enterprise.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::Display<Options> {
friend Configurable::Options::Display<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(
type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -815,14 +815,14 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = allow_fast_tape_;
options->quick_load = allow_fast_tape_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
allow_fast_tape_ = options->quickload;
allow_fast_tape_ = options->quick_load;
set_use_fast_tape();
}

View File

@@ -23,18 +23,18 @@ struct Machine {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -21,15 +21,15 @@ struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> MasterSystem(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::Display<Options> {
friend Configurable::Options::Display<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -679,14 +679,14 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
options->quickload = use_fast_tape_hack_;
options->quick_load = use_fast_tape_hack_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
set_use_fast_tape_hack(options->quickload);
set_use_fast_tape_hack(options->quick_load);
}
void set_activity_observer(Activity::Observer *observer) final {

View File

@@ -26,19 +26,19 @@ struct Machine {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -30,15 +30,15 @@ struct Machine {
/// Defines the runtime options [sometimes] available for a PC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>
public Configurable::Options::Display<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::Options::Display<Options>;
public:
Options(Configurable::OptionsType) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB) {}
Options(const Configurable::OptionsType) :
Configurable::Options::Display<Options>(Configurable::Display::RGB) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -386,14 +386,14 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly); // OptionsType is arbitrary, but not optional.
options->automatic_tape_motor_control = use_automatic_tape_motor_control_;
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) {
const auto options = dynamic_cast<Options *>(str.get());
set_use_automatic_tape_motor_control(options->automatic_tape_motor_control);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape();
}

View File

@@ -26,17 +26,17 @@ struct Machine {
virtual bool get_tape_is_playing() = 0;
/// Defines the runtime options available for a ZX80/81.
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
class Options: public Reflection::StructImpl<Options>, public Configurable::Options::QuickLoad<Options> {
friend Configurable::Options::QuickLoad<Options>;
public:
bool automatic_tape_motor_control = true;
Options(Configurable::OptionsType type):
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
Options(const Configurable::OptionsType type):
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -731,7 +731,7 @@ public:
std::unique_ptr<Reflection::Struct> get_options() const override {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly); // OptionsType is arbitrary, but not optional.
options->automatic_tape_motor_control = use_automatic_tape_motor_control_;
options->quickload = allow_fast_tape_hack_;
options->quick_load = allow_fast_tape_hack_;
options->output = get_video_signal_configurable();
return options;
}
@@ -740,7 +740,7 @@ public:
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
set_use_automatic_tape_motor_control(options->automatic_tape_motor_control);
allow_fast_tape_hack_ = options->quickload;
allow_fast_tape_hack_ = options->quick_load;
set_use_fast_tape();
}

View File

@@ -26,21 +26,21 @@ struct Machine {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
public Configurable::Options::Display<Options>,
public Configurable::Options::QuickLoad<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
friend Configurable::Options::Display<Options>;
friend Configurable::Options::QuickLoad<Options>;
public:
bool automatic_tape_motor_control = true;
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
Options(const Configurable::OptionsType type) :
Configurable::Options::Display<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::Options::QuickLoad<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options() : Options( Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {

View File

@@ -366,6 +366,7 @@
4B47F6C5241C87A100ED06F7 /* Struct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B47F6C4241C87A100ED06F7 /* Struct.cpp */; };
4B47F6C6241C87A100ED06F7 /* Struct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B47F6C4241C87A100ED06F7 /* Struct.cpp */; };
4B49F0A923346F7A0045E6A6 /* MacintoshOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B49F0A723346F7A0045E6A6 /* MacintoshOptions.xib */; };
4B4A75BD2EB2C55100EA398F /* CompositeDynamicCropOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B4A75BB2EB2C55100EA398F /* CompositeDynamicCropOptions.xib */; };
4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; };
4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
@@ -1608,6 +1609,7 @@
4B47F3B52E7BAB94005D4DEC /* uPD7002.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = uPD7002.cpp; sourceTree = "<group>"; };
4B47F6C4241C87A100ED06F7 /* Struct.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Struct.cpp; sourceTree = "<group>"; };
4B49F0A823346F7A0045E6A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MacintoshOptions.xib"; sourceTree = SOURCE_ROOT; };
4B4A75BC2EB2C55100EA398F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CompositeDynamicCropOptions.xib; sourceTree = "<group>"; };
4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AY38910.cpp; sourceTree = "<group>"; };
4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AY38910.hpp; sourceTree = "<group>"; };
4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KonamiSCC.cpp; sourceTree = "<group>"; };
@@ -3452,12 +3454,13 @@
children = (
4B051C94266EF50200CA44E8 /* AppleIIController.swift */,
4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsController.swift */,
4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */,
4B8FE2211DA19FB20090D3CE /* MachineController.swift */,
4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */,
4B95FA9C1F11893B0008E395 /* ZX8081Controller.swift */,
4B08A56720D72BEF0016CE5A /* Activity.xib */,
4BC5FC2E20CDDDEE00410AA0 /* AppleIIOptions.xib */,
4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */,
4B4A75BB2EB2C55100EA398F /* CompositeDynamicCropOptions.xib */,
4BEEE6BB20DC72EA003723BF /* CompositeOptions.xib */,
4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */,
4B49F0A723346F7A0045E6A6 /* MacintoshOptions.xib */,
@@ -5696,6 +5699,7 @@
buildActionMask = 2147483647;
files = (
4B2C45421E3C3896002A2389 /* cartridge.png in Resources */,
4B4A75BD2EB2C55100EA398F /* CompositeDynamicCropOptions.xib in Resources */,
4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */,
4B79E4451E3AF38600141F11 /* floppy35.png in Resources */,
4BEDA3BD25B25563000C2DBD /* README.md in Resources */,
@@ -7003,6 +7007,14 @@
name = MacintoshOptions.xib;
sourceTree = "<group>";
};
4B4A75BB2EB2C55100EA398F /* CompositeDynamicCropOptions.xib */ = {
isa = PBXVariantGroup;
children = (
4B4A75BC2EB2C55100EA398F /* Base */,
);
name = CompositeDynamicCropOptions.xib;
sourceTree = "<group>";
};
4B55DD8120DF06680043F2E5 /* MachinePicker.xib */ = {
isa = PBXVariantGroup;
children = (

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MachineDocument" customModule="Clock_Signal" customModuleProvider="target">
<connections>
<outlet property="optionsController" destination="MXS-dG-Doo" id="zwz-gg-WjA"/>
<outlet property="optionsView" destination="tpZ-0B-QQu" id="xhc-MP-y9X"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<visualEffectView hidden="YES" wantsLayer="YES" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<rect key="frame" x="0.0" y="0.0" width="200" height="44"/>
<subviews>
<popUpButton wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rh8-km-57n">
<rect key="frame" x="9" y="8" width="183" height="25"/>
<popUpButtonCell key="cell" type="push" title="RGB Monitor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="L06-TO-EF0">
<items>
<menuItem title="RGB Monitor" state="on" id="tJM-kX-gaK"/>
<menuItem title="S-Video" tag="2" id="Mtc-Ht-iY8"/>
<menuItem title="Television" tag="1" id="fFm-fS-rWG"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="setDisplayType:" target="MXS-dG-Doo" id="5Vp-mv-kZU"/>
</connections>
</popUpButton>
</subviews>
<constraints>
<constraint firstItem="rh8-km-57n" firstAttribute="top" secondItem="tpZ-0B-QQu" secondAttribute="top" constant="12" id="B6L-VS-2cN"/>
<constraint firstItem="rh8-km-57n" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="12" id="VRo-6R-IKd"/>
<constraint firstAttribute="bottom" secondItem="rh8-km-57n" secondAttribute="bottom" constant="12" id="jHA-lf-e7V"/>
<constraint firstAttribute="trailing" secondItem="rh8-km-57n" secondAttribute="trailing" constant="12" id="urO-Ac-aqK"/>
</constraints>
<point key="canvasLocation" x="-118" y="120"/>
</visualEffectView>
<customObject id="MXS-dG-Doo" customClass="MachineController" customModule="Clock_Signal" customModuleProvider="target">
<connections>
<outlet property="displayTypeButton" destination="rh8-km-57n" id="3ln-Pl-G3k"/>
</connections>
</customObject>
</objects>
</document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -21,7 +21,7 @@
<rect key="frame" x="9" y="8" width="183" height="25"/>
<popUpButtonCell key="cell" type="push" title="RGB Monitor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<font key="font" metaFont="message"/>
<menu key="menu" id="L06-TO-EF0">
<items>
<menuItem title="RGB Monitor" state="on" id="tJM-kX-gaK"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -21,7 +21,7 @@
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="80" y="250" width="600" height="450"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1440"/>
<rect key="screenRect" x="0.0" y="0.0" width="1710" height="1074"/>
<value key="minSize" type="size" width="228" height="171"/>
<view key="contentView" id="gIp-Ho-8D9" customClass="CSScanTargetView">
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -31,7 +31,7 @@
<rect key="frame" x="9" y="8" width="204" height="25"/>
<popUpButtonCell key="cell" type="push" title="SCART" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<font key="font" metaFont="message"/>
<menu key="menu" id="L06-TO-EF0">
<items>
<menuItem title="SCART" state="on" id="tJM-kX-gaK"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -31,7 +31,7 @@
<rect key="frame" x="9" y="8" width="183" height="25"/>
<popUpButtonCell key="cell" type="push" title="RGB Monitor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<font key="font" metaFont="message"/>
<menu key="menu" id="L06-TO-EF0">
<items>
<menuItem title="RGB Monitor" state="on" id="tJM-kX-gaK"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MachineDocument" customModule="Clock_Signal" customModuleProvider="target">
<connections>
<outlet property="optionsController" destination="MXS-dG-Doo" id="zwz-gg-WjA"/>
<outlet property="optionsView" destination="tpZ-0B-QQu" id="xhc-MP-y9X"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<visualEffectView hidden="YES" wantsLayer="YES" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<rect key="frame" x="0.0" y="0.0" width="200" height="68"/>
<subviews>
<popUpButton wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rh8-km-57n">
<rect key="frame" x="9" y="8" width="183" height="25"/>
<popUpButtonCell key="cell" type="push" title="RGB Monitor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/>
<menu key="menu" id="L06-TO-EF0">
<items>
<menuItem title="RGB Monitor" state="on" id="tJM-kX-gaK"/>
<menuItem title="S-Video" tag="2" id="Mtc-Ht-iY8"/>
<menuItem title="Television" tag="1" id="fFm-fS-rWG"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="setDisplayType:" target="MXS-dG-Doo" id="5Vp-mv-kZU"/>
</connections>
</popUpButton>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lCr-xK-y7V">
<rect key="frame" x="10" y="39" width="178" height="18"/>
<buttonCell key="cell" type="check" title="Crop Dynamically" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="xvl-A3-tob">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="setDynamicCrop:" target="MXS-dG-Doo" id="kiQ-GJ-a6G"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="rh8-km-57n" firstAttribute="top" secondItem="lCr-xK-y7V" secondAttribute="bottom" constant="8" id="E1E-iG-Wry"/>
<constraint firstItem="lCr-xK-y7V" firstAttribute="top" secondItem="tpZ-0B-QQu" secondAttribute="top" constant="12" id="FTU-FS-P3d"/>
<constraint firstItem="rh8-km-57n" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="12" id="VRo-6R-IKd"/>
<constraint firstItem="lCr-xK-y7V" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="12" id="evE-Ha-9FB"/>
<constraint firstAttribute="bottom" secondItem="rh8-km-57n" secondAttribute="bottom" constant="12" id="jHA-lf-e7V"/>
<constraint firstAttribute="trailing" secondItem="rh8-km-57n" secondAttribute="trailing" constant="12" id="urO-Ac-aqK"/>
<constraint firstAttribute="trailing" secondItem="lCr-xK-y7V" secondAttribute="trailing" constant="12" id="z74-4d-WAn"/>
</constraints>
<point key="canvasLocation" x="-118" y="97.5"/>
</visualEffectView>
<customObject id="MXS-dG-Doo" customClass="MachineController" customModule="Clock_Signal" customModuleProvider="target">
<connections>
<outlet property="displayTypeButton" destination="rh8-km-57n" id="3ln-Pl-G3k"/>
<outlet property="dynamicCropButton" destination="lCr-xK-y7V" id="JcY-qe-Xvu"/>
</connections>
</customObject>
</objects>
</document>

View File

@@ -56,10 +56,21 @@ class MachineController: NSObject {
@IBAction func setDisplayType(_ sender: NSPopUpButton!) {
if let selectedItem = sender.selectedItem {
machine.videoSignal = signalForTag(tag: selectedItem.tag)
UserDefaults.standard.set(selectedItem.tag, forKey: self.displayTypeUserDefaultsKey)
UserDefaults.standard.set(selectedItem.tag, forKey: displayTypeUserDefaultsKey)
}
}
// MARK: Dynamic Cropping
var dynamicCroppingUserDefaultsKey: String {
return prefixedUserDefaultsKey("dynamicCrop")
}
@IBOutlet var dynamicCropButton: NSButton?
@IBAction func setDynamicCrop(_ sender: NSButton!) {
let useDynamicCropping = sender.state == .on
machine.useDynamicCropping = useDynamicCropping
UserDefaults.standard.set(useDynamicCropping, forKey: dynamicCroppingUserDefaultsKey)
}
// MARK: Restoring user defaults
func establishStoredOptions() {
let standardUserDefaults = UserDefaults.standard
@@ -70,17 +81,23 @@ class MachineController: NSObject {
])
if let fastLoadingButton = self.fastLoadingButton {
let useFastLoadingHack = standardUserDefaults.bool(forKey: self.fastLoadingUserDefaultsKey)
let useFastLoadingHack = standardUserDefaults.bool(forKey: fastLoadingUserDefaultsKey)
machine.useFastLoadingHack = useFastLoadingHack
fastLoadingButton.state = useFastLoadingHack ? .on : .off
}
if let fastBootingButton = self.fastBootingButton {
let bootQuickly = standardUserDefaults.bool(forKey: self.bootQuicklyUserDefaultsKey)
let bootQuickly = standardUserDefaults.bool(forKey: bootQuicklyUserDefaultsKey)
machine.useQuickBootingHack = bootQuickly
fastBootingButton.state = bootQuickly ? .on : .off
}
if let dynamicCropButton = self.dynamicCropButton {
let useDynamicCropping = standardUserDefaults.bool(forKey: dynamicCroppingUserDefaultsKey)
machine.useDynamicCropping = useDynamicCropping
dynamicCropButton.state = useDynamicCropping ? .on : .off
}
if let displayTypeButton = self.displayTypeButton {
// Enable or disable options as per machine support.
var titlesToRemove: [String] = []

View File

@@ -94,6 +94,7 @@ typedef NS_ENUM(NSInteger, CSMachineChangeEffect) {
@property (nonatomic, assign) CSMachineVideoSignal videoSignal;
@property (nonatomic, assign) BOOL useAutomaticTapeMotorControl;
@property (nonatomic, assign) BOOL useQuickBootingHack;
@property (nonatomic, assign) BOOL useDynamicCropping;
- (BOOL)supportsVideoSignal:(CSMachineVideoSignal)videoSignal;

View File

@@ -669,6 +669,20 @@ struct ActivityObserver: public Activity::Observer {
}
}
- (void)setUseDynamicCropping:(BOOL)useDynamicCropping {
Configurable::Device *configurable_device = _machine->configurable_device();
if(!configurable_device) return;
@synchronized(self) {
_useDynamicCropping = useDynamicCropping;
auto options = configurable_device->get_options();
Reflection::set(*options, "dynamiccrop", useDynamicCropping ? true : false);
configurable_device->set_options(options);
}
}
- (NSString *)userDefaultsPrefix {
// Assumes that the first machine in the targets list is the source of user defaults.
std::string name = Machine::ShortNameForTargetMachine(_analyser.targets.front()->machine);

View File

@@ -403,7 +403,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
- (NSString *)optionsNibName {
switch(_targets.front()->machine) {
case Analyser::Machine::AmstradCPC: return @"CompositeOptions";
case Analyser::Machine::AmstradCPC: return @"CompositeDynamicCropOptions";
case Analyser::Machine::Archimedes: return @"QuickLoadOptions";
case Analyser::Machine::AppleII: return @"AppleIIOptions";
case Analyser::Machine::Atari2600: return @"Atari2600Options";

View File

@@ -505,6 +505,12 @@ void CRT::posit(Display::Rect rect) {
Logger::info().append("First reading is (%0.5ff, %0.5ff, %0.5ff, %0.5ff)",
posted_rect_.origin.x, posted_rect_.origin.y,
posted_rect_.size.width, posted_rect_.size.height);
auto frame = border_rect_;
frame.scale(0.90f, 0.90f);
Logger::info().append("90%% of whole frame was (%0.5ff, %0.5ff, %0.5ff, %0.5ff)",
frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height);
}
return;
}