From 96e7eb1bed378a2b84cafb26068b65291c536d4e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Jun 2021 20:16:01 -0400 Subject: [PATCH 1/8] Adds a use-square-pixels option for the Apple II. --- Machines/Apple/AppleII/AppleII.cpp | 2 ++ Machines/Apple/AppleII/AppleII.hpp | 8 +++++++- Machines/Apple/AppleII/Video.cpp | 24 ++++++++++++++++++++++++ Machines/Apple/AppleII/Video.hpp | 6 ++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Machines/Apple/AppleII/AppleII.cpp b/Machines/Apple/AppleII/AppleII.cpp index 6b6078824..80436626d 100644 --- a/Machines/Apple/AppleII/AppleII.cpp +++ b/Machines/Apple/AppleII/AppleII.cpp @@ -787,12 +787,14 @@ template class ConcreteMachine: std::unique_ptr get_options() final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); + options->use_square_pixels = video_.get_use_square_pixels(); return options; } void set_options(const std::unique_ptr &str) { const auto options = dynamic_cast(str.get()); set_video_signal_configurable(options->output); + video_.set_use_square_pixels(options->use_square_pixels); } // MARK: MediaTarget diff --git a/Machines/Apple/AppleII/AppleII.hpp b/Machines/Apple/AppleII/AppleII.hpp index e373da4b8..94aa43289 100644 --- a/Machines/Apple/AppleII/AppleII.hpp +++ b/Machines/Apple/AppleII/AppleII.hpp @@ -30,10 +30,16 @@ class Machine { class Options: public Reflection::StructImpl, public Configurable::DisplayOption { friend Configurable::DisplayOption; public: - Options(Configurable::OptionsType) : Configurable::DisplayOption(Configurable::Display::CompositeColour) { + bool use_square_pixels = false; + + Options(Configurable::OptionsType) : Configurable::DisplayOption(Configurable::Display::CompositeColour) { if(needs_declare()) { declare_display_option(); limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1); + + if(needs_declare()) { + DeclareField(use_square_pixels); + } } } }; diff --git a/Machines/Apple/AppleII/Video.cpp b/Machines/Apple/AppleII/Video.cpp index 7b0df2baa..6a07308b2 100644 --- a/Machines/Apple/AppleII/Video.cpp +++ b/Machines/Apple/AppleII/Video.cpp @@ -26,6 +26,30 @@ VideoBase::VideoBase(bool is_iie, std::function &&target) : // crt_.set_immediate_default_phase(0.5f); } +void VideoBase::set_use_square_pixels(bool use_square_pixels) { + use_square_pixels_ = use_square_pixels; + + if(use_square_pixels) { + // From what I can make out, many contemporary Apple II monitors were + // calibrated slightly to stretch the Apple II's display slightly wider + // than it should be per the NTSC standards, for approximately square + // pixels. This reproduces that. + + // 243 lines and 52µs are visible. + // i.e. to be square, 1 pixel should be: (1/243 * 52) * (3/4) = 156/972 = 39/243 µs + // On an Apple II each pixel is actually 1/7µs. + // Therefore the adjusted aspect ratio should be (4/3) * (39/243)/(1/7) = (4/3) * 273/243 = 1092/729 = 343/243 ~= 1.412 + crt_.set_aspect_ratio(343.0f / 243.0f); + } else { + // Standard NTSC aspect ratio. + crt_.set_aspect_ratio(4.0f / 3.0f); + } +} +bool VideoBase::get_use_square_pixels() { + return use_square_pixels_; +} + + void VideoBase::set_scan_target(Outputs::Display::ScanTarget *scan_target) { crt_.set_scan_target(scan_target); } diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index afd332efc..ba414c83e 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -51,8 +51,14 @@ class VideoBase: public VideoSwitches { /// Gets the type of output. Outputs::Display::DisplayType get_display_type() const; + /// Sets whether the current CRT should be recalibrated away from normative NTSC + /// to produce square pixels in 40-column text mode. + void set_use_square_pixels(bool); + bool get_use_square_pixels(); + protected: Outputs::CRT::CRT crt_; + bool use_square_pixels_ = false; // State affecting output video stream generation. uint8_t *pixel_pointer_ = nullptr; From 778b9ef6838e6abb14b6422dc5d4494cb9805713 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Jun 2021 20:41:02 -0400 Subject: [PATCH 2/8] Ensures set_square_pixels is exposed, works around OpenGL aspect ratio bug. --- Machines/Apple/AppleII/AppleII.hpp | 5 +---- Machines/Apple/AppleII/Video.cpp | 14 ++++++++++++-- .../xcschemes/Clock Signal Kiosk.xcscheme | 16 ++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Machines/Apple/AppleII/AppleII.hpp b/Machines/Apple/AppleII/AppleII.hpp index 94aa43289..97d348578 100644 --- a/Machines/Apple/AppleII/AppleII.hpp +++ b/Machines/Apple/AppleII/AppleII.hpp @@ -34,12 +34,9 @@ class Machine { Options(Configurable::OptionsType) : Configurable::DisplayOption(Configurable::Display::CompositeColour) { if(needs_declare()) { + DeclareField(use_square_pixels); declare_display_option(); limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1); - - if(needs_declare()) { - DeclareField(use_square_pixels); - } } } }; diff --git a/Machines/Apple/AppleII/Video.cpp b/Machines/Apple/AppleII/Video.cpp index 6a07308b2..ae358c0ab 100644 --- a/Machines/Apple/AppleII/Video.cpp +++ b/Machines/Apple/AppleII/Video.cpp @@ -15,9 +15,8 @@ VideoBase::VideoBase(bool is_iie, std::function &&target) : crt_(910, 1, Outputs::Display::Type::NTSC60, Outputs::Display::InputDataType::Luminance1), is_iie_(is_iie) { - // Show only the centre 75% of the TV frame. crt_.set_display_type(Outputs::Display::DisplayType::CompositeColour); - crt_.set_visible_area(Outputs::Display::Rect(0.118f, 0.122f, 0.77f, 0.77f)); + set_use_square_pixels(use_square_pixels_); // TODO: there seems to be some sort of bug whereby switching modes can cause // a signal discontinuity that knocks phase out of whack. So it isn't safe to @@ -29,6 +28,17 @@ VideoBase::VideoBase(bool is_iie, std::function &&target) : void VideoBase::set_use_square_pixels(bool use_square_pixels) { use_square_pixels_ = use_square_pixels; + // HYPER-UGLY HACK. See correlated hack in the Macintosh. +#ifdef __APPLE__ + crt_.set_visible_area(Outputs::Display::Rect(0.128f, 0.122f, 0.75f, 0.77f)); +#else + if(use_square_pixels) { + crt_.set_visible_area(Outputs::Display::Rect(0.128f, 0.112f, 0.75f, 0.73f)); + } else { + crt_.set_visible_area(Outputs::Display::Rect(0.128f, 0.12f, 0.75f, 0.77f)); + } +#endif + if(use_square_pixels) { // From what I can make out, many contemporary Apple II monitors were // calibrated slightly to stretch the Apple II's display slightly wider diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme index 131430afb..263537208 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal Kiosk.xcscheme @@ -56,13 +56,17 @@ argument = "/Users/thomasharte/Downloads/test-dsk-for-rw-and-50-60-hz/TEST-RW-60Hz.DSK" isEnabled = "NO"> + + + isEnabled = "NO"> + isEnabled = "YES"> + isEnabled = "YES"> + + From 462bbf2e40fefd8d2d8251837b7aa0f9b6bdde7d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Jun 2021 21:21:45 -0400 Subject: [PATCH 3/8] Exposes square pixels option on macOS. --- .../Clock Signal.xcodeproj/project.pbxproj | 10 ++++ .../Base.lproj/AppleIIOptions.xib | 36 +++++++++---- .../Base.lproj/Atari2600Options.xib | 18 +++---- .../Mac/Clock Signal/Machine/CSMachine.h | 2 + .../Mac/Clock Signal/Machine/CSMachine.mm | 4 ++ .../Clock Signal/Machine/Wrappers/CSAppleII.h | 18 +++++++ .../Machine/Wrappers/CSAppleII.mm | 50 +++++++++++++++++++ 7 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAppleII.h create mode 100644 OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAppleII.mm diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index bda241923..60a7ae8c2 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 4B051C912669C90B00CA44E8 /* ROMCatalogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */; }; 4B051C922669C90B00CA44E8 /* ROMCatalogue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */; }; 4B051C93266D9D6900CA44E8 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; }; + 4B051C95266EF50200CA44E8 /* AppleIIOptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C94266EF50200CA44E8 /* AppleIIOptionsPanel.swift */; }; + 4B051C97266EF5F600CA44E8 /* CSAppleII.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B051C96266EF5F600CA44E8 /* CSAppleII.mm */; }; 4B05401E219D1618001BF69C /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B05401D219D1618001BF69C /* ScanTarget.cpp */; }; 4B05401F219D1618001BF69C /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B05401D219D1618001BF69C /* ScanTarget.cpp */; }; 4B055A7A1FAE78A00060FFFF /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055A771FAE78210060FFFF /* SDL2.framework */; }; @@ -1023,6 +1025,9 @@ 4B04B65622A58CB40006AB58 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4B051C5826670A9300CA44E8 /* ROMCatalogue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ROMCatalogue.cpp; sourceTree = ""; }; 4B051C5926670A9300CA44E8 /* ROMCatalogue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMCatalogue.hpp; sourceTree = ""; }; + 4B051C94266EF50200CA44E8 /* AppleIIOptionsPanel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleIIOptionsPanel.swift; sourceTree = ""; }; + 4B051C96266EF5F600CA44E8 /* CSAppleII.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CSAppleII.mm; sourceTree = ""; }; + 4B051C98266EF60500CA44E8 /* CSAppleII.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSAppleII.h; sourceTree = ""; }; 4B05401D219D1618001BF69C /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = ""; }; 4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Clock Signal Kiosk"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B055A771FAE78210060FFFF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../Library/Frameworks/SDL2.framework; sourceTree = SOURCE_ROOT; }; @@ -2405,8 +2410,10 @@ 4B2A53981D117D36003C6002 /* Wrappers */ = { isa = PBXGroup; children = ( + 4B051C98266EF60500CA44E8 /* CSAppleII.h */, 4B2A53991D117D36003C6002 /* CSAtari2600.h */, 4B14978D1EE4B4D200CE2596 /* CSZX8081.h */, + 4B051C96266EF5F600CA44E8 /* CSAppleII.mm */, 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */, 4B14978E1EE4B4D200CE2596 /* CSZX8081.mm */, ); @@ -2777,6 +2784,7 @@ 4B55CE551C3B7D360093A61B /* Documents */ = { isa = PBXGroup; children = ( + 4B051C94266EF50200CA44E8 /* AppleIIOptionsPanel.swift */, 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */, 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */, 4B8FE2211DA19FB20090D3CE /* MachinePanel.swift */, @@ -5402,11 +5410,13 @@ 4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */, 4B0ACC2C23775819008902D0 /* IntelligentKeyboard.cpp in Sources */, 4B92E26A234AE35100CD6D1B /* MFP68901.cpp in Sources */, + 4B051C97266EF5F600CA44E8 /* CSAppleII.mm in Sources */, 4B0ACC2A23775819008902D0 /* Video.cpp in Sources */, 4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */, 4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */, 4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */, 4BEDA3BF25B25563000C2DBD /* Decoder.cpp in Sources */, + 4B051C95266EF50200CA44E8 /* AppleIIOptionsPanel.swift in Sources */, 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */, 4BE8EB6625C750B50040BC40 /* DAT.cpp in Sources */, 4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */, diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/AppleIIOptions.xib b/OSBindings/Mac/Clock Signal/Base.lproj/AppleIIOptions.xib index 8c80a36f1..5b4ef82a7 100644 --- a/OSBindings/Mac/Clock Signal/Base.lproj/AppleIIOptions.xib +++ b/OSBindings/Mac/Clock Signal/Base.lproj/AppleIIOptions.xib @@ -1,8 +1,8 @@ - + - + @@ -13,17 +13,27 @@ - + - - - - + + + + + - + @@ -40,16 +50,20 @@ - + + + - + + + - + diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib index 2e6e00fb0..41c6e7572 100644 --- a/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib +++ b/OSBindings/Mac/Clock Signal/Base.lproj/Atari2600Options.xib @@ -1,8 +1,8 @@ - + - + @@ -13,17 +13,17 @@ - + - +