mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-05 13:29:06 +00:00
Merge pull request #398 from TomHarte/SVideoOption
Exposes S-Video as a user-selectable option
This commit is contained in:
commit
80c84ddd75
@ -33,7 +33,13 @@ bool get_bool(const Configurable::SelectionSet &selections_by_option, const std:
|
|||||||
std::vector<std::unique_ptr<Configurable::Option>> Configurable::standard_options(Configurable::StandardOptions mask) {
|
std::vector<std::unique_ptr<Configurable::Option>> Configurable::standard_options(Configurable::StandardOptions mask) {
|
||||||
std::vector<std::unique_ptr<Configurable::Option>> options;
|
std::vector<std::unique_ptr<Configurable::Option>> options;
|
||||||
if(mask & QuickLoadTape) options.emplace_back(new Configurable::BooleanOption("Load Tapes Quickly", "quickload"));
|
if(mask & QuickLoadTape) options.emplace_back(new Configurable::BooleanOption("Load Tapes Quickly", "quickload"));
|
||||||
if(mask & DisplayRGBComposite) options.emplace_back(new Configurable::ListOption("Display", "display", {"composite", "rgb"}));
|
if(mask & (DisplayRGB | DisplayComposite | DisplaySVideo)) {
|
||||||
|
std::vector<std::string> display_options;
|
||||||
|
if(mask & DisplayComposite) display_options.emplace_back("composite");
|
||||||
|
if(mask & DisplaySVideo) display_options.emplace_back("svideo");
|
||||||
|
if(mask & DisplayRGB) display_options.emplace_back("rgb");
|
||||||
|
options.emplace_back(new Configurable::ListOption("Display", "display", display_options));
|
||||||
|
}
|
||||||
if(mask & AutomaticTapeMotorControl) options.emplace_back(new Configurable::BooleanOption("Automatic Tape Motor Control", "autotapemotor"));
|
if(mask & AutomaticTapeMotorControl) options.emplace_back(new Configurable::BooleanOption("Automatic Tape Motor Control", "autotapemotor"));
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
@ -48,7 +54,14 @@ void Configurable::append_automatic_tape_motor_control_selection(SelectionSet &s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Configurable::append_display_selection(Configurable::SelectionSet &selection_set, Display selection) {
|
void Configurable::append_display_selection(Configurable::SelectionSet &selection_set, Display selection) {
|
||||||
selection_set["display"] = std::unique_ptr<Configurable::Selection>(new Configurable::ListSelection((selection == Display::RGB) ? "rgb" : "composite"));
|
std::string string_selection;
|
||||||
|
switch(selection) {
|
||||||
|
default:
|
||||||
|
case Display::RGB: string_selection = "rgb"; break;
|
||||||
|
case Display::SVideo: string_selection = "svideo"; break;
|
||||||
|
case Display::Composite: string_selection = "composite"; break;
|
||||||
|
}
|
||||||
|
selection_set["display"] = std::unique_ptr<Configurable::Selection>(new Configurable::ListSelection(string_selection));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Selection parsers
|
// MARK: - Selection parsers
|
||||||
@ -67,6 +80,10 @@ bool Configurable::get_display(const Configurable::SelectionSet &selections_by_o
|
|||||||
result = Configurable::Display::RGB;
|
result = Configurable::Display::RGB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(display->value == "svideo") {
|
||||||
|
result = Configurable::Display::SVideo;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(display->value == "composite") {
|
if(display->value == "composite") {
|
||||||
result = Configurable::Display::Composite;
|
result = Configurable::Display::Composite;
|
||||||
return true;
|
return true;
|
||||||
|
@ -14,13 +14,16 @@
|
|||||||
namespace Configurable {
|
namespace Configurable {
|
||||||
|
|
||||||
enum StandardOptions {
|
enum StandardOptions {
|
||||||
DisplayRGBComposite = (1 << 0),
|
DisplayRGB = (1 << 0),
|
||||||
QuickLoadTape = (1 << 1),
|
DisplaySVideo = (1 << 1),
|
||||||
AutomaticTapeMotorControl = (1 << 2)
|
DisplayComposite = (1 << 2),
|
||||||
|
QuickLoadTape = (1 << 3),
|
||||||
|
AutomaticTapeMotorControl = (1 << 4)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Display {
|
enum class Display {
|
||||||
RGB,
|
RGB,
|
||||||
|
SVideo,
|
||||||
Composite
|
Composite
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "../ClockReceiver/TimeTypes.hpp"
|
#include "../ClockReceiver/TimeTypes.hpp"
|
||||||
#include "ROMMachine.hpp"
|
#include "ROMMachine.hpp"
|
||||||
|
|
||||||
|
#include "../Configurable/StandardOptions.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace CRTMachine {
|
namespace CRTMachine {
|
||||||
@ -65,6 +67,23 @@ class Machine: public ROMMachine::Machine {
|
|||||||
return clock_rate_;
|
return clock_rate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_video_signal_configurable(Configurable::Display type) {
|
||||||
|
Outputs::CRT::VideoSignal signal;
|
||||||
|
switch(type) {
|
||||||
|
default:
|
||||||
|
case Configurable::Display::RGB:
|
||||||
|
signal = Outputs::CRT::VideoSignal::RGB;
|
||||||
|
break;
|
||||||
|
case Configurable::Display::SVideo:
|
||||||
|
signal = Outputs::CRT::VideoSignal::SVideo;
|
||||||
|
break;
|
||||||
|
case Configurable::Display::Composite:
|
||||||
|
signal = Outputs::CRT::VideoSignal::Composite;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
get_crt()->set_video_signal(signal);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double clock_rate_ = 1.0;
|
double clock_rate_ = 1.0;
|
||||||
double clock_conversion_error_ = 0.0;
|
double clock_conversion_error_ = 0.0;
|
||||||
|
@ -47,7 +47,9 @@ enum ROMSlot {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
||||||
return Configurable::standard_options(Configurable::QuickLoadTape);
|
return Configurable::standard_options(
|
||||||
|
static_cast<Configurable::StandardOptions>(Configurable::DisplaySVideo | Configurable::DisplayComposite | Configurable::QuickLoadTape)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum JoystickInput {
|
enum JoystickInput {
|
||||||
@ -709,17 +711,24 @@ class ConcreteMachine:
|
|||||||
allow_fast_tape_hack_ = quickload;
|
allow_fast_tape_hack_ = quickload;
|
||||||
set_use_fast_tape();
|
set_use_fast_tape();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Configurable::Display display;
|
||||||
|
if(Configurable::get_display(selections_by_option, display)) {
|
||||||
|
set_video_signal_configurable(display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Configurable::SelectionSet get_accurate_selections() override {
|
Configurable::SelectionSet get_accurate_selections() override {
|
||||||
Configurable::SelectionSet selection_set;
|
Configurable::SelectionSet selection_set;
|
||||||
Configurable::append_quick_load_tape_selection(selection_set, false);
|
Configurable::append_quick_load_tape_selection(selection_set, false);
|
||||||
|
Configurable::append_display_selection(selection_set, Configurable::Display::Composite);
|
||||||
return selection_set;
|
return selection_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
Configurable::SelectionSet get_user_friendly_selections() override {
|
Configurable::SelectionSet get_user_friendly_selections() override {
|
||||||
Configurable::SelectionSet selection_set;
|
Configurable::SelectionSet selection_set;
|
||||||
Configurable::append_quick_load_tape_selection(selection_set, true);
|
Configurable::append_quick_load_tape_selection(selection_set, true);
|
||||||
|
Configurable::append_display_selection(selection_set, Configurable::Display::SVideo);
|
||||||
return selection_set;
|
return selection_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace Electron {
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
||||||
return Configurable::standard_options(
|
return Configurable::standard_options(
|
||||||
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGBComposite | Configurable::QuickLoadTape)
|
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGB | Configurable::DisplayComposite | Configurable::QuickLoadTape)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
Configurable::Display display;
|
Configurable::Display display;
|
||||||
if(Configurable::get_display(selections_by_option, display)) {
|
if(Configurable::get_display(selections_by_option, display)) {
|
||||||
get_crt()->set_video_signal((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
set_video_signal_configurable(display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ namespace MSX {
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
||||||
return Configurable::standard_options(
|
return Configurable::standard_options(
|
||||||
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGBComposite | Configurable::QuickLoadTape)
|
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGB | Configurable::DisplaySVideo | Configurable::DisplayComposite | Configurable::QuickLoadTape)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
Configurable::Display display;
|
Configurable::Display display;
|
||||||
if(Configurable::get_display(selections_by_option, display)) {
|
if(Configurable::get_display(selections_by_option, display)) {
|
||||||
get_crt()->set_video_signal((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
set_video_signal_configurable(display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ enum ROM {
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
||||||
return Configurable::standard_options(
|
return Configurable::standard_options(
|
||||||
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGBComposite | Configurable::QuickLoadTape)
|
static_cast<Configurable::StandardOptions>(Configurable::DisplayRGB | Configurable::DisplayComposite | Configurable::QuickLoadTape)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +465,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
Configurable::Display display;
|
Configurable::Display display;
|
||||||
if(Configurable::get_display(selections_by_option, display)) {
|
if(Configurable::get_display(selections_by_option, display)) {
|
||||||
set_output_device((display == Configurable::Display::RGB) ? Outputs::CRT::VideoSignal::RGB : Outputs::CRT::VideoSignal::Composite);
|
set_video_signal_configurable(display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,6 @@
|
|||||||
4B322E041F5A2E3C004EB04C /* Z80Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322E031F5A2E3C004EB04C /* Z80Base.cpp */; };
|
4B322E041F5A2E3C004EB04C /* Z80Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B322E031F5A2E3C004EB04C /* Z80Base.cpp */; };
|
||||||
4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */; };
|
4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */; };
|
||||||
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */; };
|
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */; };
|
||||||
4B38F34F1F2EC6BA00D9235D /* AmstradCPCOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B38F34D1F2EC6BA00D9235D /* AmstradCPCOptions.xib */; };
|
|
||||||
4B3940E71DA83C8300427841 /* AsyncTaskQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */; };
|
4B3940E71DA83C8300427841 /* AsyncTaskQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */; };
|
||||||
4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; };
|
4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; };
|
||||||
4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; };
|
4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; };
|
||||||
@ -755,7 +754,6 @@
|
|||||||
4B37EE811D7345A6006A09A4 /* BinaryDump.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BinaryDump.hpp; sourceTree = "<group>"; };
|
4B37EE811D7345A6006A09A4 /* BinaryDump.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BinaryDump.hpp; sourceTree = "<group>"; };
|
||||||
4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AmstradCPC.cpp; path = AmstradCPC/AmstradCPC.cpp; sourceTree = "<group>"; };
|
4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AmstradCPC.cpp; path = AmstradCPC/AmstradCPC.cpp; sourceTree = "<group>"; };
|
||||||
4B38F3471F2EC11D00D9235D /* AmstradCPC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AmstradCPC.hpp; path = AmstradCPC/AmstradCPC.hpp; sourceTree = "<group>"; };
|
4B38F3471F2EC11D00D9235D /* AmstradCPC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AmstradCPC.hpp; path = AmstradCPC/AmstradCPC.hpp; sourceTree = "<group>"; };
|
||||||
4B38F34E1F2EC6BA00D9235D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/AmstradCPCOptions.xib"; sourceTree = SOURCE_ROOT; };
|
|
||||||
4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AsyncTaskQueue.cpp; path = ../../Concurrency/AsyncTaskQueue.cpp; sourceTree = "<group>"; };
|
4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AsyncTaskQueue.cpp; path = ../../Concurrency/AsyncTaskQueue.cpp; sourceTree = "<group>"; };
|
||||||
4B3940E61DA83C8300427841 /* AsyncTaskQueue.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AsyncTaskQueue.hpp; path = ../../Concurrency/AsyncTaskQueue.hpp; sourceTree = "<group>"; };
|
4B3940E61DA83C8300427841 /* AsyncTaskQueue.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AsyncTaskQueue.hpp; path = ../../Concurrency/AsyncTaskQueue.hpp; sourceTree = "<group>"; };
|
||||||
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = "<group>"; };
|
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = "<group>"; };
|
||||||
@ -1875,7 +1873,6 @@
|
|||||||
4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */,
|
4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */,
|
||||||
4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */,
|
4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */,
|
||||||
4B95FA9C1F11893B0008E395 /* ZX8081OptionsPanel.swift */,
|
4B95FA9C1F11893B0008E395 /* ZX8081OptionsPanel.swift */,
|
||||||
4B38F34D1F2EC6BA00D9235D /* AmstradCPCOptions.xib */,
|
|
||||||
4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */,
|
4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */,
|
||||||
4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */,
|
4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */,
|
||||||
4B2A332B1DB86821002876E3 /* OricOptions.xib */,
|
4B2A332B1DB86821002876E3 /* OricOptions.xib */,
|
||||||
@ -3126,7 +3123,6 @@
|
|||||||
4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */,
|
4BB73EAC1B587A5100552FC2 /* MainMenu.xib in Resources */,
|
||||||
4B8FE21D1DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib in Resources */,
|
4B8FE21D1DA19D5F0090D3CE /* QuickLoadCompositeOptions.xib in Resources */,
|
||||||
4B79E4461E3AF38600141F11 /* floppy525.png in Resources */,
|
4B79E4461E3AF38600141F11 /* floppy525.png in Resources */,
|
||||||
4B38F34F1F2EC6BA00D9235D /* AmstradCPCOptions.xib in Resources */,
|
|
||||||
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */,
|
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */,
|
||||||
4B1497981EE4B97F00CE2596 /* ZX8081Options.xib in Resources */,
|
4B1497981EE4B97F00CE2596 /* ZX8081Options.xib in Resources */,
|
||||||
);
|
);
|
||||||
@ -3809,14 +3805,6 @@
|
|||||||
name = OricOptions.xib;
|
name = OricOptions.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
4B38F34D1F2EC6BA00D9235D /* AmstradCPCOptions.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
4B38F34E1F2EC6BA00D9235D /* Base */,
|
|
||||||
);
|
|
||||||
name = AmstradCPCOptions.xib;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */ = {
|
4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="macosx"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
|
||||||
<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="optionsPanel" destination="ZW7-Bw-4RP" id="JpE-wG-zRR"/>
|
|
||||||
</connections>
|
|
||||||
</customObject>
|
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
|
||||||
<window title="Options" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="ZW7-Bw-4RP" customClass="MachinePanel" customModule="Clock_Signal" customModuleProvider="target">
|
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES" HUD="YES"/>
|
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
|
||||||
<rect key="contentRect" x="83" y="102" width="200" height="54"/>
|
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
|
||||||
<view key="contentView" id="tpZ-0B-QQu">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="200" height="54"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="e1J-pw-zGw">
|
|
||||||
<rect key="frame" x="18" y="18" width="164" height="18"/>
|
|
||||||
<buttonCell key="cell" type="check" title="Load Quickly" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="tD6-UB-ESB">
|
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="setFastLoading:" target="ZW7-Bw-4RP" id="JmG-Ks-jSh"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="e1J-pw-zGw" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="20" id="HSD-3d-Bl7"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="e1J-pw-zGw" secondAttribute="trailing" constant="20" id="Q9M-FH-92N"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="e1J-pw-zGw" secondAttribute="bottom" constant="20" id="sdh-oJ-ZIQ"/>
|
|
||||||
<constraint firstItem="e1J-pw-zGw" firstAttribute="top" secondItem="tpZ-0B-QQu" secondAttribute="top" constant="20" id="ul9-lf-Y3u"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
<connections>
|
|
||||||
<outlet property="fastLoadingButton" destination="e1J-pw-zGw" id="jj7-OZ-mOH"/>
|
|
||||||
</connections>
|
|
||||||
<point key="canvasLocation" x="175" y="30"/>
|
|
||||||
</window>
|
|
||||||
</objects>
|
|
||||||
</document>
|
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14109"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES" HUD="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES" HUD="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="83" y="102" width="200" height="83"/>
|
<rect key="contentRect" x="83" y="102" width="200" height="83"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1366" height="768"/>
|
||||||
<view key="contentView" id="tpZ-0B-QQu">
|
<view key="contentView" id="tpZ-0B-QQu">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="200" height="83"/>
|
<rect key="frame" x="0.0" y="0.0" width="200" height="83"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<menu key="menu" id="L06-TO-EF0">
|
<menu key="menu" id="L06-TO-EF0">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="SCART" state="on" id="tJM-kX-gaK"/>
|
<menuItem title="SCART" state="on" id="tJM-kX-gaK"/>
|
||||||
<menuItem title="Composite" id="fFm-fS-rWG"/>
|
<menuItem title="Composite" tag="1" id="fFm-fS-rWG"/>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</popUpButtonCell>
|
</popUpButtonCell>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14109"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES" HUD="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" utility="YES" nonactivatingPanel="YES" HUD="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="83" y="102" width="200" height="83"/>
|
<rect key="contentRect" x="83" y="102" width="200" height="83"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1366" height="768"/>
|
||||||
<view key="contentView" id="tpZ-0B-QQu">
|
<view key="contentView" id="tpZ-0B-QQu">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="200" height="83"/>
|
<rect key="frame" x="0.0" y="0.0" width="200" height="83"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
@ -34,13 +34,14 @@
|
|||||||
</button>
|
</button>
|
||||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rh8-km-57n">
|
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rh8-km-57n">
|
||||||
<rect key="frame" x="18" y="17" width="165" height="26"/>
|
<rect key="frame" x="18" y="17" width="165" height="26"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Monitor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="tJM-kX-gaK" id="8SX-c5-ud1">
|
<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"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="menu"/>
|
||||||
<menu key="menu" id="L06-TO-EF0">
|
<menu key="menu" id="L06-TO-EF0">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Monitor" state="on" id="tJM-kX-gaK"/>
|
<menuItem title="RGB Monitor" state="on" id="tJM-kX-gaK"/>
|
||||||
<menuItem title="Television" id="fFm-fS-rWG"/>
|
<menuItem title="S-Video" tag="2" id="Mtc-Ht-iY8"/>
|
||||||
|
<menuItem title="Television" tag="1" id="fFm-fS-rWG"/>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</popUpButtonCell>
|
</popUpButtonCell>
|
||||||
|
@ -28,13 +28,24 @@ class MachinePanel: NSPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func signalForTag(tag: Int) -> CSMachineVideoSignal {
|
||||||
|
switch tag {
|
||||||
|
case 1: return .composite
|
||||||
|
case 2: return .sVideo
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
return .RGB
|
||||||
|
}
|
||||||
|
|
||||||
var displayTypeUserDefaultsKey: String {
|
var displayTypeUserDefaultsKey: String {
|
||||||
return prefixedUserDefaultsKey("displayType")
|
return prefixedUserDefaultsKey("displayType")
|
||||||
}
|
}
|
||||||
@IBOutlet var displayTypeButton: NSPopUpButton?
|
@IBOutlet var displayTypeButton: NSPopUpButton?
|
||||||
@IBAction func setDisplayType(_ sender: NSPopUpButton!) {
|
@IBAction func setDisplayType(_ sender: NSPopUpButton!) {
|
||||||
machine.useCompositeOutput = (sender.indexOfSelectedItem == 1)
|
if let selectedItem = sender.selectedItem {
|
||||||
UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: self.displayTypeUserDefaultsKey)
|
machine.videoSignal = signalForTag(tag: selectedItem.tag)
|
||||||
|
UserDefaults.standard.set(selectedItem.tag, forKey: self.displayTypeUserDefaultsKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func establishStoredOptions() {
|
func establishStoredOptions() {
|
||||||
@ -50,8 +61,21 @@ class MachinePanel: NSPanel {
|
|||||||
self.fastLoadingButton?.state = useFastLoadingHack ? .on : .off
|
self.fastLoadingButton?.state = useFastLoadingHack ? .on : .off
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let displayTypeButton = self.displayTypeButton {
|
||||||
|
// Enable or disable options as per machine support.
|
||||||
|
var titlesToRemove: [String] = []
|
||||||
|
for item in displayTypeButton.itemArray {
|
||||||
|
if !machine.supportsVideoSignal(signalForTag(tag: item.tag)) {
|
||||||
|
titlesToRemove.append(item.title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for title in titlesToRemove {
|
||||||
|
displayTypeButton.removeItem(withTitle: title)
|
||||||
|
}
|
||||||
|
|
||||||
let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey)
|
let displayType = standardUserDefaults.integer(forKey: self.displayTypeUserDefaultsKey)
|
||||||
machine.useCompositeOutput = (displayType == 1)
|
displayTypeButton.selectItem(withTag: displayType)
|
||||||
self.displayTypeButton?.selectItem(at: displayType)
|
setDisplayType(displayTypeButton)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
- (void)machineSpeakerDidChangeInputClock:(CSMachine *)machine;
|
- (void)machineSpeakerDidChangeInputClock:(CSMachine *)machine;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, CSMachineVideoSignal) {
|
||||||
|
CSMachineVideoSignalComposite,
|
||||||
|
CSMachineVideoSignalSVideo,
|
||||||
|
CSMachineVideoSignalRGB
|
||||||
|
};
|
||||||
|
|
||||||
// Deliberately low; to ensure CSMachine has been declared as an @class already.
|
// Deliberately low; to ensure CSMachine has been declared as an @class already.
|
||||||
#import "CSAtari2600.h"
|
#import "CSAtari2600.h"
|
||||||
#import "CSZX8081.h"
|
#import "CSZX8081.h"
|
||||||
@ -52,9 +58,11 @@
|
|||||||
- (void)paste:(NSString *)string;
|
- (void)paste:(NSString *)string;
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL useFastLoadingHack;
|
@property (nonatomic, assign) BOOL useFastLoadingHack;
|
||||||
@property (nonatomic, assign) BOOL useCompositeOutput;
|
@property (nonatomic, assign) CSMachineVideoSignal videoSignal;
|
||||||
@property (nonatomic, assign) BOOL useAutomaticTapeMotorControl;
|
@property (nonatomic, assign) BOOL useAutomaticTapeMotorControl;
|
||||||
|
|
||||||
|
- (bool)supportsVideoSignal:(CSMachineVideoSignal)videoSignal;
|
||||||
|
|
||||||
// Special-case accessors; undefined behaviour if accessed for a machine not of the corresponding type.
|
// Special-case accessors; undefined behaviour if accessed for a machine not of the corresponding type.
|
||||||
@property (nonatomic, readonly) CSAtari2600 *atari2600;
|
@property (nonatomic, readonly) CSAtari2600 *atari2600;
|
||||||
@property (nonatomic, readonly) CSZX8081 *zx8081;
|
@property (nonatomic, readonly) CSZX8081 *zx8081;
|
||||||
|
@ -289,19 +289,63 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate, public LockP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setUseCompositeOutput:(BOOL)useCompositeOutput {
|
- (void)setVideoSignal:(CSMachineVideoSignal)videoSignal {
|
||||||
Configurable::Device *configurable_device = _machine->configurable_device();
|
Configurable::Device *configurable_device = _machine->configurable_device();
|
||||||
if(!configurable_device) return;
|
if(!configurable_device) return;
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
_useCompositeOutput = useCompositeOutput;
|
_videoSignal = videoSignal;
|
||||||
|
|
||||||
Configurable::SelectionSet selection_set;
|
Configurable::SelectionSet selection_set;
|
||||||
append_display_selection(selection_set, useCompositeOutput ? Configurable::Display::Composite : Configurable::Display::RGB);
|
Configurable::Display display;
|
||||||
|
switch(videoSignal) {
|
||||||
|
case CSMachineVideoSignalRGB: display = Configurable::Display::RGB; break;
|
||||||
|
case CSMachineVideoSignalSVideo: display = Configurable::Display::SVideo; break;
|
||||||
|
case CSMachineVideoSignalComposite: display = Configurable::Display::Composite; break;
|
||||||
|
}
|
||||||
|
append_display_selection(selection_set, display);
|
||||||
configurable_device->set_selections(selection_set);
|
configurable_device->set_selections(selection_set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)supportsVideoSignal:(CSMachineVideoSignal)videoSignal {
|
||||||
|
Configurable::Device *configurable_device = _machine->configurable_device();
|
||||||
|
if(!configurable_device) return NO;
|
||||||
|
|
||||||
|
// Get the options this machine provides.
|
||||||
|
std::vector<std::unique_ptr<Configurable::Option>> options;
|
||||||
|
@synchronized(self) {
|
||||||
|
options = configurable_device->get_options();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the standard option for this video signal.
|
||||||
|
Configurable::StandardOptions option;
|
||||||
|
switch(videoSignal) {
|
||||||
|
case CSMachineVideoSignalRGB: option = Configurable::DisplayRGB; break;
|
||||||
|
case CSMachineVideoSignalSVideo: option = Configurable::DisplaySVideo; break;
|
||||||
|
case CSMachineVideoSignalComposite: option = Configurable::DisplayComposite; break;
|
||||||
|
}
|
||||||
|
std::unique_ptr<Configurable::Option> display_option = std::move(standard_options(option).front());
|
||||||
|
Configurable::ListOption *display_list_option = dynamic_cast<Configurable::ListOption *>(display_option.get());
|
||||||
|
NSAssert(display_list_option, @"Expected display option to be a list");
|
||||||
|
|
||||||
|
// See whether the video signal is included in the machine options.
|
||||||
|
for(auto &candidate: options) {
|
||||||
|
Configurable::ListOption *list_option = dynamic_cast<Configurable::ListOption *>(candidate.get());
|
||||||
|
|
||||||
|
// Both should be list options
|
||||||
|
if(!list_option) continue;
|
||||||
|
|
||||||
|
// Check for same name of option.
|
||||||
|
if(candidate->short_name != display_option->short_name) continue;
|
||||||
|
|
||||||
|
// Check that the video signal option is included.
|
||||||
|
return std::find(list_option->options.begin(), list_option->options.end(), display_list_option->options.front()) != list_option->options.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setUseAutomaticTapeMotorControl:(BOOL)useAutomaticTapeMotorControl {
|
- (void)setUseAutomaticTapeMotorControl:(BOOL)useAutomaticTapeMotorControl {
|
||||||
Configurable::Device *configurable_device = _machine->configurable_device();
|
Configurable::Device *configurable_device = _machine->configurable_device();
|
||||||
if(!configurable_device) return;
|
if(!configurable_device) return;
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions";
|
case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions";
|
||||||
case Analyser::Machine::MSX: return @"QuickLoadCompositeOptions";
|
case Analyser::Machine::MSX: return @"QuickLoadCompositeOptions";
|
||||||
case Analyser::Machine::Oric: return @"OricOptions";
|
case Analyser::Machine::Oric: return @"OricOptions";
|
||||||
case Analyser::Machine::Vic20: return @"QuickLoadOptions";
|
case Analyser::Machine::Vic20: return @"QuickLoadCompositeOptions";
|
||||||
case Analyser::Machine::ZX8081: return @"ZX8081Options";
|
case Analyser::Machine::ZX8081: return @"ZX8081Options";
|
||||||
default: return nil;
|
default: return nil;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user