From 7248470950c513de64de9f651e5ddb0219730bed Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 30 Nov 2024 18:57:56 -0500 Subject: [PATCH] Roll formatting and `const` tweaks into Inputs. --- .../Implementation/MultiConfigurable.cpp | 2 +- .../Implementation/MultiConfigurable.hpp | 2 +- Concurrency/AsyncTaskQueue.hpp | 206 +++++----- Configurable/Configurable.hpp | 2 +- Configurable/StandardOptions.hpp | 44 +-- Inputs/Joystick.hpp | 356 +++++++++--------- Inputs/Keyboard.cpp | 4 +- Inputs/Keyboard.hpp | 108 +++--- Inputs/Mouse.hpp | 6 +- Inputs/QuadratureMouse/QuadratureMouse.hpp | 150 ++++---- Machines/Acorn/Archimedes/Archimedes.cpp | 2 +- Machines/Acorn/Archimedes/Keyboard.hpp | 2 +- Machines/Acorn/Electron/Electron.cpp | 2 +- Machines/Amiga/MouseJoystick.cpp | 2 +- Machines/Amiga/MouseJoystick.hpp | 2 +- Machines/AmstradCPC/AmstradCPC.cpp | 2 +- Machines/Apple/ADB/Mouse.cpp | 2 +- Machines/Apple/ADB/Mouse.hpp | 2 +- Machines/Apple/AppleII/AppleII.cpp | 2 +- Machines/Apple/AppleII/Video.cpp | 3 +- Machines/Apple/AppleII/Video.hpp | 2 +- Machines/Apple/Macintosh/Macintosh.cpp | 2 +- Machines/Atari/ST/AtariST.cpp | 2 +- Machines/Atari/ST/IntelligentKeyboard.cpp | 2 +- Machines/Atari/ST/IntelligentKeyboard.hpp | 2 +- Machines/ColecoVision/ColecoVision.cpp | 2 +- Machines/Commodore/Vic-20/Vic20.cpp | 2 +- Machines/Enterprise/Enterprise.cpp | 2 +- Machines/MSX/MSX.cpp | 2 +- Machines/MasterSystem/MasterSystem.cpp | 2 +- Machines/Oric/Oric.cpp | 2 +- Machines/PCCompatible/PCCompatible.cpp | 2 +- Machines/Sinclair/ZX8081/ZX8081.cpp | 2 +- Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 2 +- 34 files changed, 464 insertions(+), 465 deletions(-) diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.cpp index 3556719b1..f0dc5c2ed 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.cpp @@ -115,6 +115,6 @@ void MultiConfigurable::set_options(const std::unique_ptr &s options->apply(); } -std::unique_ptr MultiConfigurable::get_options() { +std::unique_ptr MultiConfigurable::get_options() const { return std::make_unique(devices_); } diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp index 07da52d3d..47b10cf17 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp @@ -28,7 +28,7 @@ public: // Below is the standard Configurable::Device interface; see there for documentation. void set_options(const std::unique_ptr &) final; - std::unique_ptr get_options() final; + std::unique_ptr get_options() const final; private: std::vector devices_; diff --git a/Concurrency/AsyncTaskQueue.hpp b/Concurrency/AsyncTaskQueue.hpp index 594438446..6e1b82b50 100644 --- a/Concurrency/AsyncTaskQueue.hpp +++ b/Concurrency/AsyncTaskQueue.hpp @@ -65,126 +65,126 @@ template <> struct TaskQueueStorage { called once per action. */ template class AsyncTaskQueue: public TaskQueueStorage { - public: - template AsyncTaskQueue(Args&&... args) : - TaskQueueStorage(std::forward(args)...) { - if constexpr (start_immediately) { - start(); - } +public: + template AsyncTaskQueue(Args&&... args) : + TaskQueueStorage(std::forward(args)...) { + if constexpr (start_immediately) { + start(); } + } - /// Enqueus @c post_action to be performed asynchronously at some point - /// in the future. If @c perform_automatically is @c true then the action - /// will be performed as soon as possible. Otherwise it will sit unsheculed until - /// a call to @c perform(). - /// - /// Actions may be elided. - /// - /// If this TaskQueue has a @c Performer then the action will be performed - /// on the same thread as the performer, after the performer has been updated - /// to 'now'. - void enqueue(const std::function &post_action) { - std::lock_guard guard(condition_mutex_); - actions_.push_back(post_action); + /// Enqueus @c post_action to be performed asynchronously at some point + /// in the future. If @c perform_automatically is @c true then the action + /// will be performed as soon as possible. Otherwise it will sit unsheculed until + /// a call to @c perform(). + /// + /// Actions may be elided. + /// + /// If this TaskQueue has a @c Performer then the action will be performed + /// on the same thread as the performer, after the performer has been updated + /// to 'now'. + void enqueue(const std::function &post_action) { + std::lock_guard guard(condition_mutex_); + actions_.push_back(post_action); - if constexpr (perform_automatically) { - condition_.notify_all(); - } - } - - /// Causes any enqueued actions that are not yet scheduled to be scheduled. - void perform() { - if(actions_.empty()) { - return; - } + if constexpr (perform_automatically) { condition_.notify_all(); } + } - /// Permanently stops this task queue, blocking until that has happened. - /// All pending actions will be performed first. - /// - /// The queue cannot be restarted; this is a destructive action. - void stop() { - if(thread_.joinable()) { - should_quit_ = true; - enqueue([] {}); - if constexpr (!perform_automatically) { - perform(); - } - thread_.join(); - } + /// Causes any enqueued actions that are not yet scheduled to be scheduled. + void perform() { + if(actions_.empty()) { + return; } + condition_.notify_all(); + } - /// Starts the queue if it has never been started before. - /// - /// This is not guaranteed safely to restart a stopped queue. - void start() { - thread_ = std::thread{ - [this] { - ActionVector actions; - - // Continue until told to quit. - while(!should_quit_) { - // Wait for new actions to be signalled, and grab them. - std::unique_lock lock(condition_mutex_); - while(actions_.empty() && !should_quit_) { - condition_.wait(lock); - } - std::swap(actions, actions_); - lock.unlock(); - - // Update to now (which is possibly a no-op). - TaskQueueStorage::update(); - - // Perform the actions and destroy them. - for(const auto &action: actions) { - action(); - } - actions.clear(); - } - } - }; - } - - /// Schedules any remaining unscheduled work, then blocks synchronously - /// until all scheduled work has been performed. - void flush() { - std::mutex flush_mutex; - std::condition_variable flush_condition; - bool has_run = false; - std::unique_lock lock(flush_mutex); - - enqueue([&flush_mutex, &flush_condition, &has_run] () { - std::unique_lock inner_lock(flush_mutex); - has_run = true; - flush_condition.notify_all(); - }); - + /// Permanently stops this task queue, blocking until that has happened. + /// All pending actions will be performed first. + /// + /// The queue cannot be restarted; this is a destructive action. + void stop() { + if(thread_.joinable()) { + should_quit_ = true; + enqueue([] {}); if constexpr (!perform_automatically) { perform(); } + thread_.join(); + } + } - flush_condition.wait(lock, [&has_run] { return has_run; }); + /// Starts the queue if it has never been started before. + /// + /// This is not guaranteed safely to restart a stopped queue. + void start() { + thread_ = std::thread{ + [this] { + ActionVector actions; + + // Continue until told to quit. + while(!should_quit_) { + // Wait for new actions to be signalled, and grab them. + std::unique_lock lock(condition_mutex_); + while(actions_.empty() && !should_quit_) { + condition_.wait(lock); + } + std::swap(actions, actions_); + lock.unlock(); + + // Update to now (which is possibly a no-op). + TaskQueueStorage::update(); + + // Perform the actions and destroy them. + for(const auto &action: actions) { + action(); + } + actions.clear(); + } + } + }; + } + + /// Schedules any remaining unscheduled work, then blocks synchronously + /// until all scheduled work has been performed. + void flush() { + std::mutex flush_mutex; + std::condition_variable flush_condition; + bool has_run = false; + std::unique_lock lock(flush_mutex); + + enqueue([&flush_mutex, &flush_condition, &has_run] () { + std::unique_lock inner_lock(flush_mutex); + has_run = true; + flush_condition.notify_all(); + }); + + if constexpr (!perform_automatically) { + perform(); } - ~AsyncTaskQueue() { - stop(); - } + flush_condition.wait(lock, [&has_run] { return has_run; }); + } - private: - // The list of actions waiting be performed. These will be elided, - // increasing their latency, if the emulation thread falls behind. - using ActionVector = std::vector>; - ActionVector actions_; + ~AsyncTaskQueue() { + stop(); + } - // Necessary synchronisation parts. - std::atomic should_quit_ = false; - std::mutex condition_mutex_; - std::condition_variable condition_; +private: + // The list of actions waiting be performed. These will be elided, + // increasing their latency, if the emulation thread falls behind. + using ActionVector = std::vector>; + ActionVector actions_; - // Ensure the thread isn't constructed until after the mutex - // and condition variable. - std::thread thread_; + // Necessary synchronisation parts. + std::atomic should_quit_ = false; + std::mutex condition_mutex_; + std::condition_variable condition_; + + // Ensure the thread isn't constructed until after the mutex + // and condition variable. + std::thread thread_; }; } diff --git a/Configurable/Configurable.hpp b/Configurable/Configurable.hpp index de543931b..0144d34c3 100644 --- a/Configurable/Configurable.hpp +++ b/Configurable/Configurable.hpp @@ -25,7 +25,7 @@ struct Device { virtual void set_options(const std::unique_ptr &options) = 0; /// @returns An options object - virtual std::unique_ptr get_options() = 0; + virtual std::unique_ptr get_options() const = 0; }; /*! diff --git a/Configurable/StandardOptions.hpp b/Configurable/StandardOptions.hpp index 0cc911644..c57513718 100644 --- a/Configurable/StandardOptions.hpp +++ b/Configurable/StandardOptions.hpp @@ -26,37 +26,37 @@ ReflectableEnum(Display, //=== template class DisplayOption { - public: - Configurable::Display output; - DisplayOption(Configurable::Display output) : output(output) {} +public: + Configurable::Display output; + DisplayOption(Configurable::Display output) : output(output) {} - protected: - void declare_display_option() { - static_cast(this)->declare(&output, "output"); - AnnounceEnumNS(Configurable, Display); - } +protected: + void declare_display_option() { + static_cast(this)->declare(&output, "output"); + AnnounceEnumNS(Configurable, Display); + } }; template class QuickloadOption { - public: - bool quickload; - QuickloadOption(bool quickload) : quickload(quickload) {} +public: + bool quickload; + QuickloadOption(bool quickload) : quickload(quickload) {} - protected: - void declare_quickload_option() { - static_cast(this)->declare(&quickload, "quickload"); - } +protected: + void declare_quickload_option() { + static_cast(this)->declare(&quickload, "quickload"); + } }; template class QuickbootOption { - public: - bool quickboot; - QuickbootOption(bool quickboot) : quickboot(quickboot) {} +public: + bool quickboot; + QuickbootOption(bool quickboot) : quickboot(quickboot) {} - protected: - void declare_quickboot_option() { - static_cast(this)->declare(&quickboot, "quickboot"); - } +protected: + void declare_quickboot_option() { + static_cast(this)->declare(&quickboot, "quickboot"); + } }; } diff --git a/Inputs/Joystick.hpp b/Inputs/Joystick.hpp index 064baf092..31150b7b7 100644 --- a/Inputs/Joystick.hpp +++ b/Inputs/Joystick.hpp @@ -18,137 +18,137 @@ namespace Inputs { machine to toggle states, while an interested party either observes or polls. */ class Joystick { - public: - virtual ~Joystick() = default; +public: + virtual ~Joystick() = default; - /*! - Defines a single input, any individually-measured thing — a fire button or - other digital control, an analogue axis, or a button with a symbol on it. - */ - struct Input { - /// Defines the broad type of the input. - enum Type { - // Half-axis inputs. - Up, Down, Left, Right, - // Full-axis inputs. - Horizontal, Vertical, - // Fire buttons. - Fire, - // Other labelled keys. - Key, + /*! + Defines a single input, any individually-measured thing — a fire button or + other digital control, an analogue axis, or a button with a symbol on it. + */ + struct Input { + /// Defines the broad type of the input. + enum Type { + // Half-axis inputs. + Up, Down, Left, Right, + // Full-axis inputs. + Horizontal, Vertical, + // Fire buttons. + Fire, + // Other labelled keys. + Key, - // The maximum value this enum can contain. - Max = Key - }; - const Type type; - - bool is_digital_axis() const { - return type < Type::Horizontal; - } - bool is_analogue_axis() const { - return type >= Type::Horizontal && type < Type::Fire; - } - bool is_axis() const { - return type < Type::Fire; - } - bool is_button() const { - return type >= Type::Fire; - } - - enum Precision { - Analogue, Digital - }; - Precision precision() const { - return is_analogue_axis() ? Precision::Analogue : Precision::Digital; - } - - /*! - Holds extra information pertaining to the input. - - @c Type::Key inputs declare the symbol printed on them. - - All other types of input have an associated index, indicating whether they - are the zeroth, first, second, third, etc of those things. E.g. a joystick - may have two fire buttons, which will be buttons 0 and 1. - */ - union Info { - struct { - size_t index; - } control; - struct { - wchar_t symbol; - } key; - }; - Info info; - // TODO: Find a way to make the above safely const; may mean not using a union. - - Input(Type type, size_t index = 0) : - type(type) { - info.control.index = index; - } - Input(wchar_t symbol) : type(Key) { - info.key.symbol = symbol; - } - - bool operator == (const Input &rhs) { - if(rhs.type != type) return false; - if(rhs.type == Key) { - return rhs.info.key.symbol == info.key.symbol; - } else { - return rhs.info.control.index == info.control.index; - } - } + // The maximum value this enum can contain. + Max = Key }; + const Type type; - /// @returns The list of all inputs defined on this joystick. - virtual const std::vector &get_inputs() = 0; + bool is_digital_axis() const { + return type < Type::Horizontal; + } + bool is_analogue_axis() const { + return type >= Type::Horizontal && type < Type::Fire; + } + bool is_axis() const { + return type < Type::Fire; + } + bool is_button() const { + return type >= Type::Fire; + } - /*! - Sets the digital value of @c input. This may have direct effect or - influence an analogue value; e.g. if the caller declares that ::Left is - active but this joystick has only an analogue horizontal axis, this will - cause a change to that analogue value. - */ - virtual void set_input(const Input &input, bool is_active) = 0; - - /*! - Sets the analogue value of @c input. If the input is actually digital, - or if there is a digital input with a corresponding meaning (e.g. ::Left - versus the horizontal axis), this may cause a digital input to be set. - - @c value should be in the range [0.0, 1.0]. - */ - virtual void set_input(const Input &input, float value) = 0; - - /*! - Sets all inputs to their resting state. - */ - virtual void reset_all_inputs() { - for(const auto &input: get_inputs()) { - if(input.precision() == Input::Precision::Digital) - set_input(input, false); - else - set_input(input, 0.5f); - } + enum Precision { + Analogue, Digital + }; + Precision precision() const { + return is_analogue_axis() ? Precision::Analogue : Precision::Digital; } /*! - Gets the number of input fire buttons. + Holds extra information pertaining to the input. - This is cached by default, but it's virtual so overridable. + @c Type::Key inputs declare the symbol printed on them. + + All other types of input have an associated index, indicating whether they + are the zeroth, first, second, third, etc of those things. E.g. a joystick + may have two fire buttons, which will be buttons 0 and 1. */ - virtual int get_number_of_fire_buttons() { - if(number_of_buttons_ >= 0) return number_of_buttons_; + union Info { + struct { + size_t index; + } control; + struct { + wchar_t symbol; + } key; + }; + Info info; + // TODO: Find a way to make the above safely const; may mean not using a union. - number_of_buttons_ = 0; - for(const auto &input: get_inputs()) { - if(input.type == Input::Type::Fire) ++number_of_buttons_; - } - return number_of_buttons_; + Input(const Type type, const size_t index = 0) : + type(type) { + info.control.index = index; + } + Input(const wchar_t symbol) : type(Key) { + info.key.symbol = symbol; } - private: - int number_of_buttons_ = -1; + bool operator == (const Input &rhs) { + if(rhs.type != type) return false; + if(rhs.type == Key) { + return rhs.info.key.symbol == info.key.symbol; + } else { + return rhs.info.control.index == info.control.index; + } + } + }; + + /// @returns The list of all inputs defined on this joystick. + virtual const std::vector &get_inputs() = 0; + + /*! + Sets the digital value of @c input. This may have direct effect or + influence an analogue value; e.g. if the caller declares that ::Left is + active but this joystick has only an analogue horizontal axis, this will + cause a change to that analogue value. + */ + virtual void set_input(const Input &input, bool is_active) = 0; + + /*! + Sets the analogue value of @c input. If the input is actually digital, + or if there is a digital input with a corresponding meaning (e.g. ::Left + versus the horizontal axis), this may cause a digital input to be set. + + @c value should be in the range [0.0, 1.0]. + */ + virtual void set_input(const Input &input, float value) = 0; + + /*! + Sets all inputs to their resting state. + */ + virtual void reset_all_inputs() { + for(const auto &input: get_inputs()) { + if(input.precision() == Input::Precision::Digital) + set_input(input, false); + else + set_input(input, 0.5f); + } + } + + /*! + Gets the number of input fire buttons. + + This is cached by default, but it's virtual so overridable. + */ + virtual int get_number_of_fire_buttons() { + if(number_of_buttons_ >= 0) return number_of_buttons_; + + number_of_buttons_ = 0; + for(const auto &input: get_inputs()) { + if(input.type == Input::Type::Fire) ++number_of_buttons_; + } + return number_of_buttons_; + } + +private: + int number_of_buttons_ = -1; }; /*! @@ -157,79 +157,79 @@ class Joystick { promised analogue <-> digital mapping of Joystick. */ class ConcreteJoystick: public Joystick { - public: - ConcreteJoystick(const std::vector &inputs) : inputs_(inputs) { - // Size and populate stick_types_, which is used for digital <-> analogue conversion. - for(const auto &input: inputs_) { - const bool is_digital_axis = input.is_digital_axis(); - const bool is_analogue_axis = input.is_analogue_axis(); - if(is_digital_axis || is_analogue_axis) { - const size_t required_size = size_t(input.info.control.index+1); - if(stick_types_.size() < required_size) { - stick_types_.resize(required_size); - } - stick_types_[size_t(input.info.control.index)] = is_digital_axis ? StickType::Digital : StickType::Analogue; +public: + ConcreteJoystick(const std::vector &inputs) : inputs_(inputs) { + // Size and populate stick_types_, which is used for digital <-> analogue conversion. + for(const auto &input: inputs_) { + const bool is_digital_axis = input.is_digital_axis(); + const bool is_analogue_axis = input.is_analogue_axis(); + if(is_digital_axis || is_analogue_axis) { + const size_t required_size = size_t(input.info.control.index+1); + if(stick_types_.size() < required_size) { + stick_types_.resize(required_size); } + stick_types_[size_t(input.info.control.index)] = is_digital_axis ? StickType::Digital : StickType::Analogue; } } + } - const std::vector &get_inputs() final { - return inputs_; + const std::vector &get_inputs() final { + return inputs_; + } + + void set_input(const Input &input, const bool is_active) final { + // If this is a digital setting to a digital property, just pass it along. + if(input.is_button() || stick_types_[input.info.control.index] == StickType::Digital) { + did_set_input(input, is_active); + return; } - void set_input(const Input &input, bool is_active) final { - // If this is a digital setting to a digital property, just pass it along. - if(input.is_button() || stick_types_[input.info.control.index] == StickType::Digital) { - did_set_input(input, is_active); - return; - } + // Otherwise this is logically to an analogue axis; for now just use some + // convenient hard-coded values. TODO: make these a function of time. + using Type = Joystick::Input::Type; + switch(input.type) { + default: did_set_input(input, is_active ? 1.0f : 0.0f); break; + case Type::Left: did_set_input(Input(Type::Horizontal, input.info.control.index), is_active ? 0.1f : 0.5f); break; + case Type::Right: did_set_input(Input(Type::Horizontal, input.info.control.index), is_active ? 0.9f : 0.5f); break; + case Type::Up: did_set_input(Input(Type::Vertical, input.info.control.index), is_active ? 0.1f : 0.5f); break; + case Type::Down: did_set_input(Input(Type::Vertical, input.info.control.index), is_active ? 0.9f : 0.5f); break; + } + } - // Otherwise this is logically to an analogue axis; for now just use some - // convenient hard-coded values. TODO: make these a function of time. - using Type = Joystick::Input::Type; - switch(input.type) { - default: did_set_input(input, is_active ? 1.0f : 0.0f); break; - case Type::Left: did_set_input(Input(Type::Horizontal, input.info.control.index), is_active ? 0.1f : 0.5f); break; - case Type::Right: did_set_input(Input(Type::Horizontal, input.info.control.index), is_active ? 0.9f : 0.5f); break; - case Type::Up: did_set_input(Input(Type::Vertical, input.info.control.index), is_active ? 0.1f : 0.5f); break; - case Type::Down: did_set_input(Input(Type::Vertical, input.info.control.index), is_active ? 0.9f : 0.5f); break; - } + void set_input(const Input &input, const float value) final { + // If this is an analogue setting to an analogue property, just pass it along. + if(!input.is_button() && stick_types_[input.info.control.index] == StickType::Analogue) { + did_set_input(input, value); + return; } - void set_input(const Input &input, float value) final { - // If this is an analogue setting to an analogue property, just pass it along. - if(!input.is_button() && stick_types_[input.info.control.index] == StickType::Analogue) { - did_set_input(input, value); - return; - } - - // Otherwise apply a threshold test to convert to digital, with remapping from axes to digital inputs. - using Type = Joystick::Input::Type; - switch(input.type) { - default: did_set_input(input, value > 0.5f); break; - case Type::Horizontal: - did_set_input(Input(Type::Left, input.info.control.index), value <= 0.25f); - did_set_input(Input(Type::Right, input.info.control.index), value >= 0.75f); - break; - case Type::Vertical: - did_set_input(Input(Type::Up, input.info.control.index), value <= 0.25f); - did_set_input(Input(Type::Down, input.info.control.index), value >= 0.75f); - break; - } + // Otherwise apply a threshold test to convert to digital, with remapping from axes to digital inputs. + using Type = Joystick::Input::Type; + switch(input.type) { + default: did_set_input(input, value > 0.5f); break; + case Type::Horizontal: + did_set_input(Input(Type::Left, input.info.control.index), value <= 0.25f); + did_set_input(Input(Type::Right, input.info.control.index), value >= 0.75f); + break; + case Type::Vertical: + did_set_input(Input(Type::Up, input.info.control.index), value <= 0.25f); + did_set_input(Input(Type::Down, input.info.control.index), value >= 0.75f); + break; } + } - protected: - virtual void did_set_input([[maybe_unused]] const Input &input, [[maybe_unused]] float value) {} - virtual void did_set_input([[maybe_unused]] const Input &input, [[maybe_unused]] bool value) {} +protected: + virtual void did_set_input([[maybe_unused]] const Input &input, [[maybe_unused]] float value) {} + virtual void did_set_input([[maybe_unused]] const Input &input, [[maybe_unused]] bool value) {} - private: - const std::vector inputs_; +private: + const std::vector inputs_; - enum class StickType { - Digital, - Analogue - }; - std::vector stick_types_; + enum class StickType { + Digital, + Analogue + }; + std::vector stick_types_; }; } diff --git a/Inputs/Keyboard.cpp b/Inputs/Keyboard.cpp index 7abdb87e5..8825baba9 100644 --- a/Inputs/Keyboard.cpp +++ b/Inputs/Keyboard.cpp @@ -21,7 +21,7 @@ Keyboard::Keyboard(const std::set &essential_modifiers) : essential_modifie Keyboard::Keyboard(const std::set &observed_keys, const std::set &essential_modifiers) : observed_keys_(observed_keys), essential_modifiers_(essential_modifiers), is_exclusive_(false) {} -bool Keyboard::set_key_pressed(Key key, char, bool is_pressed, bool) { +bool Keyboard::set_key_pressed(const Key key, const char, const bool is_pressed, bool) { const size_t key_offset = size_t(key); if(key_offset >= key_states_.size()) { key_states_.resize(key_offset+1, false); @@ -41,7 +41,7 @@ void Keyboard::reset_all_keys() { if(delegate_) delegate_->reset_all_keys(this); } -void Keyboard::set_delegate(Delegate *delegate) { +void Keyboard::set_delegate(Delegate *const delegate) { delegate_ = delegate; } diff --git a/Inputs/Keyboard.hpp b/Inputs/Keyboard.hpp index ad00c1b05..230d710f0 100644 --- a/Inputs/Keyboard.hpp +++ b/Inputs/Keyboard.hpp @@ -19,73 +19,73 @@ namespace Inputs { machine to toggle states, while an interested party either observes or polls. */ class Keyboard { - public: - enum class Key { - Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PrintScreen, ScrollLock, Pause, - BackTick, k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, Hyphen, Equals, Backspace, - Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, Backslash, - CapsLock, A, S, D, F, G, H, J, K, L, Semicolon, Quote, Hash, Enter, - LeftShift, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift, - LeftControl, LeftOption, LeftMeta, Space, RightMeta, RightOption, RightControl, - Left, Right, Up, Down, - Insert, Home, PageUp, Delete, End, PageDown, - NumLock, KeypadSlash, KeypadAsterisk, KeypadDelete, - Keypad7, Keypad8, Keypad9, KeypadPlus, - Keypad4, Keypad5, Keypad6, KeypadMinus, - Keypad1, Keypad2, Keypad3, KeypadEnter, - Keypad0, KeypadDecimalPoint, KeypadEquals, - Help, +public: + enum class Key { + Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PrintScreen, ScrollLock, Pause, + BackTick, k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, Hyphen, Equals, Backspace, + Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, Backslash, + CapsLock, A, S, D, F, G, H, J, K, L, Semicolon, Quote, Hash, Enter, + LeftShift, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift, + LeftControl, LeftOption, LeftMeta, Space, RightMeta, RightOption, RightControl, + Left, Right, Up, Down, + Insert, Home, PageUp, Delete, End, PageDown, + NumLock, KeypadSlash, KeypadAsterisk, KeypadDelete, + Keypad7, Keypad8, Keypad9, KeypadPlus, + Keypad4, Keypad5, Keypad6, KeypadMinus, + Keypad1, Keypad2, Keypad3, KeypadEnter, + Keypad0, KeypadDecimalPoint, KeypadEquals, + Help, - Max = Help - }; + Max = Help + }; - /// Constructs a Keyboard that declares itself to observe all keys. - Keyboard(const std::set &essential_modifiers = {}); + /// Constructs a Keyboard that declares itself to observe all keys. + Keyboard(const std::set &essential_modifiers = {}); - /// Constructs a Keyboard that declares itself to observe only members of @c observed_keys. - Keyboard(const std::set &observed_keys, const std::set &essential_modifiers); + /// Constructs a Keyboard that declares itself to observe only members of @c observed_keys. + Keyboard(const std::set &observed_keys, const std::set &essential_modifiers); - virtual ~Keyboard() = default; + virtual ~Keyboard() = default; - // Host interface. + // Host interface. - /// @returns @c true if the key press affects the machine; @c false otherwise. - virtual bool set_key_pressed(Key key, char value, bool is_pressed, bool is_repeat); - virtual void reset_all_keys(); + /// @returns @c true if the key press affects the machine; @c false otherwise. + virtual bool set_key_pressed(Key key, char value, bool is_pressed, bool is_repeat); + virtual void reset_all_keys(); - /// @returns a set of all Keys that this keyboard responds to. - virtual const std::set &observed_keys() const; + /// @returns a set of all Keys that this keyboard responds to. + virtual const std::set &observed_keys() const; - /// @returns the list of modifiers that this keyboard considers 'essential' (i.e. both mapped and highly used). - virtual const std::set &get_essential_modifiers() const; + /// @returns the list of modifiers that this keyboard considers 'essential' (i.e. both mapped and highly used). + virtual const std::set &get_essential_modifiers() const; - /*! - @returns @c true if this keyboard, on its original machine, looked - like a complete keyboard — i.e. if a user would expect this keyboard - to be the only thing a real keyboard maps to. + /*! + @returns @c true if this keyboard, on its original machine, looked + like a complete keyboard — i.e. if a user would expect this keyboard + to be the only thing a real keyboard maps to. - So this would be true of something like the Amstrad CPC, which has a full - keyboard, but it would be false of something like the Sega Master System - which has some buttons that you'd expect an emulator to map to its host - keyboard but which does not offer a full keyboard. - */ - virtual bool is_exclusive() const; + So this would be true of something like the Amstrad CPC, which has a full + keyboard, but it would be false of something like the Sega Master System + which has some buttons that you'd expect an emulator to map to its host + keyboard but which does not offer a full keyboard. + */ + virtual bool is_exclusive() const; - // Delegate interface. - struct Delegate { - virtual bool keyboard_did_change_key(Keyboard *keyboard, Key key, bool is_pressed) = 0; - virtual void reset_all_keys(Keyboard *keyboard) = 0; - }; - void set_delegate(Delegate *delegate); - bool get_key_state(Key key) const; + // Delegate interface. + struct Delegate { + virtual bool keyboard_did_change_key(Keyboard *keyboard, Key key, bool is_pressed) = 0; + virtual void reset_all_keys(Keyboard *keyboard) = 0; + }; + void set_delegate(Delegate *); + bool get_key_state(Key) const; - private: - std::set observed_keys_; - const std::set essential_modifiers_; - const bool is_exclusive_ = true; +private: + std::set observed_keys_; + const std::set essential_modifiers_; + const bool is_exclusive_ = true; - std::vector key_states_; - Delegate *delegate_ = nullptr; + std::vector key_states_; + Delegate *delegate_ = nullptr; }; } diff --git a/Inputs/Mouse.hpp b/Inputs/Mouse.hpp index 9772abfd3..6bad55950 100644 --- a/Inputs/Mouse.hpp +++ b/Inputs/Mouse.hpp @@ -19,12 +19,12 @@ class Mouse { /*! Indicates a movement of the mouse. */ - virtual void move([[maybe_unused]] int x, [[maybe_unused]] int y) {} + virtual void move([[maybe_unused]] const int x, [[maybe_unused]] const int y) {} /*! @returns the number of buttons on this mouse. */ - virtual int get_number_of_buttons() { + virtual int get_number_of_buttons() const { return 1; } @@ -33,7 +33,7 @@ class Mouse { The intention is that @c index be semantic, not positional: 0 for the primary button, 1 for the secondary, 2 for the tertiary, etc. */ - virtual void set_button_pressed([[maybe_unused]] int index, [[maybe_unused]] bool is_pressed) {} + virtual void set_button_pressed([[maybe_unused]] const int index, [[maybe_unused]] const bool is_pressed) {} /*! Releases all depressed buttons. diff --git a/Inputs/QuadratureMouse/QuadratureMouse.hpp b/Inputs/QuadratureMouse/QuadratureMouse.hpp index 78d52420d..ce2edf883 100644 --- a/Inputs/QuadratureMouse/QuadratureMouse.hpp +++ b/Inputs/QuadratureMouse/QuadratureMouse.hpp @@ -26,95 +26,95 @@ namespace Inputs { channels below. This is intended to be fixed. */ class QuadratureMouse: public Mouse { - public: - QuadratureMouse(int number_of_buttons) : - number_of_buttons_(number_of_buttons) {} +public: + QuadratureMouse(const int number_of_buttons) : + number_of_buttons_(number_of_buttons) {} - /* - Inputs, to satisfy the Mouse interface. - */ - void move(int x, int y) final { - // Accumulate all provided motion. - axes_[0] += x; - axes_[1] += y; - } + /* + Inputs, to satisfy the Mouse interface. + */ + void move(const int x, const int y) final { + // Accumulate all provided motion. + axes_[0] += x; + axes_[1] += y; + } - int get_number_of_buttons() final { - return number_of_buttons_; - } + int get_number_of_buttons() const final { + return number_of_buttons_; + } - void set_button_pressed(int index, bool is_pressed) final { - if(is_pressed) - button_flags_ |= (1 << index); - else - button_flags_ &= ~(1 << index); - } + void set_button_pressed(const int index, const bool is_pressed) final { + if(is_pressed) + button_flags_ |= (1 << index); + else + button_flags_ &= ~(1 << index); + } - void reset_all_buttons() final { - button_flags_ = 0; - } + void reset_all_buttons() final { + button_flags_ = 0; + } - /* - Outputs. - */ + /* + Outputs. + */ - /*! - Applies a single step from the current accumulated mouse movement, which - might involve the mouse moving right, or left, or not at all. - */ - void prepare_step() { - for(int axis = 0; axis < 2; ++axis) { - // Do nothing if there's no motion to communicate. - const int axis_value = axes_[axis]; - if(!axis_value) continue; + /*! + Applies a single step from the current accumulated mouse movement, which + might involve the mouse moving right, or left, or not at all. + */ + void prepare_step() { + for(int axis = 0; axis < 2; ++axis) { + // Do nothing if there's no motion to communicate. + const int axis_value = axes_[axis]; + if(!axis_value) continue; - // Toggle the primary channel and set the secondary for - // negative motion. At present the y axis signals the - // secondary channel the opposite way around from the - // primary. - primaries_[axis] ^= 1; - secondaries_[axis] = primaries_[axis] ^ axis; - if(axis_value > 0) { - -- axes_[axis]; - secondaries_[axis] ^= 1; // Switch to positive motion. - } else { - ++ axes_[axis]; - } + // Toggle the primary channel and set the secondary for + // negative motion. At present the y axis signals the + // secondary channel the opposite way around from the + // primary. + primaries_[axis] ^= 1; + secondaries_[axis] = primaries_[axis] ^ axis; + if(axis_value > 0) { + -- axes_[axis]; + secondaries_[axis] ^= 1; // Switch to positive motion. + } else { + ++ axes_[axis]; } } + } - /*! - @returns the two quadrature channels — bit 0 is the 'primary' channel - (i.e. the one that can be monitored to observe velocity) and - bit 1 is the 'secondary' (i.e. that which can be queried to - observe direction). - */ - int get_channel(int axis) { - return primaries_[axis] | (secondaries_[axis] << 1); - } + /*! + @returns the two quadrature channels — bit 0 is the 'primary' channel + (i.e. the one that can be monitored to observe velocity) and + bit 1 is the 'secondary' (i.e. that which can be queried to + observe direction). + */ + int get_channel(int axis) const { + return primaries_[axis] | (secondaries_[axis] << 1); + } - /*! - @returns a bit mask of the currently pressed buttons. - */ - int get_button_mask() { - return button_flags_; - } + /*! + @returns a bit mask of the currently pressed buttons. + */ + int get_button_mask() const { + return button_flags_; + } - /*! - @returns @c true if any mouse motion is waiting to be communicated; - @c false otherwise. - */ - bool has_steps() { - return axes_[0] || axes_[1]; - } + /*! + @returns @c true if any mouse motion is waiting to be communicated; + @c false otherwise. + */ + bool has_steps() const { + return axes_[0] || axes_[1]; + } - private: - const int number_of_buttons_ = 0; - std::atomic button_flags_{0}; - std::atomic axes_[2]{0, 0}; +private: + const int number_of_buttons_ = 0; + std::atomic button_flags_{0}; + std::atomic axes_[2]{0, 0}; - int primaries_[2] = {0, 0}; - int secondaries_[2] = {0, 0}; + int primaries_[2] = {0, 0}; + int secondaries_[2] = {0, 0}; }; } diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index e87b203dd..5a29ae891 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -507,7 +507,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->quickload = accelerate_loading_; return options; diff --git a/Machines/Acorn/Archimedes/Keyboard.hpp b/Machines/Acorn/Archimedes/Keyboard.hpp index 617c87a65..81a356117 100644 --- a/Machines/Acorn/Archimedes/Keyboard.hpp +++ b/Machines/Acorn/Archimedes/Keyboard.hpp @@ -314,7 +314,7 @@ private: keyboard_.mouse_y_ += y; } - int get_number_of_buttons() override { + int get_number_of_buttons() const override { return 3; } diff --git a/Machines/Acorn/Electron/Electron.cpp b/Machines/Acorn/Electron/Electron.cpp index ab19216bf..eb1b7de4e 100644 --- a/Machines/Acorn/Electron/Electron.cpp +++ b/Machines/Acorn/Electron/Electron.cpp @@ -589,7 +589,7 @@ template class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->quickload = allow_fast_tape_hack_; diff --git a/Machines/Amiga/MouseJoystick.cpp b/Machines/Amiga/MouseJoystick.cpp index 7659fc7a7..c1a24aafd 100644 --- a/Machines/Amiga/MouseJoystick.cpp +++ b/Machines/Amiga/MouseJoystick.cpp @@ -14,7 +14,7 @@ using namespace Amiga; // MARK: - Mouse. -int Mouse::get_number_of_buttons() { +int Mouse::get_number_of_buttons() const { return 2; } diff --git a/Machines/Amiga/MouseJoystick.hpp b/Machines/Amiga/MouseJoystick.hpp index 3289c3764..fa667c505 100644 --- a/Machines/Amiga/MouseJoystick.hpp +++ b/Machines/Amiga/MouseJoystick.hpp @@ -27,7 +27,7 @@ class Mouse: public Inputs::Mouse, public MouseJoystickInput { uint8_t get_cia_button() const final; private: - int get_number_of_buttons() final; + int get_number_of_buttons() const final; void set_button_pressed(int, bool) final; void reset_all_buttons() final; void move(int, int) final; diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 85fba8015..17328b5d8 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -1187,7 +1187,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->quickload = allow_fast_tape_hack_; diff --git a/Machines/Apple/ADB/Mouse.cpp b/Machines/Apple/ADB/Mouse.cpp index a2f9657fb..d7f431308 100644 --- a/Machines/Apple/ADB/Mouse.cpp +++ b/Machines/Apple/ADB/Mouse.cpp @@ -58,7 +58,7 @@ void Mouse::move(int x, int y) { post_service_request(); } -int Mouse::get_number_of_buttons() { +int Mouse::get_number_of_buttons() const { return 2; } diff --git a/Machines/Apple/ADB/Mouse.hpp b/Machines/Apple/ADB/Mouse.hpp index 2835552d5..b7e776b80 100644 --- a/Machines/Apple/ADB/Mouse.hpp +++ b/Machines/Apple/ADB/Mouse.hpp @@ -21,7 +21,7 @@ class Mouse: public ReactiveDevice, public Inputs::Mouse { void perform_command(const Command &command) override; void move(int x, int y) override; - int get_number_of_buttons() override; + int get_number_of_buttons() const override; void set_button_pressed(int index, bool is_pressed) override; void reset_all_buttons() override; diff --git a/Machines/Apple/AppleII/AppleII.cpp b/Machines/Apple/AppleII/AppleII.cpp index f8fc8305f..94642f8e1 100644 --- a/Machines/Apple/AppleII/AppleII.cpp +++ b/Machines/Apple/AppleII/AppleII.cpp @@ -1043,7 +1043,7 @@ template } // MARK:: Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->use_square_pixels = video_.get_use_square_pixels(); diff --git a/Machines/Apple/AppleII/Video.cpp b/Machines/Apple/AppleII/Video.cpp index 6ed67553c..93f0ba45c 100644 --- a/Machines/Apple/AppleII/Video.cpp +++ b/Machines/Apple/AppleII/Video.cpp @@ -55,11 +55,10 @@ void VideoBase::set_use_square_pixels(bool use_square_pixels) { crt_.set_aspect_ratio(4.0f / 3.0f); } } -bool VideoBase::get_use_square_pixels() { +bool VideoBase::get_use_square_pixels() const { 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 fe6ce1504..f0a8e9055 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -50,7 +50,7 @@ class VideoBase: public VideoSwitches { /// 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(); + bool get_use_square_pixels() const; protected: Outputs::CRT::CRT crt_; diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index cf1f65981..e7c271408 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -502,7 +502,7 @@ template class ConcreteMachin } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->quickboot = quickboot_; return options; diff --git a/Machines/Atari/ST/AtariST.cpp b/Machines/Atari/ST/AtariST.cpp index 7c39e28bc..c853acec6 100644 --- a/Machines/Atari/ST/AtariST.cpp +++ b/Machines/Atari/ST/AtariST.cpp @@ -692,7 +692,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); return options; diff --git a/Machines/Atari/ST/IntelligentKeyboard.cpp b/Machines/Atari/ST/IntelligentKeyboard.cpp index 1888bc550..5f4e6607c 100644 --- a/Machines/Atari/ST/IntelligentKeyboard.cpp +++ b/Machines/Atari/ST/IntelligentKeyboard.cpp @@ -427,7 +427,7 @@ void IntelligentKeyboard::move(int x, int y) { mouse_movement_[1] += y; } -int IntelligentKeyboard::get_number_of_buttons() { +int IntelligentKeyboard::get_number_of_buttons() const { return 2; } diff --git a/Machines/Atari/ST/IntelligentKeyboard.hpp b/Machines/Atari/ST/IntelligentKeyboard.hpp index 440590229..54f9306ee 100644 --- a/Machines/Atari/ST/IntelligentKeyboard.hpp +++ b/Machines/Atari/ST/IntelligentKeyboard.hpp @@ -105,7 +105,7 @@ class IntelligentKeyboard: // Inputs::Mouse. void move(int x, int y) final; - int get_number_of_buttons() final; + int get_number_of_buttons() const final; void set_button_pressed(int index, bool is_pressed) final; void reset_all_buttons() final; diff --git a/Machines/ColecoVision/ColecoVision.cpp b/Machines/ColecoVision/ColecoVision.cpp index 730624697..e45515a62 100644 --- a/Machines/ColecoVision/ColecoVision.cpp +++ b/Machines/ColecoVision/ColecoVision.cpp @@ -357,7 +357,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); return options; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 181eb8cc9..54ea08660 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -678,7 +678,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->quickload = allow_fast_tape_hack_; diff --git a/Machines/Enterprise/Enterprise.cpp b/Machines/Enterprise/Enterprise.cpp index 485889796..325559d30 100644 --- a/Machines/Enterprise/Enterprise.cpp +++ b/Machines/Enterprise/Enterprise.cpp @@ -734,7 +734,7 @@ template class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); return options; diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 66dae2aa4..8a668d8c0 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -812,7 +812,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->quickload = allow_fast_tape_; diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 40ffef60c..c8eccfbf0 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -421,7 +421,7 @@ template class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); return options; diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index f10a4e884..eab424a5d 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -677,7 +677,7 @@ template get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); options->quickload = use_fast_tape_hack_; diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index c0f17eb3f..f1b629e70 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -1118,7 +1118,7 @@ class ConcreteMachine: } // MARK: - Configuration options. - std::unique_ptr get_options() override { + std::unique_ptr get_options() const override { auto options = std::make_unique(Configurable::OptionsType::UserFriendly); options->output = get_video_signal_configurable(); return options; diff --git a/Machines/Sinclair/ZX8081/ZX8081.cpp b/Machines/Sinclair/ZX8081/ZX8081.cpp index 1186c20b7..45a823c76 100644 --- a/Machines/Sinclair/ZX8081/ZX8081.cpp +++ b/Machines/Sinclair/ZX8081/ZX8081.cpp @@ -383,7 +383,7 @@ template class ConcreteMachine: // MARK: - Configuration options. - std::unique_ptr get_options() final { + std::unique_ptr get_options() const final { auto options = std::make_unique(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_; diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index fae483b58..a94b715f0 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -721,7 +721,7 @@ template class ConcreteMachine: // MARK: - Configuration options. - std::unique_ptr get_options() override { + std::unique_ptr get_options() const override { auto options = std::make_unique(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_;