diff --git a/Inputs/Keyboard.cpp b/Inputs/Keyboard.cpp index e90f1f306..6193a5ff8 100644 --- a/Inputs/Keyboard.cpp +++ b/Inputs/Keyboard.cpp @@ -10,13 +10,14 @@ using namespace Inputs; -Keyboard::Keyboard() { +Keyboard::Keyboard(const std::set &essential_modifiers) : essential_modifiers_(essential_modifiers) { for(int k = 0; k < int(Key::Help); ++k) { observed_keys_.insert(Key(k)); } } -Keyboard::Keyboard(const std::set &observed_keys) : observed_keys_(observed_keys), is_exclusive_(false) {} +Keyboard::Keyboard(const std::set &observed_keys, const std::set &essential_modifiers) : + observed_keys_(observed_keys), essential_modifiers_(essential_modifiers), is_exclusive_(false) {} void Keyboard::set_key_pressed(Key key, char value, bool is_pressed) { std::size_t key_offset = static_cast(key); @@ -28,6 +29,10 @@ void Keyboard::set_key_pressed(Key key, char value, bool is_pressed) { if(delegate_) delegate_->keyboard_did_change_key(this, key, is_pressed); } +const std::set &Keyboard::get_essential_modifiers() { + return essential_modifiers_; +} + void Keyboard::reset_all_keys() { std::fill(key_states_.begin(), key_states_.end(), false); if(delegate_) delegate_->reset_all_keys(this); diff --git a/Inputs/Keyboard.hpp b/Inputs/Keyboard.hpp index ee9fe7d72..f93d96179 100644 --- a/Inputs/Keyboard.hpp +++ b/Inputs/Keyboard.hpp @@ -39,10 +39,10 @@ class Keyboard { }; /// Constructs a Keyboard that declares itself to observe all keys. - Keyboard(); + 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); + Keyboard(const std::set &observed_keys, const std::set &essential_modifiers); // Host interface. virtual void set_key_pressed(Key key, char value, bool is_pressed); @@ -51,10 +51,18 @@ class Keyboard { /// @returns a set of all Keys that this keyboard responds to. virtual const std::set &observed_keys(); - /* + /// @returns the list of modifiers that this keyboard considers 'essential' (i.e. both mapped and highly used). + virtual const std::set &get_essential_modifiers(); + + /*! @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(); @@ -68,6 +76,7 @@ class Keyboard { private: std::set observed_keys_; + std::set essential_modifiers_; std::vector key_states_; Delegate *delegate_ = nullptr; bool is_exclusive_ = true; diff --git a/Machines/Apple/Macintosh/Keyboard.cpp b/Machines/Apple/Macintosh/Keyboard.cpp index 9dd89d38a..4be2dcffe 100644 --- a/Machines/Apple/Macintosh/Keyboard.cpp +++ b/Machines/Apple/Macintosh/Keyboard.cpp @@ -86,13 +86,3 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) { #undef Bind } } - -std::set KeyboardMapper::get_essential_modifiers() { - // Control is fairly optional for a Mac, but option, meta and shift - // are essential. - return { - Inputs::Keyboard::Key::LeftShift, Inputs::Keyboard::Key::RightShift, - Inputs::Keyboard::Key::LeftOption, Inputs::Keyboard::Key::RightOption, - Inputs::Keyboard::Key::LeftMeta, Inputs::Keyboard::Key::RightMeta, - }; -} diff --git a/Machines/Apple/Macintosh/Keyboard.hpp b/Machines/Apple/Macintosh/Keyboard.hpp index 6b1060e46..b654ef107 100644 --- a/Machines/Apple/Macintosh/Keyboard.hpp +++ b/Machines/Apple/Macintosh/Keyboard.hpp @@ -292,7 +292,6 @@ class Keyboard { */ class KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper { uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) final; - std::set get_essential_modifiers() final; }; } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 2fb9f5f75..09d91a47d 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -78,6 +78,11 @@ template class ConcreteMachin using Target = Analyser::Static::Macintosh::Target; ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : + KeyboardMachine::MappedMachine({ + Inputs::Keyboard::Key::LeftShift, Inputs::Keyboard::Key::RightShift, + Inputs::Keyboard::Key::LeftOption, Inputs::Keyboard::Key::RightOption, + Inputs::Keyboard::Key::LeftMeta, Inputs::Keyboard::Key::RightMeta, + }), mc68000_(*this), iwm_(CLOCK_RATE), video_(audio_, drive_speed_accumulator_), diff --git a/Machines/KeyboardMachine.cpp b/Machines/KeyboardMachine.cpp index 5d7084028..0d79387ee 100644 --- a/Machines/KeyboardMachine.cpp +++ b/Machines/KeyboardMachine.cpp @@ -10,7 +10,7 @@ using namespace KeyboardMachine; -MappedMachine::MappedMachine() { +MappedMachine::MappedMachine(const std::set &essential_modifiers) : keyboard_(essential_modifiers) { keyboard_.set_delegate(this); } diff --git a/Machines/KeyboardMachine.hpp b/Machines/KeyboardMachine.hpp index 276411c52..84fcd517f 100644 --- a/Machines/KeyboardMachine.hpp +++ b/Machines/KeyboardMachine.hpp @@ -57,7 +57,7 @@ class Machine: public KeyActions { */ class MappedMachine: public Inputs::Keyboard::Delegate, public Machine { public: - MappedMachine(); + MappedMachine(const std::set &essential_modifiers = {}); /*! A keyboard mapper attempts to provide a physical mapping between host keys and emulated keys. @@ -66,7 +66,6 @@ class MappedMachine: public Inputs::Keyboard::Delegate, public Machine { class KeyboardMapper { public: virtual uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) = 0; - virtual std::set get_essential_modifiers() { return {}; } }; /// Terminates a key sequence from the character mapper. diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 7aff87195..152ddb018 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -101,7 +101,7 @@ class ConcreteMachine: audio_queue_, sn76489_divider), speaker_(sn76489_), - keyboard_({Inputs::Keyboard::Key::Enter, Inputs::Keyboard::Key::Escape}) { + keyboard_({Inputs::Keyboard::Key::Enter, Inputs::Keyboard::Key::Escape}, {}) { // Pick the clock rate based on the region. const double clock_rate = target.region == Target::Region::Europe ? 3546893.0 : 3579540.0; speaker_.set_input_rate(static_cast(clock_rate / sn76489_divider));