diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.cpp index bb5cd0ce1..f1405b499 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.cpp @@ -30,13 +30,13 @@ void MultiKeyboardMachine::set_key_state(const uint16_t key, const bool is_press } } -void MultiKeyboardMachine::type_string(const std::string &string) { +void MultiKeyboardMachine::type_string(const std::wstring &string) { for(const auto &machine: machines_) { machine->type_string(string); } } -bool MultiKeyboardMachine::can_type(const char c) const { +bool MultiKeyboardMachine::can_type(const wchar_t c) const { bool can_type = true; for(const auto &machine: machines_) { can_type &= machine->can_type(c); @@ -44,7 +44,7 @@ bool MultiKeyboardMachine::can_type(const char c) const { return can_type; } -Inputs::Keyboard &MultiKeyboardMachine::get_keyboard() { +Inputs::Keyboard &MultiKeyboardMachine::keyboard() { return *keyboard_; } @@ -52,10 +52,10 @@ MultiKeyboardMachine::MultiKeyboard::MultiKeyboard(const std::vector<::MachineTy : machines_(machines) { for(const auto &machine: machines_) { observed_keys_.insert( - machine->get_keyboard().observed_keys().begin(), - machine->get_keyboard().observed_keys().end() + machine->keyboard().observed_keys().begin(), + machine->keyboard().observed_keys().end() ); - is_exclusive_ |= machine->get_keyboard().is_exclusive(); + is_exclusive_ |= machine->keyboard().is_exclusive(); } } @@ -67,14 +67,14 @@ bool MultiKeyboardMachine::MultiKeyboard::set_key_pressed( ) { bool was_consumed = false; for(const auto &machine: machines_) { - was_consumed |= machine->get_keyboard().set_key_pressed(key, value, is_pressed, is_repeat); + was_consumed |= machine->keyboard().set_key_pressed(key, value, is_pressed, is_repeat); } return was_consumed; } void MultiKeyboardMachine::MultiKeyboard::reset_all_keys() { for(const auto &machine: machines_) { - machine->get_keyboard().reset_all_keys(); + machine->keyboard().reset_all_keys(); } } diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp index 880e2f91d..970408ec5 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp @@ -48,9 +48,9 @@ public: // Below is the standard KeyboardMachine::Machine interface; see there for documentation. void clear_all_keys() final; void set_key_state(uint16_t key, bool is_pressed) final; - void type_string(const std::string &) final; - bool can_type(char c) const final; - Inputs::Keyboard &get_keyboard() final; + void type_string(const std::wstring &) final; + bool can_type(wchar_t) const final; + Inputs::Keyboard &keyboard() final; }; } diff --git a/Analyser/Static/Acorn/StaticAnalyser.cpp b/Analyser/Static/Acorn/StaticAnalyser.cpp index 75dfed7e9..1086762d5 100644 --- a/Analyser/Static/Acorn/StaticAnalyser.cpp +++ b/Analyser/Static/Acorn/StaticAnalyser.cpp @@ -113,8 +113,9 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets( if(!files.empty()) { // Inspect first file. If it's protected or doesn't look like BASIC // then the loading command is *RUN. Otherwise it's CHAIN"". - targetElectron->loading_command = + const std::string loading_command = (files.front().flags & File::Flags::ExecuteOnly) || !is_basic(files.front()) ? "*RUN\n" : "CHAIN\"\"\n"; + targetElectron->loading_command = std::wstring(loading_command.begin(), loading_command.end()); targetElectron->media.tapes = media.tapes; // TODO: my BBC Micro doesn't yet support tapes; evaluate here in the future. @@ -171,8 +172,10 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets( } } - targetBBC->loading_command = targetElectron->loading_command = + const std::string loading_command = sole_basic_file ? "CHAIN \"" + sole_basic_file->name + "\"\n" : "*CAT\n"; + targetBBC->loading_command = targetElectron->loading_command = + std::wstring(loading_command.begin(), loading_command.end()); } // Further special case: if any of the files have a top word of 0x0003 then @@ -329,7 +332,7 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets( if(sector[0xfd]) { targetElectron->should_shift_restart = true; } else { - targetElectron->loading_command = "*CAT\n"; + targetElectron->loading_command = L"*CAT\n"; } } diff --git a/Analyser/Static/AmstradCPC/StaticAnalyser.cpp b/Analyser/Static/AmstradCPC/StaticAnalyser.cpp index 39d5e2148..acfadb280 100644 --- a/Analyser/Static/AmstradCPC/StaticAnalyser.cpp +++ b/Analyser/Static/AmstradCPC/StaticAnalyser.cpp @@ -52,7 +52,7 @@ void right_trim(std::string &string) { }).base(), string.end()); } -std::string RunCommandFor(const Storage::Disk::CPM::File &file) { +std::wstring RunCommandFor(const Storage::Disk::CPM::File &file) { // Trim spaces from the name. std::string name = file.name; right_trim(name); @@ -68,7 +68,8 @@ std::string RunCommandFor(const Storage::Disk::CPM::File &file) { } // Add a newline and return. - return command + "\n"; + command += "\n"; + return std::wstring(command.begin(), command.end()); } void InspectCatalogue( @@ -189,9 +190,10 @@ void InspectCatalogue( } (); if(run_name.has_value()) { - target->loading_command = "run\"" + rtrimmed(*run_name) + "\n"; + const std::string loading_command = "run\"" + rtrimmed(*run_name) + "\n"; + target->loading_command = std::wstring(loading_command.begin(), loading_command.end()); } else { - target->loading_command = "cat\n"; + target->loading_command = L"cat\n"; } } @@ -214,7 +216,7 @@ bool CheckBootSector( // This is a system disk, then launch it as though it were CP/M. if(!matched) { - target->loading_command = "|cpm\n"; + target->loading_command = L"|cpm\n"; return true; } } @@ -269,7 +271,7 @@ Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets( // Ugliness flows here: assume the CPC isn't smart enough to pause between pressing // enter and responding to the follow-on prompt to press a key, so just type for // a while. Yuck! - target->loading_command = "|tape\nrun\"\n123"; + target->loading_command = L"|tape\nrun\"\n123"; } } diff --git a/Analyser/Static/Commodore/StaticAnalyser.cpp b/Analyser/Static/Commodore/StaticAnalyser.cpp index 8935250ac..35a8476d9 100644 --- a/Analyser/Static/Commodore/StaticAnalyser.cpp +++ b/Analyser/Static/Commodore/StaticAnalyser.cpp @@ -163,9 +163,9 @@ std::optional analyse(const File &file) { template void set_loading_command(TargetT &target) { if(target.media.disks.empty()) { - target.loading_command = "LOAD\"\",1,1\nRUN\n"; + target.loading_command = L"LOAD\"\",1,1\nRUN\n"; } else { - target.loading_command = "LOAD\"*\",8,1\nRUN\n"; + target.loading_command = L"LOAD\"*\",8,1\nRUN\n"; } } diff --git a/Analyser/Static/DiskII/StaticAnalyser.cpp b/Analyser/Static/DiskII/StaticAnalyser.cpp index 857e5d6ec..d8f4d032d 100644 --- a/Analyser/Static/DiskII/StaticAnalyser.cpp +++ b/Analyser/Static/DiskII/StaticAnalyser.cpp @@ -41,7 +41,7 @@ Analyser::Static::Target *OricTarget(const Storage::Encodings::AppleGCR::Sector auto *const target = new Target; target->rom = Target::ROM::Pravetz; target->disk_interface = Target::DiskInterface::Pravetz; - target->loading_command = "CALL 800\n"; + target->loading_command = L"CALL 800\n"; return target; } diff --git a/Analyser/Static/Oric/StaticAnalyser.cpp b/Analyser/Static/Oric/StaticAnalyser.cpp index 84c0d1993..d123d814a 100644 --- a/Analyser/Static/Oric/StaticAnalyser.cpp +++ b/Analyser/Static/Oric/StaticAnalyser.cpp @@ -212,7 +212,7 @@ Analyser::Static::TargetList Analyser::Static::Oric::GetTargets( } target->media.tapes.push_back(tape); - target->loading_command = "CLOAD\"\"\n"; + target->loading_command = L"CLOAD\"\"\n"; } } diff --git a/Analyser/Static/Thomson/StaticAnalyser.cpp b/Analyser/Static/Thomson/StaticAnalyser.cpp index 0948fee26..25055824d 100644 --- a/Analyser/Static/Thomson/StaticAnalyser.cpp +++ b/Analyser/Static/Thomson/StaticAnalyser.cpp @@ -37,9 +37,9 @@ Analyser::Static::TargetList Analyser::Static::Thomson::GetTargets( static constexpr size_t TypeOffset = 0xb; if(!first->type && first->data.size() > TypeOffset) { if(!first->data[TypeOffset]) { // File type; 0 = BASIC, 1 = DATA; 2 = binary. - target->loading_command = "RUN\"\n"; + target->loading_command = L"RUN\"\n"; } else { - target->loading_command = "LOADM\"\",,R\n"; + target->loading_command = L"LOADM\"\",,R\n"; } } } diff --git a/Analyser/Static/ZX8081/StaticAnalyser.cpp b/Analyser/Static/ZX8081/StaticAnalyser.cpp index 409ec51da..3e155afcd 100644 --- a/Analyser/Static/ZX8081/StaticAnalyser.cpp +++ b/Analyser/Static/ZX8081/StaticAnalyser.cpp @@ -64,9 +64,9 @@ Analyser::Static::TargetList Analyser::Static::ZX8081::GetTargets( // TODO: how to run software once loaded? Might require a BASIC detokeniser. if(target->is_ZX81) { - target->loading_command = "J\"\"\n"; + target->loading_command = L"J\"\"\n"; } else { - target->loading_command = "W\n"; + target->loading_command = L"W\n"; } } diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index 0fad6831d..1e03df7ea 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -535,7 +535,7 @@ private: } // MARK: - MappedKeyboardMachine. - MappedKeyboardMachine::KeyboardMapper *get_keyboard_mapper() override { + MappedKeyboardMachine::KeyboardMapper *keyboard_mapper() override { return &keyboard_mapper_; } Archimedes::KeyboardMapper keyboard_mapper_; diff --git a/Machines/Acorn/Archimedes/Keyboard.hpp b/Machines/Acorn/Archimedes/Keyboard.hpp index 1912d3562..695e7b250 100644 --- a/Machines/Acorn/Archimedes/Keyboard.hpp +++ b/Machines/Acorn/Archimedes/Keyboard.hpp @@ -75,7 +75,7 @@ struct Key { struct Keyboard { Keyboard(HalfDuplexSerial &serial) : serial_(serial), mouse_(*this) {} - void set_key_state(uint16_t key, bool is_pressed) { + void set_key_state(const uint16_t key, const bool is_pressed) { states_[key] = is_pressed; if(!scan_keyboard_) { @@ -91,7 +91,7 @@ struct Keyboard { consider_dequeue(); } - void set_mouse_button(uint8_t button, bool is_pressed) { + void set_mouse_button(const uint8_t button, const bool is_pressed) { if(!scan_mouse_) { return; } diff --git a/Machines/Acorn/BBCMicro/BBCMicro.cpp b/Machines/Acorn/BBCMicro/BBCMicro.cpp index dd9da44d2..255fa5c4a 100644 --- a/Machines/Acorn/BBCMicro/BBCMicro.cpp +++ b/Machines/Acorn/BBCMicro/BBCMicro.cpp @@ -1105,12 +1105,12 @@ private: // MARK: - KeyboardMachine. BBCMicro::KeyboardMapper mapper_; - KeyboardMapper *get_keyboard_mapper() override { + KeyboardMapper *keyboard_mapper() override { return &mapper_; } void set_key_state(const uint16_t key, const bool is_pressed) override { - switch(Key(key)) { + switch(key) { case Key::SwitchOffCaps: // Store current caps lock state for a potential restore; press caps lock // now if there's a need to exit caps lock mode. @@ -1150,7 +1150,7 @@ private: } } - HalfCycles get_typer_delay(const std::string &text) const final { + HalfCycles typer_delay(const std::wstring &text) const final { if(!m6502_.is_resetting()) { return Cycles(0); } @@ -1159,19 +1159,19 @@ private: // empirically this seems to be a requirement, in order to avoid a collision with // the system's built-in modifier-at-startup test (e.g. to perform shift+break). CharacterMapper test_mapper; - const uint16_t *const sequence = test_mapper.sequence_for_character(text[0]); - return is_modifier(Key(sequence[0])) ? Cycles(1'000'000) : Cycles(750'000); + const auto front = (*test_mapper.sequence_for_character(text[0]))[0]; + return is_modifier(Key::Key(front)) ? Cycles(1'000'000) : Cycles(750'000); } - HalfCycles get_typer_frequency() const final { + HalfCycles typer_frequency() const final { return Cycles(60'000); } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(const char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } diff --git a/Machines/Acorn/BBCMicro/Keyboard.hpp b/Machines/Acorn/BBCMicro/Keyboard.hpp index 964f8ab66..470e46c45 100644 --- a/Machines/Acorn/BBCMicro/Keyboard.hpp +++ b/Machines/Acorn/BBCMicro/Keyboard.hpp @@ -13,10 +13,12 @@ #include #include +#include namespace BBCMicro { -enum class Key: uint16_t { +namespace Key { +enum Key: uint16_t { Escape = 0x70, Q = 0x10, F0 = 0x20, k1 = 0x30, CapsLock = 0x40, ShiftLock = 0x50, Tab = 0x60, Shift = 0x00, F1 = 0x71, k3 = 0x11, W = 0x21, k2 = 0x31, @@ -78,8 +80,9 @@ enum class Key: uint16_t { MouseMenu = 0x0a, MouseAdjust = 0x0b, }; +} -constexpr bool is_modifier(const Key key) { +constexpr bool is_modifier(const Key::Key key) { return key == Key::Shift || key == Key::Control; } @@ -142,9 +145,8 @@ private: }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(const char character) const override { - const auto found = sequences.find(character); - return found != sequences.end() ? found->second.data() : nullptr; + const std::vector *sequence_for_character(const wchar_t character) const override { + return lookup_sequence(sequences, character); } bool needs_pause_after_reset_all_keys() const override { return false; } @@ -153,100 +155,86 @@ struct CharacterMapper: public ::Utility::CharacterMapper { } private: - static constexpr size_t MaxSequenceLength = 4; - using Sequence = std::array; + static inline const std::unordered_map> sequences = { + {Utility::Typer::BeginString, {Key::SwitchOffCaps}}, + {Utility::Typer::EndString, {Key::RestoreCaps}}, - template - requires (n < MaxSequenceLength - 1) - static constexpr Sequence keys(const Key (&keys)[n]){ - Sequence sequence; - for(size_t c = 0; c < n; c++) { - sequence[c] = uint16_t(keys[c]); - } - sequence[n] = MachineTypes::MappedKeyboardMachine::KeyEndSequence; - return sequence; - } + {L'q', {Key::Q} }, {L'w', {Key::W} }, + {L'e', {Key::E} }, {L'r', {Key::R} }, + {L't', {Key::T} }, {L'y', {Key::Y} }, + {L'u', {Key::U} }, {L'i', {Key::I} }, + {L'o', {Key::O} }, {L'p', {Key::P} }, + {L'a', {Key::A} }, {L's', {Key::S} }, + {L'd', {Key::D} }, {L'f', {Key::F} }, + {L'g', {Key::G} }, {L'h', {Key::H} }, + {L'j', {Key::J} }, {L'k', {Key::K} }, + {L'l', {Key::L} }, {L'z', {Key::Z} }, + {L'x', {Key::X} }, {L'c', {Key::C} }, + {L'v', {Key::V} }, {L'b', {Key::B} }, + {L'n', {Key::N} }, {L'm', {Key::M} }, - static inline const std::unordered_map sequences = { - {Utility::Typer::BeginString, keys({Key::SwitchOffCaps})}, - {Utility::Typer::EndString, keys({Key::RestoreCaps})}, + {L'Q', {Key::Shift, Key::Q} }, {L'W', {Key::Shift, Key::W} }, + {L'E', {Key::Shift, Key::E} }, {L'R', {Key::Shift, Key::R} }, + {L'T', {Key::Shift, Key::T} }, {L'Y', {Key::Shift, Key::Y} }, + {L'U', {Key::Shift, Key::U} }, {L'I', {Key::Shift, Key::I} }, + {L'O', {Key::Shift, Key::O} }, {L'P', {Key::Shift, Key::P} }, + {L'A', {Key::Shift, Key::A} }, {L'S', {Key::Shift, Key::S} }, + {L'D', {Key::Shift, Key::D} }, {L'F', {Key::Shift, Key::F} }, + {L'G', {Key::Shift, Key::G} }, {L'H', {Key::Shift, Key::H} }, + {L'J', {Key::Shift, Key::J} }, {L'K', {Key::Shift, Key::K} }, + {L'L', {Key::Shift, Key::L} }, {L'Z', {Key::Shift, Key::Z} }, + {L'X', {Key::Shift, Key::X} }, {L'C', {Key::Shift, Key::C} }, + {L'V', {Key::Shift, Key::V} }, {L'B', {Key::Shift, Key::B} }, + {L'N', {Key::Shift, Key::N} }, {L'M', {Key::Shift, Key::M} }, - {'q', keys({Key::Q}) }, {'w', keys({Key::W}) }, - {'e', keys({Key::E}) }, {'r', keys({Key::R}) }, - {'t', keys({Key::T}) }, {'y', keys({Key::Y}) }, - {'u', keys({Key::U}) }, {'i', keys({Key::I}) }, - {'o', keys({Key::O}) }, {'p', keys({Key::P}) }, - {'a', keys({Key::A}) }, {'s', keys({Key::S}) }, - {'d', keys({Key::D}) }, {'f', keys({Key::F}) }, - {'g', keys({Key::G}) }, {'h', keys({Key::H}) }, - {'j', keys({Key::J}) }, {'k', keys({Key::K}) }, - {'l', keys({Key::L}) }, {'z', keys({Key::Z}) }, - {'x', keys({Key::X}) }, {'c', keys({Key::C}) }, - {'v', keys({Key::V}) }, {'b', keys({Key::B}) }, - {'n', keys({Key::N}) }, {'m', keys({Key::M}) }, + {L'0', {Key::k0} }, {L'1', {Key::k1} }, + {L'2', {Key::k2} }, {L'3', {Key::k3} }, + {L'4', {Key::k4} }, {L'5', {Key::k5} }, + {L'6', {Key::k6} }, {L'7', {Key::k7} }, + {L'8', {Key::k8} }, {L'9', {Key::k9} }, - {'Q', keys({Key::Shift, Key::Q}) }, {'W', keys({Key::Shift, Key::W}) }, - {'E', keys({Key::Shift, Key::E}) }, {'R', keys({Key::Shift, Key::R}) }, - {'T', keys({Key::Shift, Key::T}) }, {'Y', keys({Key::Shift, Key::Y}) }, - {'U', keys({Key::Shift, Key::U}) }, {'I', keys({Key::Shift, Key::I}) }, - {'O', keys({Key::Shift, Key::O}) }, {'P', keys({Key::Shift, Key::P}) }, - {'A', keys({Key::Shift, Key::A}) }, {'S', keys({Key::Shift, Key::S}) }, - {'D', keys({Key::Shift, Key::D}) }, {'F', keys({Key::Shift, Key::F}) }, - {'G', keys({Key::Shift, Key::G}) }, {'H', keys({Key::Shift, Key::H}) }, - {'J', keys({Key::Shift, Key::J}) }, {'K', keys({Key::Shift, Key::K}) }, - {'L', keys({Key::Shift, Key::L}) }, {'Z', keys({Key::Shift, Key::Z}) }, - {'X', keys({Key::Shift, Key::X}) }, {'C', keys({Key::Shift, Key::C}) }, - {'V', keys({Key::Shift, Key::V}) }, {'B', keys({Key::Shift, Key::B}) }, - {'N', keys({Key::Shift, Key::N}) }, {'M', keys({Key::Shift, Key::M}) }, + {L'\n', {Key::Return} }, + {L'\r', {Key::Return} }, + {L'\b', {Key::Delete} }, + {L'\t', {Key::Tab} }, + {L' ', {Key::Space} }, - {'0', keys({Key::k0}) }, {'1', keys({Key::k1}) }, - {'2', keys({Key::k2}) }, {'3', keys({Key::k3}) }, - {'4', keys({Key::k4}) }, {'5', keys({Key::k5}) }, - {'6', keys({Key::k6}) }, {'7', keys({Key::k7}) }, - {'8', keys({Key::k8}) }, {'9', keys({Key::k9}) }, + {L'!', {Key::Shift, Key::k1} }, + {L'"', {Key::Shift, Key::k2} }, + {L'#', {Key::Shift, Key::k3} }, + {L'$', {Key::Shift, Key::k4} }, + {L'%', {Key::Shift, Key::k5} }, + {L'&', {Key::Shift, Key::k6} }, + {L'\'', {Key::Shift, Key::k7} }, + {L'(', {Key::Shift, Key::k8} }, + {L')', {Key::Shift, Key::k9} }, - {'\n', keys({Key::Return}) }, - {'\r', keys({Key::Return}) }, - {'\b', keys({Key::Delete}) }, - {'\t', keys({Key::Tab}) }, - {' ', keys({Key::Space}) }, + {L'-', {Key::Hyphen} }, + {L'^', {Key::Caret} }, + {L'\\', {Key::Backslash} }, + {L'=', {Key::Shift, Key::Hyphen} }, + {L'~', {Key::Shift, Key::Caret} }, + {L'|', {Key::Shift, Key::Backslash} }, - {'!', keys({Key::Shift, Key::k1}) }, - {'"', keys({Key::Shift, Key::k2}) }, - {'#', keys({Key::Shift, Key::k3}) }, - {'$', keys({Key::Shift, Key::k4}) }, - {'%', keys({Key::Shift, Key::k5}) }, - {'&', keys({Key::Shift, Key::k6}) }, - {'\'', keys({Key::Shift, Key::k7}) }, - {'(', keys({Key::Shift, Key::k8}) }, - {')', keys({Key::Shift, Key::k9}) }, + {L'@', {Key::At} }, + {L'[', {Key::OpenSquareBracket} }, + {L'_', {Key::Underscore} }, + {L'{', {Key::Shift, Key::OpenSquareBracket} }, + {L'£', {Key::Shift, Key::Underscore} }, - {'-', keys({Key::Hyphen}) }, - {'^', keys({Key::Caret}) }, - {'\\', keys({Key::Backslash}) }, - {'=', keys({Key::Shift, Key::Hyphen}) }, - {'~', keys({Key::Shift, Key::Caret}) }, - {'|', keys({Key::Shift, Key::Backslash}) }, + {L';', {Key::Semicolon} }, + {L':', {Key::Colon} }, + {L']', {Key::CloseSquareBracket} }, + {L'+', {Key::Shift, Key::Semicolon} }, + {L'*', {Key::Shift, Key::Colon} }, + {L'}', {Key::Shift, Key::CloseSquareBracket} }, - {'@', keys({Key::At}) }, - {'[', keys({Key::OpenSquareBracket}) }, - {'_', keys({Key::Underscore}) }, - {'{', keys({Key::Shift, Key::OpenSquareBracket}) }, -// {'£', keys({BBCKey::Shift, BBCKey::Underscore}) }, - - {';', keys({Key::Semicolon}) }, - {':', keys({Key::Colon}) }, - {']', keys({Key::CloseSquareBracket}) }, - {'+', keys({Key::Shift, Key::Semicolon}) }, - {'*', keys({Key::Shift, Key::Colon}) }, - {'}', keys({Key::Shift, Key::CloseSquareBracket}) }, - - {',', keys({Key::Comma}) }, - {'.', keys({Key::FullStop}) }, - {'/', keys({Key::ForwardSlash}) }, - {'<', keys({Key::Shift, Key::Comma}) }, - {'>', keys({Key::Shift, Key::FullStop}) }, - {'?', keys({Key::Shift, Key::ForwardSlash}) }, + {L',', {Key::Comma} }, + {L'.', {Key::FullStop} }, + {L'/', {Key::ForwardSlash} }, + {L'<', {Key::Shift, Key::Comma} }, + {L'>', {Key::Shift, Key::FullStop} }, + {L'?', {Key::Shift, Key::ForwardSlash} }, }; }; diff --git a/Machines/Acorn/Electron/Electron.cpp b/Machines/Acorn/Electron/Electron.cpp index 3905ae367..016031a5a 100644 --- a/Machines/Acorn/Electron/Electron.cpp +++ b/Machines/Acorn/Electron/Electron.cpp @@ -570,7 +570,7 @@ public: evaluate_interrupts(); } - HalfCycles get_typer_delay(const std::string &text) const final { + HalfCycles get_typer_delay(const std::wstring &text) const final { if(!m6502_.get_is_resetting()) { return Cycles(0); } @@ -587,15 +587,15 @@ public: return Cycles(60'000); } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Acorn/Electron/Keyboard.cpp b/Machines/Acorn/Electron/Keyboard.cpp index b710c26d9..1ce460da1 100644 --- a/Machines/Acorn/Electron/Keyboard.cpp +++ b/Machines/Acorn/Electron/Keyboard.cpp @@ -70,82 +70,71 @@ uint16_t KeyboardMapper::mapped_key_for_key(const Inputs::Keyboard::Key key) con return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(const char character) const { -#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define SHIFT(...) {KeyShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define CTRL(...) {KeyControl, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ KEYS(KeyDelete), /* HT */ X, - /* LF */ KEYS(KeyReturn), /* VT */ X, - /* FF */ X, /* CR */ KEYS(KeyReturn), - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), - /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), - /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), - /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), - /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), - /* * */ SHIFT(KeyColon), /* + */ SHIFT(KeySemiColon), - /* , */ KEYS(KeyComma), /* - */ KEYS(KeyMinus), - /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeySlash), - /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), - /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), - /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), - /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), - /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), - /* : */ KEYS(KeyColon), /* ; */ KEYS(KeySemiColon), - /* < */ SHIFT(KeyComma), /* = */ SHIFT(KeyMinus), - /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeySlash), - /* @ */ SHIFT(Key0), /* A */ KEYS(KeyA), - /* B */ KEYS(KeyB), /* C */ KEYS(KeyC), - /* D */ KEYS(KeyD), /* E */ KEYS(KeyE), - /* F */ KEYS(KeyF), /* G */ KEYS(KeyG), - /* H */ KEYS(KeyH), /* I */ KEYS(KeyI), - /* J */ KEYS(KeyJ), /* K */ KEYS(KeyK), - /* L */ KEYS(KeyL), /* M */ KEYS(KeyM), - /* N */ KEYS(KeyN), /* O */ KEYS(KeyO), - /* P */ KEYS(KeyP), /* Q */ KEYS(KeyQ), - /* R */ KEYS(KeyR), /* S */ KEYS(KeyS), - /* T */ KEYS(KeyT), /* U */ KEYS(KeyU), - /* V */ KEYS(KeyV), /* W */ KEYS(KeyW), - /* X */ KEYS(KeyX), /* Y */ KEYS(KeyY), - /* Z */ KEYS(KeyZ), /* [ */ SHIFT(KeyCopy), - /* \ */ CTRL(KeyRight), /* ] */ CTRL(KeyCopy), - /* ^ */ SHIFT(KeyLeft), /* _ */ SHIFT(KeyDown), - /* ` */ X, /* a */ SHIFT(KeyA), - /* b */ SHIFT(KeyB), /* c */ SHIFT(KeyC), - /* d */ SHIFT(KeyD), /* e */ SHIFT(KeyE), - /* f */ SHIFT(KeyF), /* g */ SHIFT(KeyG), - /* h */ SHIFT(KeyH), /* i */ SHIFT(KeyI), - /* j */ SHIFT(KeyJ), /* k */ SHIFT(KeyK), - /* l */ SHIFT(KeyL), /* m */ SHIFT(KeyM), - /* n */ SHIFT(KeyN), /* o */ SHIFT(KeyO), - /* p */ SHIFT(KeyP), /* q */ SHIFT(KeyQ), - /* r */ SHIFT(KeyR), /* s */ SHIFT(KeyS), - /* t */ SHIFT(KeyT), /* u */ SHIFT(KeyU), - /* v */ SHIFT(KeyV), /* w */ SHIFT(KeyW), - /* x */ SHIFT(KeyX), /* y */ SHIFT(KeyY), - /* z */ SHIFT(KeyZ), /* { */ CTRL(KeyUp), - /* | */ SHIFT(KeyRight), /* } */ CTRL(KeyDown), - /* ~ */ CTRL(KeyLeft) - }; -#undef KEYS -#undef SHIFT -#undef X +namespace { +const std::unordered_map> sequences = { + {L'\b', {KeyDelete}}, + {L'\n', {KeyReturn}}, {L'\r', {KeyReturn}}, + {L' ', {KeySpace}}, - return table_lookup_sequence_for_character(key_sequences, character); + {L'!', {KeyShift, Key1}}, + {L'"', {KeyShift, Key2}}, + {L'#', {KeyShift, Key3}}, + {L'$', {KeyShift, Key4}}, + {L'%', {KeyShift, Key5}}, + {L'&', {KeyShift, Key6}}, + {L'\'', {KeyShift, Key7}}, + {L'(', {KeyShift, Key8}}, + {L')', {KeyShift, Key9}}, + {L'@', {KeyShift, Key0}}, + + {L'-', {KeyMinus}}, + {L'=', {KeyShift, KeyMinus}}, + + {L'^', {KeyShift, KeyLeft}}, + {L'~', {KeyControl, KeyLeft}}, + {L'|', {KeyShift, KeyRight}}, + {L'\\', {KeyControl, KeyRight}}, + {L'£', {KeyShift, KeyUp}}, + {L'{', {KeyControl, KeyUp}}, + {L'_', {KeyShift, KeyDown}}, + {L'}', {KeyControl, KeyDown}}, + {L'[', {KeyShift, KeyCopy}}, + {L']', {KeyControl, KeyCopy}}, + + {L'+', {KeyShift, KeySemiColon}}, {L';', {KeySemiColon}}, + {L'*', {KeyShift, KeyColon}}, {L':', {KeyColon}}, + + {L'<', {KeyShift, KeyComma}}, {L',', {KeyComma}}, + {L'>', {KeyShift, KeyFullStop}}, {L'.', {KeyFullStop}}, + {L'?', {KeyShift, KeySlash}}, {L'/', {KeySlash}}, + + {L'0', {Key0}}, {L'1', {Key1}}, {L'2', {Key2}}, {L'3', {Key3}}, {L'4', {Key4}}, + {L'5', {Key5}}, {L'6', {Key6}}, {L'7', {Key7}}, {L'8', {Key8}}, {L'9', {Key9}}, + + {L'a', {KeyShift, KeyA}}, {L'b', {KeyShift, KeyB}}, {L'c', {KeyShift, KeyC}}, + {L'd', {KeyShift, KeyD}}, {L'e', {KeyShift, KeyE}}, {L'f', {KeyShift, KeyF}}, + {L'g', {KeyShift, KeyG}}, {L'h', {KeyShift, KeyH}}, {L'i', {KeyShift, KeyI}}, + {L'j', {KeyShift, KeyJ}}, {L'k', {KeyShift, KeyK}}, {L'l', {KeyShift, KeyL}}, + {L'm', {KeyShift, KeyM}}, {L'n', {KeyShift, KeyN}}, {L'o', {KeyShift, KeyO}}, + {L'p', {KeyShift, KeyP}}, {L'q', {KeyShift, KeyQ}}, {L'r', {KeyShift, KeyR}}, + {L's', {KeyShift, KeyS}}, {L't', {KeyShift, KeyT}}, {L'u', {KeyShift, KeyU}}, + {L'v', {KeyShift, KeyV}}, {L'w', {KeyShift, KeyW}}, {L'x', {KeyShift, KeyX}}, + {L'y', {KeyShift, KeyY}}, {L'z', {KeyShift, KeyZ}}, + + {L'A', {KeyA}}, {L'B', {KeyB}}, {L'C', {KeyC}}, + {L'D', {KeyD}}, {L'E', {KeyE}}, {L'F', {KeyF}}, + {L'G', {KeyG}}, {L'H', {KeyH}}, {L'I', {KeyI}}, + {L'J', {KeyJ}}, {L'K', {KeyK}}, {L'L', {KeyL}}, + {L'M', {KeyM}}, {L'N', {KeyN}}, {L'O', {KeyO}}, + {L'P', {KeyP}}, {L'Q', {KeyQ}}, {L'R', {KeyR}}, + {L'S', {KeyS}}, {L'T', {KeyT}}, {L'U', {KeyU}}, + {L'V', {KeyV}}, {L'W', {KeyW}}, {L'X', {KeyX}}, + {L'Y', {KeyY}}, {L'Z', {KeyZ}}, +}; +} + +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); } bool CharacterMapper::needs_pause_after_key(const uint16_t key) const { diff --git a/Machines/Acorn/Electron/Keyboard.hpp b/Machines/Acorn/Electron/Keyboard.hpp index 840121013..15c929b20 100644 --- a/Machines/Acorn/Electron/Keyboard.hpp +++ b/Machines/Acorn/Electron/Keyboard.hpp @@ -43,7 +43,7 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char character) const override; + const std::vector *sequence_for_character(wchar_t) const override; bool needs_pause_after_reset_all_keys() const override { return false; } bool needs_pause_after_key(uint16_t key) const override; diff --git a/Machines/Amiga/Amiga.cpp b/Machines/Amiga/Amiga.cpp index 5dfa3bd2b..00fa98c6f 100644 --- a/Machines/Amiga/Amiga.cpp +++ b/Machines/Amiga/Amiga.cpp @@ -233,16 +233,16 @@ private: // MARK: - Keyboard. Amiga::KeyboardMapper keyboard_mapper_; - KeyboardMapper *get_keyboard_mapper() { + KeyboardMapper *keyboard_mapper() { return &keyboard_mapper_; } void set_key_state(uint16_t key, bool is_pressed) { - chipset_.get_keyboard().set_key_state(key, is_pressed); + chipset_.keyboard().set_key_state(key, is_pressed); } void clear_all_keys() { - chipset_.get_keyboard().clear_all_keys(); + chipset_.keyboard().clear_all_keys(); } }; diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index be7605a57..0f4fbf155 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -92,7 +92,7 @@ public: } // Keyboard and mouse exposure. - Keyboard &get_keyboard() { + Keyboard &keyboard() { return keyboard_; } diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index beb03bab7..b1386224e 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -1185,15 +1185,15 @@ public: } // MARK: - Keyboard - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(const char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } - HalfCycles get_typer_delay(const std::string &) const final { + HalfCycles get_typer_delay(const std::wstring &) const final { return z80_.get_is_resetting() ? Cycles(3'400'000) : Cycles(0); } @@ -1211,7 +1211,7 @@ public: key_state_.clear_all_keys(); } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/AmstradCPC/Keyboard.cpp b/Machines/AmstradCPC/Keyboard.cpp index 9d278a870..595317b43 100644 --- a/Machines/AmstradCPC/Keyboard.cpp +++ b/Machines/AmstradCPC/Keyboard.cpp @@ -77,81 +77,65 @@ uint16_t KeyboardMapper::mapped_key_for_key(const Inputs::Keyboard::Key key) con return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(const char character) const { -#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define SHIFT(...) {KeyShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ KEYS(KeyDelete), /* HT */ X, - /* LF */ KEYS(KeyReturn), /* VT */ X, - /* FF */ X, /* CR */ KEYS(KeyReturn), - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), - /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), - /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), - /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), - /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), - /* * */ SHIFT(KeyColon), /* + */ SHIFT(KeySemicolon), - /* , */ KEYS(KeyComma), /* - */ KEYS(KeyMinus), - /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeyForwardSlash), - /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), - /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), - /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), - /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), - /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), - /* : */ KEYS(KeyColon), /* ; */ KEYS(KeySemicolon), - /* < */ SHIFT(KeyComma), /* = */ SHIFT(KeyMinus), - /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeyForwardSlash), - /* @ */ SHIFT(KeyAt), /* A */ SHIFT(KeyA), - /* B */ SHIFT(KeyB), /* C */ SHIFT(KeyC), - /* D */ SHIFT(KeyD), /* E */ SHIFT(KeyE), - /* F */ SHIFT(KeyF), /* G */ SHIFT(KeyG), - /* H */ SHIFT(KeyH), /* I */ SHIFT(KeyI), - /* J */ SHIFT(KeyJ), /* K */ SHIFT(KeyK), - /* L */ SHIFT(KeyL), /* M */ SHIFT(KeyM), - /* N */ SHIFT(KeyN), /* O */ SHIFT(KeyO), - /* P */ SHIFT(KeyP), /* Q */ SHIFT(KeyQ), - /* R */ SHIFT(KeyR), /* S */ SHIFT(KeyS), - /* T */ SHIFT(KeyT), /* U */ SHIFT(KeyU), - /* V */ SHIFT(KeyV), /* W */ SHIFT(KeyW), - /* X */ SHIFT(KeyX), /* Y */ SHIFT(KeyY), - /* Z */ SHIFT(KeyZ), /* [ */ KEYS(KeyLeftSquareBracket), - /* \ */ KEYS(KeyBackSlash), /* ] */ KEYS(KeyRightSquareBracket), - /* ^ */ SHIFT(KeyCaret), /* _ */ SHIFT(Key0), - /* ` */ X, /* a */ KEYS(KeyA), - /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), - /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), - /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), - /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), - /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), - /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), - /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), - /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), - /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), - /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), - /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), - /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), - /* z */ KEYS(KeyZ), /* { */ SHIFT(KeyLeftSquareBracket), - /* | */ SHIFT(KeyAt), /* } */ SHIFT(KeyRightSquareBracket), - /* ~ */ X - }; -#undef KEYS -#undef SHIFT -#undef X +namespace { +const std::unordered_map> sequences = { + {L'\b', {KeyDelete}}, + {L'\n', {KeyReturn}}, {L'\r', {KeyReturn}}, + {L' ', {KeySpace}}, - return table_lookup_sequence_for_character(key_sequences, character); + {L'!', {KeyShift, Key1}}, + {L'"', {KeyShift, Key2}}, + {L'#', {KeyShift, Key3}}, + {L'$', {KeyShift, Key4}}, + {L'%', {KeyShift, Key5}}, + {L'&', {KeyShift, Key6}}, + {L'\'', {KeyShift, Key7}}, + {L'(', {KeyShift, Key8}}, + {L')', {KeyShift, Key9}}, + {L'_', {KeyShift, Key0}}, + + {L'=', {KeyShift, KeyMinus}}, {L'-', {KeyMinus}}, + {L'£', {KeyShift, KeyCaret}}, {L'↑', {KeyCaret}}, + + {L'|', {KeyShift, KeyAt}}, {L'@', {KeyAt}}, + {L'{', {KeyShift, KeyLeftSquareBracket}}, {L'[', {KeyLeftSquareBracket}}, + + {L'*', {KeyShift, KeyColon}}, {L':', {KeyColon}}, + {L'+', {KeyShift, KeySemicolon}}, {L';', {KeySemicolon}}, + {L'}', {KeyShift, KeyRightSquareBracket}}, {L']', {KeyRightSquareBracket}}, + + {L'<', {KeyShift, KeyComma}}, {L',', {KeyComma}}, + {L'>', {KeyShift, KeyFullStop}}, {L'.', {KeyFullStop}}, + {L'?', {KeyShift, KeyForwardSlash}}, {L'/', {KeyForwardSlash}}, + {L'\\', {KeyBackSlash}}, + + {L'0', {Key0}}, {L'1', {Key1}}, {L'2', {Key2}}, {L'3', {Key3}}, {L'4', {Key4}}, + {L'5', {Key5}}, {L'6', {Key6}}, {L'7', {Key7}}, {L'8', {Key8}}, {L'9', {Key9}}, + + {L'A', {KeyShift, KeyA}}, {L'B', {KeyShift, KeyB}}, {L'C', {KeyShift, KeyC}}, + {L'D', {KeyShift, KeyD}}, {L'E', {KeyShift, KeyE}}, {L'F', {KeyShift, KeyF}}, + {L'G', {KeyShift, KeyG}}, {L'H', {KeyShift, KeyH}}, {L'I', {KeyShift, KeyI}}, + {L'J', {KeyShift, KeyJ}}, {L'K', {KeyShift, KeyK}}, {L'L', {KeyShift, KeyL}}, + {L'M', {KeyShift, KeyM}}, {L'N', {KeyShift, KeyN}}, {L'O', {KeyShift, KeyO}}, + {L'P', {KeyShift, KeyP}}, {L'Q', {KeyShift, KeyQ}}, {L'R', {KeyShift, KeyR}}, + {L'S', {KeyShift, KeyS}}, {L'T', {KeyShift, KeyT}}, {L'U', {KeyShift, KeyU}}, + {L'V', {KeyShift, KeyV}}, {L'W', {KeyShift, KeyW}}, {L'X', {KeyShift, KeyX}}, + {L'Y', {KeyShift, KeyY}}, {L'Z', {KeyShift, KeyZ}}, + + {L'a', {KeyA}}, {L'b', {KeyB}}, {L'c', {KeyC}}, + {L'd', {KeyD}}, {L'e', {KeyE}}, {L'f', {KeyF}}, + {L'g', {KeyG}}, {L'h', {KeyH}}, {L'i', {KeyI}}, + {L'j', {KeyJ}}, {L'k', {KeyK}}, {L'l', {KeyL}}, + {L'm', {KeyM}}, {L'n', {KeyN}}, {L'o', {KeyO}}, + {L'p', {KeyP}}, {L'q', {KeyQ}}, {L'r', {KeyR}}, + {L's', {KeyS}}, {L't', {KeyT}}, {L'u', {KeyU}}, + {L'v', {KeyV}}, {L'w', {KeyW}}, {L'x', {KeyX}}, + {L'y', {KeyY}}, {L'z', {KeyZ}}, +}; +} + +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); } bool CharacterMapper::needs_pause_after_key(const uint16_t key) const { diff --git a/Machines/AmstradCPC/Keyboard.hpp b/Machines/AmstradCPC/Keyboard.hpp index 80f1d7183..e468cb201 100644 --- a/Machines/AmstradCPC/Keyboard.hpp +++ b/Machines/AmstradCPC/Keyboard.hpp @@ -37,7 +37,7 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char) const override; + const std::vector *sequence_for_character(wchar_t) const override; bool needs_pause_after_reset_all_keys() const override { return true; } bool needs_pause_after_key(uint16_t) const override; diff --git a/Machines/Apple/AppleII/AppleII.cpp b/Machines/Apple/AppleII/AppleII.cpp index d73222a6c..987168609 100644 --- a/Machines/Apple/AppleII/AppleII.cpp +++ b/Machines/Apple/AppleII/AppleII.cpp @@ -1034,15 +1034,15 @@ public: return is_iie(model); } - Inputs::Keyboard &get_keyboard() final { + Inputs::Keyboard &keyboard() final { return keyboard_; } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { keyboard_.set_string_serialiser(std::make_unique(string, true)); } - bool can_type(char c) const final { + bool can_type(const wchar_t c) const final { // Make an effort to type the entire printable ASCII range. return c >= 32 && c < 127; } diff --git a/Machines/Apple/AppleIIgs/AppleIIgs.cpp b/Machines/Apple/AppleIIgs/AppleIIgs.cpp index 90365fc04..0ec263a87 100644 --- a/Machines/Apple/AppleIIgs/AppleIIgs.cpp +++ b/Machines/Apple/AppleIIgs/AppleIIgs.cpp @@ -912,7 +912,7 @@ public: } // MARK: - Input. - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 8458193bb..56fa24056 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -466,7 +466,7 @@ public: // MARK: Keyboard input. - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Atari/ST/AtariST.cpp b/Machines/Atari/ST/AtariST.cpp index 5f1c91f17..da2f812ef 100644 --- a/Machines/Atari/ST/AtariST.cpp +++ b/Machines/Atari/ST/AtariST.cpp @@ -639,7 +639,7 @@ private: } IntelligentKeyboard::KeyboardMapper keyboard_mapper_; - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Commodore/Plus4/Keyboard.cpp b/Machines/Commodore/Plus4/Keyboard.cpp index 4f41509f0..72318ae25 100644 --- a/Machines/Commodore/Plus4/Keyboard.cpp +++ b/Machines/Commodore/Plus4/Keyboard.cpp @@ -58,79 +58,85 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const { return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(char character) const { - static constexpr KeySequence X = { MachineTypes::MappedKeyboardMachine::KeyNotMapped }; - const auto key = [](Key k) -> KeySequence { - return { k, MachineTypes::MappedKeyboardMachine::KeyEndSequence }; - }; - const auto shift = [](Key k) -> KeySequence { - return { Key::Shift, k, MachineTypes::MappedKeyboardMachine::KeyEndSequence }; - }; +namespace { +const std::unordered_map> sequences = { +}; +} - static KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ key(Key::InsDel), /* HT */ X, - /* LF */ key(Key::Return), /* VT */ X, - /* FF */ X, /* CR */ X, - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ key(Key::Space), /* ! */ shift(Key::k1), - /* " */ shift(Key::k2), /* # */ shift(Key::k3), - /* $ */ shift(Key::k4), /* % */ shift(Key::k5), - /* & */ shift(Key::k6), /* ' */ shift(Key::k7), - /* ( */ shift(Key::k8), /* ) */ shift(Key::k9), - /* * */ key(Key::Asterisk), /* + */ key(Key::Plus), - /* , */ key(Key::Comma), /* - */ key(Key::Minus), - /* . */ key(Key::FullStop), /* / */ key(Key::Slash), - /* 0 */ key(Key::k0), /* 1 */ key(Key::k1), - /* 2 */ key(Key::k2), /* 3 */ key(Key::k3), - /* 4 */ key(Key::k4), /* 5 */ key(Key::k5), - /* 6 */ key(Key::k6), /* 7 */ key(Key::k7), - /* 8 */ key(Key::k8), /* 9 */ key(Key::k9), - /* : */ key(Key::Colon), /* ; */ key(Key::Semicolon), - /* < */ shift(Key::Comma), /* = */ key(Key::Equals), - /* > */ shift(Key::FullStop), /* ? */ shift(Key::Slash), - /* @ */ key(Key::At), /* A */ key(Key::A), - /* B */ key(Key::B), /* C */ key(Key::C), - /* D */ key(Key::D), /* E */ key(Key::E), - /* F */ key(Key::F), /* G */ key(Key::G), - /* H */ key(Key::H), /* I */ key(Key::I), - /* J */ key(Key::J), /* K */ key(Key::K), - /* L */ key(Key::L), /* M */ key(Key::M), - /* N */ key(Key::N), /* O */ key(Key::O), - /* P */ key(Key::P), /* Q */ key(Key::Q), - /* R */ key(Key::R), /* S */ key(Key::S), - /* T */ key(Key::T), /* U */ key(Key::U), - /* V */ key(Key::V), /* W */ key(Key::W), - /* X */ key(Key::X), /* Y */ key(Key::Y), - /* Z */ key(Key::Z), /* [ */ shift(Key::Colon), - /* \ */ X, /* ] */ shift(Key::Semicolon), - /* ^ */ X, /* _ */ X, - /* ` */ X, /* a */ key(Key::A), - /* b */ key(Key::B), /* c */ key(Key::C), - /* d */ key(Key::D), /* e */ key(Key::E), - /* f */ key(Key::F), /* g */ key(Key::G), - /* h */ key(Key::H), /* i */ key(Key::I), - /* j */ key(Key::J), /* k */ key(Key::K), - /* l */ key(Key::L), /* m */ key(Key::M), - /* n */ key(Key::N), /* o */ key(Key::O), - /* p */ key(Key::P), /* q */ key(Key::Q), - /* r */ key(Key::R), /* s */ key(Key::S), - /* t */ key(Key::T), /* u */ key(Key::U), - /* v */ key(Key::V), /* w */ key(Key::W), - /* x */ key(Key::X), /* y */ key(Key::Y), - /* z */ key(Key::Z) - }; - - return table_lookup_sequence_for_character(key_sequences, character); +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); +// static constexpr KeySequence X = { MachineTypes::MappedKeyboardMachine::KeyNotMapped }; +// const auto key = [](Key k) -> KeySequence { +// return { k, MachineTypes::MappedKeyboardMachine::KeyEndSequence }; +// }; +// const auto shift = [](Key k) -> KeySequence { +// return { Key::Shift, k, MachineTypes::MappedKeyboardMachine::KeyEndSequence }; +// }; +// +// static KeySequence key_sequences[] = { +// /* NUL */ X, /* SOH */ X, +// /* STX */ X, /* ETX */ X, +// /* EOT */ X, /* ENQ */ X, +// /* ACK */ X, /* BEL */ X, +// /* BS */ key(Key::InsDel), /* HT */ X, +// /* LF */ key(Key::Return), /* VT */ X, +// /* FF */ X, /* CR */ X, +// /* SO */ X, /* SI */ X, +// /* DLE */ X, /* DC1 */ X, +// /* DC2 */ X, /* DC3 */ X, +// /* DC4 */ X, /* NAK */ X, +// /* SYN */ X, /* ETB */ X, +// /* CAN */ X, /* EM */ X, +// /* SUB */ X, /* ESC */ X, +// /* FS */ X, /* GS */ X, +// /* RS */ X, /* US */ X, +// /* space */ key(Key::Space), /* ! */ shift(Key::k1), +// /* " */ shift(Key::k2), /* # */ shift(Key::k3), +// /* $ */ shift(Key::k4), /* % */ shift(Key::k5), +// /* & */ shift(Key::k6), /* ' */ shift(Key::k7), +// /* ( */ shift(Key::k8), /* ) */ shift(Key::k9), +// /* * */ key(Key::Asterisk), /* + */ key(Key::Plus), +// /* , */ key(Key::Comma), /* - */ key(Key::Minus), +// /* . */ key(Key::FullStop), /* / */ key(Key::Slash), +// /* 0 */ key(Key::k0), /* 1 */ key(Key::k1), +// /* 2 */ key(Key::k2), /* 3 */ key(Key::k3), +// /* 4 */ key(Key::k4), /* 5 */ key(Key::k5), +// /* 6 */ key(Key::k6), /* 7 */ key(Key::k7), +// /* 8 */ key(Key::k8), /* 9 */ key(Key::k9), +// /* : */ key(Key::Colon), /* ; */ key(Key::Semicolon), +// /* < */ shift(Key::Comma), /* = */ key(Key::Equals), +// /* > */ shift(Key::FullStop), /* ? */ shift(Key::Slash), +// /* @ */ key(Key::At), /* A */ key(Key::A), +// /* B */ key(Key::B), /* C */ key(Key::C), +// /* D */ key(Key::D), /* E */ key(Key::E), +// /* F */ key(Key::F), /* G */ key(Key::G), +// /* H */ key(Key::H), /* I */ key(Key::I), +// /* J */ key(Key::J), /* K */ key(Key::K), +// /* L */ key(Key::L), /* M */ key(Key::M), +// /* N */ key(Key::N), /* O */ key(Key::O), +// /* P */ key(Key::P), /* Q */ key(Key::Q), +// /* R */ key(Key::R), /* S */ key(Key::S), +// /* T */ key(Key::T), /* U */ key(Key::U), +// /* V */ key(Key::V), /* W */ key(Key::W), +// /* X */ key(Key::X), /* Y */ key(Key::Y), +// /* Z */ key(Key::Z), /* [ */ shift(Key::Colon), +// /* \ */ X, /* ] */ shift(Key::Semicolon), +// /* ^ */ X, /* _ */ X, +// /* ` */ X, /* a */ key(Key::A), +// /* b */ key(Key::B), /* c */ key(Key::C), +// /* d */ key(Key::D), /* e */ key(Key::E), +// /* f */ key(Key::F), /* g */ key(Key::G), +// /* h */ key(Key::H), /* i */ key(Key::I), +// /* j */ key(Key::J), /* k */ key(Key::K), +// /* l */ key(Key::L), /* m */ key(Key::M), +// /* n */ key(Key::N), /* o */ key(Key::O), +// /* p */ key(Key::P), /* q */ key(Key::Q), +// /* r */ key(Key::R), /* s */ key(Key::S), +// /* t */ key(Key::T), /* u */ key(Key::U), +// /* v */ key(Key::V), /* w */ key(Key::W), +// /* x */ key(Key::X), /* y */ key(Key::Y), +// /* z */ key(Key::Z) +// }; +// +// return table_lookup_sequence_for_character(key_sequences, character); } diff --git a/Machines/Commodore/Plus4/Keyboard.hpp b/Machines/Commodore/Plus4/Keyboard.hpp index 65659cd37..ac2b55466 100644 --- a/Machines/Commodore/Plus4/Keyboard.hpp +++ b/Machines/Commodore/Plus4/Keyboard.hpp @@ -76,7 +76,7 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char character) const final; + const std::vector *sequence_for_character(wchar_t) const final; bool needs_pause_after_reset_all_keys() const final { return false; } bool needs_pause_after_key(uint16_t key) const { return key != Key::Shift && key != Key::Commodore && key != Key::Control; diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index a2edb6f07..21a63e730 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -231,7 +231,7 @@ public: insert_media(target.media); if(!target.loading_command.empty()) { // Prefix a space as a delaying technique. - type_string(std::string(" ") + target.loading_command); + type_string(L" " + target.loading_command); } } @@ -664,16 +664,16 @@ private: } // MARK: - MappedKeyboardMachine. - MappedKeyboardMachine::KeyboardMapper *get_keyboard_mapper() override { + MappedKeyboardMachine::KeyboardMapper *keyboard_mapper() override { static Plus4::KeyboardMapper keyboard_mapper_; return &keyboard_mapper_; } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(const char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } diff --git a/Machines/Commodore/Vic-20/Keyboard.cpp b/Machines/Commodore/Vic-20/Keyboard.cpp index 62493d0e1..2856b35af 100644 --- a/Machines/Commodore/Vic-20/Keyboard.cpp +++ b/Machines/Commodore/Vic-20/Keyboard.cpp @@ -79,77 +79,52 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const { return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(char character) const { -#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define SHIFT(...) {KeyLShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ KEYS(KeyDelete), /* HT */ X, - /* LF */ KEYS(KeyReturn), /* VT */ X, - /* FF */ X, /* CR */ X, - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), - /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), - /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), - /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), - /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), - /* * */ KEYS(KeyAsterisk), /* + */ KEYS(KeyPlus), - /* , */ KEYS(KeyComma), /* - */ KEYS(KeyDash), - /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeySlash), - /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), - /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), - /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), - /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), - /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), - /* : */ KEYS(KeyColon), /* ; */ KEYS(KeySemicolon), - /* < */ SHIFT(KeyComma), /* = */ KEYS(KeyEquals), - /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeySlash), - /* @ */ KEYS(KeyAt), /* A */ KEYS(KeyA), - /* B */ KEYS(KeyB), /* C */ KEYS(KeyC), - /* D */ KEYS(KeyD), /* E */ KEYS(KeyE), - /* F */ KEYS(KeyF), /* G */ KEYS(KeyG), - /* H */ KEYS(KeyH), /* I */ KEYS(KeyI), - /* J */ KEYS(KeyJ), /* K */ KEYS(KeyK), - /* L */ KEYS(KeyL), /* M */ KEYS(KeyM), - /* N */ KEYS(KeyN), /* O */ KEYS(KeyO), - /* P */ KEYS(KeyP), /* Q */ KEYS(KeyQ), - /* R */ KEYS(KeyR), /* S */ KEYS(KeyS), - /* T */ KEYS(KeyT), /* U */ KEYS(KeyU), - /* V */ KEYS(KeyV), /* W */ KEYS(KeyW), - /* X */ KEYS(KeyX), /* Y */ KEYS(KeyY), - /* Z */ KEYS(KeyZ), /* [ */ SHIFT(KeyColon), - /* \ */ X, /* ] */ SHIFT(KeySemicolon), - /* ^ */ X, /* _ */ X, - /* ` */ X, /* a */ KEYS(KeyA), - /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), - /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), - /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), - /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), - /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), - /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), - /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), - /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), - /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), - /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), - /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), - /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), - /* z */ KEYS(KeyZ) - }; -#undef KEYS -#undef SHIFT -#undef X +namespace { +const std::unordered_map> sequences = { + {L'\b', {KeyDelete}}, + {L'\n', {KeyReturn}}, {L'\r', {KeyReturn}}, + {L' ', {KeySpace}}, - return table_lookup_sequence_for_character(key_sequences, character); + {L'!', {KeyLShift, Key1}}, + {L'"', {KeyLShift, Key2}}, + {L'#', {KeyLShift, Key3}}, + {L'$', {KeyLShift, Key4}}, + {L'%', {KeyLShift, Key5}}, + {L'&', {KeyLShift, Key6}}, + {L'\'', {KeyLShift, Key7}}, + {L'(', {KeyLShift, Key8}}, + {L')', {KeyLShift, Key9}}, + + {L'0', {Key0}}, {L'1', {Key1}}, {L'2', {Key2}}, {L'3', {Key3}}, {L'4', {Key4}}, + {L'5', {Key5}}, {L'6', {Key6}}, {L'7', {Key7}}, {L'8', {Key8}}, {L'9', {Key9}}, + {L'+', {KeyPlus}}, + {L'-', {KeyDash}}, + {L'£', {KeyGBP}}, + + {L'@', {KeyAt}}, + {L'*', {KeyAsterisk}}, + {L'↑', {KeyUpArrow}}, + + {L'[', {KeyLShift, KeyColon}}, {L':', {KeyColon}}, + {L']', {KeyLShift, KeySemicolon}}, {L';', {KeySemicolon}}, + {L'=', {KeyEquals}}, + + {L'<', {KeyLShift, KeyComma}}, {L',', {KeyComma}}, + {L'>', {KeyLShift, KeyFullStop}}, {L'.', {KeyFullStop}}, + {L'?', {KeyLShift, KeySlash}}, {L'/', {KeySlash}}, + + {L'a', {KeyA}}, {L'b', {KeyB}}, {L'c', {KeyC}}, + {L'd', {KeyD}}, {L'e', {KeyE}}, {L'f', {KeyF}}, + {L'g', {KeyG}}, {L'h', {KeyH}}, {L'i', {KeyI}}, + {L'j', {KeyJ}}, {L'k', {KeyK}}, {L'l', {KeyL}}, + {L'm', {KeyM}}, {L'n', {KeyN}}, {L'o', {KeyO}}, + {L'p', {KeyP}}, {L'q', {KeyQ}}, {L'r', {KeyR}}, + {L's', {KeyS}}, {L't', {KeyT}}, {L'u', {KeyU}}, + {L'v', {KeyV}}, {L'w', {KeyW}}, {L'x', {KeyX}}, + {L'y', {KeyY}}, {L'z', {KeyZ}}, +}; +} + +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); } diff --git a/Machines/Commodore/Vic-20/Keyboard.hpp b/Machines/Commodore/Vic-20/Keyboard.hpp index 9530448e8..91cd58e56 100644 --- a/Machines/Commodore/Vic-20/Keyboard.hpp +++ b/Machines/Commodore/Vic-20/Keyboard.hpp @@ -48,11 +48,11 @@ enum Key: uint16_t { }; struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper { - uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final; + uint16_t mapped_key_for_key(Inputs::Keyboard::Key) const final; }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char character) const final; + const std::vector *sequence_for_character(wchar_t) const final; }; } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index ae21eee3e..ea84a324a 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -677,11 +677,11 @@ public: m6502_.template set(keyboard_via_.get_interrupt_line()); } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(const char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } @@ -689,7 +689,7 @@ public: keyboard_via_.set_control_line_input(!tape.input()); } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Enterprise/Enterprise.cpp b/Machines/Enterprise/Enterprise.cpp index 021a3a0b5..3c7a42567 100644 --- a/Machines/Enterprise/Enterprise.cpp +++ b/Machines/Enterprise/Enterprise.cpp @@ -760,7 +760,7 @@ private: // MARK: - KeyboardMachine Enterprise::KeyboardMapper keyboard_mapper_; - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } @@ -779,7 +779,7 @@ private: } // MARK: - Utility::TypeRecipient - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); if(z80_.get_is_resetting()) { @@ -791,7 +791,7 @@ private: } } - bool can_type(const char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } diff --git a/Machines/Enterprise/Keyboard.cpp b/Machines/Enterprise/Keyboard.cpp index 88fd07798..02c4cedd9 100644 --- a/Machines/Enterprise/Keyboard.cpp +++ b/Machines/Enterprise/Keyboard.cpp @@ -73,79 +73,75 @@ uint16_t KeyboardMapper::mapped_key_for_key(const Inputs::Keyboard::Key key) con return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(const char character) const { -#define KEYS(x) {uint16_t(x), MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define SHIFT(x) {uint16_t(Key::LeftShift), uint16_t(x), MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define _ {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static KeySequence key_sequences[] = { - /* NUL */ _, /* SOH */ _, - /* STX */ _, /* ETX */ _, - /* EOT */ _, /* ENQ */ _, - /* ACK */ _, /* BEL */ _, - /* BS */ KEYS(Key::Erase), /* HT */ KEYS(Key::Tab), - /* LF */ KEYS(Key::Enter), /* VT */ _, - /* FF */ _, /* CR */ KEYS(Key::Enter), - /* SO */ _, /* SI */ _, - /* DLE */ _, /* DC1 */ _, - /* DC2 */ _, /* DC3 */ _, - /* DC4 */ _, /* NAK */ _, - /* SYN */ _, /* ETB */ _, - /* CAN */ _, /* EM */ _, - /* SUB */ _, /* ESC */ KEYS(Key::Escape), - /* FS */ _, /* GS */ _, - /* RS */ _, /* US */ _, - /* space */ KEYS(Key::Space), /* ! */ SHIFT(Key::k1), - /* " */ SHIFT(Key::k2), /* # */ _, - /* $ */ SHIFT(Key::k4), /* % */ SHIFT(Key::k5), - /* & */ SHIFT(Key::k6), /* ' */ SHIFT(Key::k7), - /* ( */ SHIFT(Key::k8), /* ) */ SHIFT(Key::k9), - /* * */ SHIFT(Key::Colon), /* + */ SHIFT(Key::Semicolon), - /* , */ KEYS(Key::Comma), /* - */ KEYS(Key::Hyphen), - /* . */ KEYS(Key::FullStop), /* / */ KEYS(Key::ForwardSlash), - /* 0 */ KEYS(Key::k0), /* 1 */ KEYS(Key::k1), - /* 2 */ KEYS(Key::k2), /* 3 */ KEYS(Key::k3), - /* 4 */ KEYS(Key::k4), /* 5 */ KEYS(Key::k5), - /* 6 */ KEYS(Key::k6), /* 7 */ KEYS(Key::k7), - /* 8 */ KEYS(Key::k8), /* 9 */ KEYS(Key::k9), - /* : */ KEYS(Key::Colon), /* ; */ KEYS(Key::Semicolon), - /* < */ SHIFT(Key::Comma), /* = */ SHIFT(Key::Hyphen), - /* > */ SHIFT(Key::FullStop), /* ? */ SHIFT(Key::ForwardSlash), - /* @ */ KEYS(Key::At), /* A */ SHIFT(Key::A), - /* B */ SHIFT(Key::B), /* C */ SHIFT(Key::C), - /* D */ SHIFT(Key::D), /* E */ SHIFT(Key::E), - /* F */ SHIFT(Key::F), /* G */ SHIFT(Key::G), - /* H */ SHIFT(Key::H), /* I */ SHIFT(Key::I), - /* J */ SHIFT(Key::J), /* K */ SHIFT(Key::K), - /* L */ SHIFT(Key::L), /* M */ SHIFT(Key::M), - /* N */ SHIFT(Key::N), /* O */ SHIFT(Key::O), - /* P */ SHIFT(Key::P), /* Q */ SHIFT(Key::Q), - /* R */ SHIFT(Key::R), /* S */ SHIFT(Key::S), - /* T */ SHIFT(Key::T), /* U */ SHIFT(Key::U), - /* V */ SHIFT(Key::V), /* W */ SHIFT(Key::W), - /* X */ SHIFT(Key::X), /* Y */ SHIFT(Key::Y), - /* Z */ SHIFT(Key::Z), /* [ */ KEYS(Key::OpenSquareBracket), - /* \ */ KEYS(Key::Backslash), /* ] */ KEYS(Key::CloseSquareBracket), - /* ^ */ SHIFT(Key::Caret), /* _ */ SHIFT(Key::k0), - /* ` */ SHIFT(Key::At), /* a */ KEYS(Key::A), - /* b */ KEYS(Key::B), /* c */ KEYS(Key::C), - /* d */ KEYS(Key::D), /* e */ KEYS(Key::E), - /* f */ KEYS(Key::F), /* g */ KEYS(Key::G), - /* h */ KEYS(Key::H), /* i */ KEYS(Key::I), - /* j */ KEYS(Key::J), /* k */ KEYS(Key::K), - /* l */ KEYS(Key::L), /* m */ KEYS(Key::M), - /* n */ KEYS(Key::N), /* o */ KEYS(Key::O), - /* p */ KEYS(Key::P), /* q */ KEYS(Key::Q), - /* r */ KEYS(Key::R), /* s */ KEYS(Key::S), - /* t */ KEYS(Key::T), /* u */ KEYS(Key::U), - /* v */ KEYS(Key::V), /* w */ KEYS(Key::W), - /* x */ KEYS(Key::X), /* y */ KEYS(Key::Y), - /* z */ KEYS(Key::Z), /* { */ SHIFT(Key::OpenSquareBracket), - /* | */ SHIFT(Key::Backslash), /* } */ SHIFT(Key::CloseSquareBracket), - /* ~ */ SHIFT(Key::Caret) - }; -#undef _ -#undef SHIFT -#undef KEYS +namespace { +const std::unordered_map> sequences = { + {L'\b', {Key::Erase}}, {L'\t', {Key::Tab}}, + {L'\n', {Key::Enter}}, {L'\r', {Key::Enter}}, + {L'\e', {Key::Escape}}, + {L' ', {Key::Space}}, - return table_lookup_sequence_for_character(key_sequences, character); + {L'!', {Key::LeftShift, Key::k1}}, + {L'"', {Key::LeftShift, Key::k2}}, + {L'£', {Key::LeftShift, Key::k3}}, + {L'$', {Key::LeftShift, Key::k4}}, + {L'%', {Key::LeftShift, Key::k5}}, + {L'&', {Key::LeftShift, Key::k6}}, + {L'\'', {Key::LeftShift, Key::k7}}, + {L'(', {Key::LeftShift, Key::k8}}, + {L')', {Key::LeftShift, Key::k9}}, + {L'_', {Key::LeftShift, Key::k0}}, + + {L'=', {Key::LeftShift, Key::Hyphen}}, + {L'-', {Key::Hyphen}}, + {L'~', {Key::LeftShift, Key::Caret}}, + {L'^', {Key::Caret}}, + + {L'`', {Key::LeftShift, Key::At}}, + {L'@', {Key::At}}, + {L'{', {Key::LeftShift, Key::OpenSquareBracket}}, + {L'[', {Key::OpenSquareBracket}}, + + {L'+', {Key::LeftShift, Key::Semicolon}}, + {L';', {Key::Semicolon}}, + {L'*', {Key::LeftShift, Key::Colon}}, + {L':', {Key::Colon}}, + {L'}', {Key::LeftShift, Key::CloseSquareBracket}}, + {L']', {Key::CloseSquareBracket}}, + + {L'|', {Key::LeftShift, Key::Backslash}}, + {L'\\', {Key::Backslash}}, + {L'<', {Key::LeftShift, Key::Comma}}, + {L',', {Key::Comma}}, + {L'>', {Key::LeftShift, Key::FullStop}}, + {L'.', {Key::FullStop}}, + {L'?', {Key::LeftShift, Key::ForwardSlash}}, + {L'/', {Key::ForwardSlash}}, + + {L'0', {Key::k0}}, {L'1', {Key::k1}}, {L'2', {Key::k2}}, {L'3', {Key::k3}}, {L'4', {Key::k4}}, + {L'5', {Key::k5}}, {L'6', {Key::k6}}, {L'7', {Key::k7}}, {L'8', {Key::k8}}, {L'9', {Key::k9}}, + + {L'A', {Key::LeftShift, Key::A}}, {L'B', {Key::LeftShift, Key::B}}, {L'C', {Key::LeftShift, Key::C}}, + {L'D', {Key::LeftShift, Key::D}}, {L'E', {Key::LeftShift, Key::E}}, {L'F', {Key::LeftShift, Key::F}}, + {L'G', {Key::LeftShift, Key::G}}, {L'H', {Key::LeftShift, Key::H}}, {L'I', {Key::LeftShift, Key::I}}, + {L'J', {Key::LeftShift, Key::J}}, {L'K', {Key::LeftShift, Key::K}}, {L'L', {Key::LeftShift, Key::L}}, + {L'M', {Key::LeftShift, Key::M}}, {L'N', {Key::LeftShift, Key::N}}, {L'O', {Key::LeftShift, Key::O}}, + {L'P', {Key::LeftShift, Key::P}}, {L'Q', {Key::LeftShift, Key::Q}}, {L'R', {Key::LeftShift, Key::R}}, + {L'S', {Key::LeftShift, Key::S}}, {L'T', {Key::LeftShift, Key::T}}, {L'U', {Key::LeftShift, Key::U}}, + {L'V', {Key::LeftShift, Key::V}}, {L'W', {Key::LeftShift, Key::W}}, {L'X', {Key::LeftShift, Key::X}}, + {L'Y', {Key::LeftShift, Key::Y}}, {L'Z', {Key::LeftShift, Key::Z}}, + + {L'a', {Key::A}}, {L'b', {Key::B}}, {L'c', {Key::C}}, + {L'd', {Key::D}}, {L'e', {Key::E}}, {L'f', {Key::F}}, + {L'g', {Key::G}}, {L'h', {Key::H}}, {L'i', {Key::I}}, + {L'j', {Key::J}}, {L'k', {Key::K}}, {L'l', {Key::L}}, + {L'm', {Key::M}}, {L'n', {Key::N}}, {L'o', {Key::O}}, + {L'p', {Key::P}}, {L'q', {Key::Q}}, {L'r', {Key::R}}, + {L's', {Key::S}}, {L't', {Key::T}}, {L'u', {Key::U}}, + {L'v', {Key::V}}, {L'w', {Key::W}}, {L'x', {Key::X}}, + {L'y', {Key::Y}}, {L'z', {Key::Z}}, +}; +} + +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); } diff --git a/Machines/Enterprise/Keyboard.hpp b/Machines/Enterprise/Keyboard.hpp index 004107c21..b5ae873e5 100644 --- a/Machines/Enterprise/Keyboard.hpp +++ b/Machines/Enterprise/Keyboard.hpp @@ -13,7 +13,8 @@ namespace Enterprise { -enum class Key: uint16_t { +namespace Key { +enum Key: uint16_t { N = 0x0000 | 0x01, Backslash = 0x0000 | 0x02, B = 0x0000 | 0x04, C = 0x0000 | 0x08, V = 0x0000 | 0x10, X = 0x0000 | 0x20, Z = 0x0000 | 0x40, LeftShift = 0x0000 | 0x80, @@ -47,13 +48,14 @@ enum class Key: uint16_t { P = 0x0900 | 0x10, OpenSquareBracket = 0x0900 | 0x20 }; +} struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper { uint16_t mapped_key_for_key(Inputs::Keyboard::Key) const final; }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char) const override; + const std::vector *sequence_for_character(wchar_t) const override; }; } diff --git a/Machines/KeyboardMachine.cpp b/Machines/KeyboardMachine.cpp index 05939d3f9..80453c5ef 100644 --- a/Machines/KeyboardMachine.cpp +++ b/Machines/KeyboardMachine.cpp @@ -19,7 +19,7 @@ bool MappedKeyboardMachine::keyboard_did_change_key( const Inputs::Keyboard::Key key, const bool is_pressed ) { - const uint16_t mapped_key = get_keyboard_mapper()->mapped_key_for_key(key); + const uint16_t mapped_key = keyboard_mapper()->mapped_key_for_key(key); if(mapped_key == KeyNotMapped) return false; set_key_state(mapped_key, is_pressed); return true; @@ -30,13 +30,13 @@ void MappedKeyboardMachine::reset_all_keys(Inputs::Keyboard &) { clear_all_keys(); } -Inputs::Keyboard &MappedKeyboardMachine::get_keyboard() { +Inputs::Keyboard &MappedKeyboardMachine::keyboard() { return keyboard_; } -void KeyboardMachine::type_string(const std::string &) { +void KeyboardMachine::type_string(const std::wstring &) { } -MappedKeyboardMachine::KeyboardMapper *MappedKeyboardMachine::get_keyboard_mapper() { +MappedKeyboardMachine::KeyboardMapper *MappedKeyboardMachine::keyboard_mapper() { return nullptr; } diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 606e6c53f..2c14d2670 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -451,7 +451,7 @@ public: return true; } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { std::transform( string.begin(), string.end(), @@ -460,7 +460,7 @@ public: ); } - bool can_type(char c) const final { + bool can_type(const wchar_t c) const final { // Make an effort to type the entire printable ASCII range. return c >= 32 && c < 127; } @@ -807,7 +807,7 @@ public: if(is_pressed) key_states_[line] &= ~mask; else key_states_[line] |= mask; } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index a40da904f..69ee2394d 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -404,7 +404,7 @@ public: } // MARK: - Keyboard (i.e. the pause and reset buttons). - Inputs::Keyboard &get_keyboard() final { + Inputs::Keyboard &keyboard() final { return keyboard_; } diff --git a/Machines/Oric/Keyboard.cpp b/Machines/Oric/Keyboard.cpp index 3f8478272..b6f9cc3d5 100644 --- a/Machines/Oric/Keyboard.cpp +++ b/Machines/Oric/Keyboard.cpp @@ -54,78 +54,63 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const { return MachineTypes::MappedKeyboardMachine::KeyNotMapped; } -const uint16_t *CharacterMapper::sequence_for_character(const char character) const { -#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define SHIFT(...) {KeyLeftShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} -#define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static constexpr KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ KEYS(KeyDelete), /* HT */ X, - /* LF */ KEYS(KeyReturn), /* VT */ X, - /* FF */ X, /* CR */ X, - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), - /* " */ SHIFT(KeyQuote), /* # */ SHIFT(Key3), - /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), - /* & */ SHIFT(Key7), /* ' */ KEYS(KeyQuote), - /* ( */ SHIFT(Key9), /* ) */ SHIFT(Key0), - /* * */ SHIFT(Key8), /* + */ SHIFT(KeyEquals), - /* , */ KEYS(KeyComma), /* - */ KEYS(KeyMinus), - /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeyForwardSlash), - /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), - /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), - /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), - /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), - /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), - /* : */ SHIFT(KeySemiColon), /* ; */ KEYS(KeySemiColon), - /* < */ SHIFT(KeyComma), /* = */ KEYS(KeyEquals), - /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeyForwardSlash), - /* @ */ SHIFT(Key2), /* A */ SHIFT(KeyA), - /* B */ SHIFT(KeyB), /* C */ SHIFT(KeyC), - /* D */ SHIFT(KeyD), /* E */ SHIFT(KeyE), - /* F */ SHIFT(KeyF), /* G */ SHIFT(KeyG), - /* H */ SHIFT(KeyH), /* I */ SHIFT(KeyI), - /* J */ SHIFT(KeyJ), /* K */ SHIFT(KeyK), - /* L */ SHIFT(KeyL), /* M */ SHIFT(KeyM), - /* N */ SHIFT(KeyN), /* O */ SHIFT(KeyO), - /* P */ SHIFT(KeyP), /* Q */ SHIFT(KeyQ), - /* R */ SHIFT(KeyR), /* S */ SHIFT(KeyS), - /* T */ SHIFT(KeyT), /* U */ SHIFT(KeyU), - /* V */ SHIFT(KeyV), /* W */ SHIFT(KeyW), - /* X */ SHIFT(KeyX), /* Y */ SHIFT(KeyY), - /* Z */ SHIFT(KeyZ), /* [ */ KEYS(KeyOpenSquare), - /* \ */ KEYS(KeyBackSlash), /* ] */ KEYS(KeyCloseSquare), - /* ^ */ SHIFT(Key6), /* _ */ X, - /* ` */ X, /* a */ KEYS(KeyA), - /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), - /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), - /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), - /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), - /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), - /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), - /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), - /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), - /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), - /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), - /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), - /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), - /* z */ KEYS(KeyZ), /* { */ SHIFT(KeyOpenSquare), - /* | */ SHIFT(KeyBackSlash), /* } */ SHIFT(KeyCloseSquare), - }; -#undef KEYS -#undef SHIFT -#undef X +namespace { +const std::unordered_map> sequences = { + {L'\e', {KeyEscape}}, + {L'\b', {KeyDelete}}, + {L'\n', {KeyReturn}}, {L'\r', {KeyReturn}}, + {L' ', {KeySpace}}, - return table_lookup_sequence_for_character(key_sequences, character); + {L'!', {KeyLeftShift, Key1}}, + {L'@', {KeyLeftShift, Key2}}, + {L'#', {KeyLeftShift, Key3}}, + {L'$', {KeyLeftShift, Key4}}, + {L'%', {KeyLeftShift, Key5}}, + {L'^', {KeyLeftShift, Key6}}, + {L'&', {KeyLeftShift, Key7}}, + {L'*', {KeyLeftShift, Key8}}, + {L'(', {KeyLeftShift, Key9}}, + {L')', {KeyLeftShift, Key0}}, + + {L'£', {KeyLeftShift, KeyMinus}}, {L'-', {KeyMinus}}, + {L'+', {KeyLeftShift, KeyEquals}}, {L'=', {KeyEquals}}, + {L'|', {KeyLeftShift, KeyBackSlash}}, {L'\\', {KeyBackSlash}}, + + {L'{', {KeyLeftShift, KeyOpenSquare}}, {L'[', {KeyOpenSquare}}, + {L'}', {KeyLeftShift, KeyCloseSquare}}, {L']', {KeyCloseSquare}}, + + {L':', {KeyLeftShift, KeySemiColon}}, {L';', {KeySemiColon}}, + {L'"', {KeyLeftShift, KeyQuote}}, {L'\'', {KeyQuote}}, + + {L'<', {KeyLeftShift, KeyComma}}, {L',', {KeyComma}}, + {L'>', {KeyLeftShift, KeyFullStop}}, {L'.', {KeyFullStop}}, + {L'?', {KeyLeftShift, KeyForwardSlash}}, {L'/', {KeyForwardSlash}}, + + {L'0', {Key0}}, {L'1', {Key1}}, {L'2', {Key2}}, {L'3', {Key3}}, {L'4', {Key4}}, + {L'5', {Key5}}, {L'6', {Key6}}, {L'7', {Key7}}, {L'8', {Key8}}, {L'9', {Key9}}, + + {L'A', {KeyLeftShift, KeyA}}, {L'B', {KeyLeftShift, KeyB}}, {L'C', {KeyLeftShift, KeyC}}, + {L'D', {KeyLeftShift, KeyD}}, {L'E', {KeyLeftShift, KeyE}}, {L'F', {KeyLeftShift, KeyF}}, + {L'G', {KeyLeftShift, KeyG}}, {L'H', {KeyLeftShift, KeyH}}, {L'I', {KeyLeftShift, KeyI}}, + {L'J', {KeyLeftShift, KeyJ}}, {L'K', {KeyLeftShift, KeyK}}, {L'L', {KeyLeftShift, KeyL}}, + {L'M', {KeyLeftShift, KeyM}}, {L'N', {KeyLeftShift, KeyN}}, {L'O', {KeyLeftShift, KeyO}}, + {L'P', {KeyLeftShift, KeyP}}, {L'Q', {KeyLeftShift, KeyQ}}, {L'R', {KeyLeftShift, KeyR}}, + {L'S', {KeyLeftShift, KeyS}}, {L'T', {KeyLeftShift, KeyT}}, {L'U', {KeyLeftShift, KeyU}}, + {L'V', {KeyLeftShift, KeyV}}, {L'W', {KeyLeftShift, KeyW}}, {L'X', {KeyLeftShift, KeyX}}, + {L'Y', {KeyLeftShift, KeyY}}, {L'Z', {KeyLeftShift, KeyZ}}, + + {L'a', {KeyA}}, {L'b', {KeyB}}, {L'c', {KeyC}}, + {L'd', {KeyD}}, {L'e', {KeyE}}, {L'f', {KeyF}}, + {L'g', {KeyG}}, {L'h', {KeyH}}, {L'i', {KeyI}}, + {L'j', {KeyJ}}, {L'k', {KeyK}}, {L'l', {KeyL}}, + {L'm', {KeyM}}, {L'n', {KeyN}}, {L'o', {KeyO}}, + {L'p', {KeyP}}, {L'q', {KeyQ}}, {L'r', {KeyR}}, + {L's', {KeyS}}, {L't', {KeyT}}, {L'u', {KeyU}}, + {L'v', {KeyV}}, {L'w', {KeyW}}, {L'x', {KeyX}}, + {L'y', {KeyY}}, {L'z', {KeyZ}}, +}; +} + +const std::vector *CharacterMapper::sequence_for_character(const wchar_t character) const { + return lookup_sequence(sequences, character); } diff --git a/Machines/Oric/Keyboard.hpp b/Machines/Oric/Keyboard.hpp index bc16d1cdf..85ec579b1 100644 --- a/Machines/Oric/Keyboard.hpp +++ b/Machines/Oric/Keyboard.hpp @@ -40,7 +40,7 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(char character) const final; + const std::vector *sequence_for_character(wchar_t) const final; }; } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index a383fe5a4..cfbdd4364 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -554,7 +554,7 @@ public: // read rather than the decode and write: (i) nothing is lost while BASIC is parsing; and // (ii) keyboard input is much more rapid. if(string_serialiser_ && address == 0x02df && operation == CPU::MOS6502::BusOperation::Read) { - *value = string_serialiser_->head() | 0x80; + *value = uint8_t(string_serialiser_->head()) | 0x80; if(!string_serialiser_->advance()) string_serialiser_.reset(); } @@ -650,11 +650,11 @@ public: } // for Utility::TypeRecipient::Delegate - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { string_serialiser_ = std::make_unique(string, true); } - bool can_type(char c) const final { + bool can_type(const wchar_t c) const final { // Make an effort to type the entire printable ASCII range. return c >= 32 && c < 127; } @@ -683,7 +683,7 @@ public: set_interrupt_line(); } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index fece61d6a..792bbe6ff 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -1021,7 +1021,7 @@ public: } // MARK: - MappedKeyboardMachine. - MappedKeyboardMachine::KeyboardMapper *get_keyboard_mapper() final { + MappedKeyboardMachine::KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Sinclair/ZX8081/ZX8081.cpp b/Machines/Sinclair/ZX8081/ZX8081.cpp index f3f57ca18..77e51fff3 100644 --- a/Machines/Sinclair/ZX8081/ZX8081.cpp +++ b/Machines/Sinclair/ZX8081/ZX8081.cpp @@ -251,7 +251,9 @@ public: } if(should_autorun_ && address == finished_load_address_) { - type_string(is_zx81 ? "r \n" : "r\n "); // Spaces here are not especially scientific; they merely ensure sufficient pauses for both the ZX80 and 81, empirically. + // Spaces here are not especially scientific; they merely ensure + // sufficient pauses for both the ZX80 and 81, empirically. + type_string(is_zx81 ? L"r \n" : L"r\n "); should_autorun_ = false; } @@ -369,15 +371,15 @@ public: } // MARK: - Typer timing - HalfCycles get_typer_delay(const std::string &) const final { + HalfCycles typer_delay(const std::wstring &) const final { return z80_.get_is_resetting() ? Cycles(7'000'000) : Cycles(0); } - HalfCycles get_typer_frequency() const final { + HalfCycles typer_frequency() const final { return Cycles(159'961); } - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index 00a8b35b7..fed4fb2d4 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -649,11 +649,11 @@ private: if(typer_) typer_->run_for(duration); } - void type_string(const std::string &string) override { + void type_string(const std::wstring &string) override { Utility::TypeRecipient::add_typer(string); } - bool can_type(char c) const override { + bool can_type(const wchar_t c) const override { return Utility::TypeRecipient::can_type(c); } diff --git a/Machines/Thomson/MO/Keyboard.hpp b/Machines/Thomson/MO/Keyboard.hpp index 95a190da9..ab4f7e16c 100644 --- a/Machines/Thomson/MO/Keyboard.hpp +++ b/Machines/Thomson/MO/Keyboard.hpp @@ -118,80 +118,86 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe }; struct CharacterMapper: public ::Utility::CharacterMapper { - const uint16_t *sequence_for_character(const char character) const final { - #define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} - #define SHIFT(...) {KeyShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} - #define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} - static constexpr KeySequence key_sequences[] = { - /* NUL */ X, /* SOH */ X, - /* STX */ X, /* ETX */ X, - /* EOT */ X, /* ENQ */ X, - /* ACK */ X, /* BEL */ X, - /* BS */ X, /* HT */ X, - /* LF */ KEYS(KeyEnter), /* VT */ X, - /* FF */ X, /* CR */ X, - /* SO */ X, /* SI */ X, - /* DLE */ X, /* DC1 */ X, - /* DC2 */ X, /* DC3 */ X, - /* DC4 */ X, /* NAK */ X, - /* SYN */ X, /* ETB */ X, - /* CAN */ X, /* EM */ X, - /* SUB */ X, /* ESC */ X, - /* FS */ X, /* GS */ X, - /* RS */ X, /* US */ X, - /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), - /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), - /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), - /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), - /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), - /* * */ KEYS(KeyAsterisk), /* + */ KEYS(KeyPlus), - /* , */ KEYS(KeyComma), /* - */ KEYS(KeyMinus), - /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeyForwardSlash), - /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), - /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), - /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), - /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), - /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), - /* : */ SHIFT(KeyAsterisk), /* ; */ SHIFT(KeyPlus), - /* < */ SHIFT(KeyComma), /* = */ SHIFT(KeyMinus), - /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeyForwardSlash), - /* @ */ KEYS(KeyAt), /* A */ SHIFT(KeyA), - /* B */ SHIFT(KeyB), /* C */ SHIFT(KeyC), - /* D */ SHIFT(KeyD), /* E */ SHIFT(KeyE), - /* F */ SHIFT(KeyF), /* G */ SHIFT(KeyG), - /* H */ SHIFT(KeyH), /* I */ SHIFT(KeyI), - /* J */ SHIFT(KeyJ), /* K */ SHIFT(KeyK), - /* L */ SHIFT(KeyL), /* M */ SHIFT(KeyM), - /* N */ SHIFT(KeyN), /* O */ SHIFT(KeyO), - /* P */ SHIFT(KeyP), /* Q */ SHIFT(KeyQ), - /* R */ SHIFT(KeyR), /* S */ SHIFT(KeyS), - /* T */ SHIFT(KeyT), /* U */ SHIFT(KeyU), - /* V */ SHIFT(KeyV), /* W */ SHIFT(KeyW), - /* X */ SHIFT(KeyX), /* Y */ SHIFT(KeyY), - /* Z */ SHIFT(KeyZ), /* [ */ X, - /* \ */ X, /* ] */ X, - /* ^ */ SHIFT(KeyAt), /* _ */ X, - /* ` */ X, /* a */ KEYS(KeyA), - /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), - /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), - /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), - /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), - /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), - /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), - /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), - /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), - /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), - /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), - /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), - /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), - /* z */ KEYS(KeyZ) - }; - #undef KEYS - #undef SHIFT - #undef X - - return table_lookup_sequence_for_character(key_sequences, character); + const std::vector *sequence_for_character(const wchar_t character) const final { + return lookup_sequence(sequences, character); } +private: + static inline std::unordered_map> sequences = { + }; + +// #define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} +// #define SHIFT(...) {KeyShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} +// #define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} +// static constexpr KeySequence key_sequences[] = { +// /* NUL */ X, /* SOH */ X, +// /* STX */ X, /* ETX */ X, +// /* EOT */ X, /* ENQ */ X, +// /* ACK */ X, /* BEL */ X, +// /* BS */ X, /* HT */ X, +// /* LF */ KEYS(KeyEnter), /* VT */ X, +// /* FF */ X, /* CR */ X, +// /* SO */ X, /* SI */ X, +// /* DLE */ X, /* DC1 */ X, +// /* DC2 */ X, /* DC3 */ X, +// /* DC4 */ X, /* NAK */ X, +// /* SYN */ X, /* ETB */ X, +// /* CAN */ X, /* EM */ X, +// /* SUB */ X, /* ESC */ X, +// /* FS */ X, /* GS */ X, +// /* RS */ X, /* US */ X, +// /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), +// /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), +// /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), +// /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), +// /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), +// /* * */ KEYS(KeyAsterisk), /* + */ KEYS(KeyPlus), +// /* , */ KEYS(KeyComma), /* - */ KEYS(KeyMinus), +// /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeyForwardSlash), +// /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), +// /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), +// /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), +// /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), +// /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), +// /* : */ SHIFT(KeyAsterisk), /* ; */ SHIFT(KeyPlus), +// /* < */ SHIFT(KeyComma), /* = */ SHIFT(KeyMinus), +// /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeyForwardSlash), +// /* @ */ KEYS(KeyAt), /* A */ SHIFT(KeyA), +// /* B */ SHIFT(KeyB), /* C */ SHIFT(KeyC), +// /* D */ SHIFT(KeyD), /* E */ SHIFT(KeyE), +// /* F */ SHIFT(KeyF), /* G */ SHIFT(KeyG), +// /* H */ SHIFT(KeyH), /* I */ SHIFT(KeyI), +// /* J */ SHIFT(KeyJ), /* K */ SHIFT(KeyK), +// /* L */ SHIFT(KeyL), /* M */ SHIFT(KeyM), +// /* N */ SHIFT(KeyN), /* O */ SHIFT(KeyO), +// /* P */ SHIFT(KeyP), /* Q */ SHIFT(KeyQ), +// /* R */ SHIFT(KeyR), /* S */ SHIFT(KeyS), +// /* T */ SHIFT(KeyT), /* U */ SHIFT(KeyU), +// /* V */ SHIFT(KeyV), /* W */ SHIFT(KeyW), +// /* X */ SHIFT(KeyX), /* Y */ SHIFT(KeyY), +// /* Z */ SHIFT(KeyZ), /* [ */ X, +// /* \ */ X, /* ] */ X, +// /* ^ */ SHIFT(KeyAt), /* _ */ X, +// /* ` */ X, /* a */ KEYS(KeyA), +// /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), +// /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), +// /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), +// /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), +// /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), +// /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), +// /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), +// /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), +// /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), +// /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), +// /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), +// /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), +// /* z */ KEYS(KeyZ) +// }; +// #undef KEYS +// #undef SHIFT +// #undef X +// +// return table_lookup_sequence_for_character(key_sequences, character); + }; } diff --git a/Machines/Thomson/MO/MO.cpp b/Machines/Thomson/MO/MO.cpp index 4d6743825..40f23c0af 100644 --- a/Machines/Thomson/MO/MO.cpp +++ b/Machines/Thomson/MO/MO.cpp @@ -614,7 +614,7 @@ private: // MARK: - MappedKeyboardMachine. Thomson::MO5::KeyboardMapper keyboard_mapper_; - KeyboardMapper *get_keyboard_mapper() final { + KeyboardMapper *keyboard_mapper() final { return &keyboard_mapper_; } @@ -626,15 +626,15 @@ private: system_pia_port_handler_.clear_all_keys(); } - void type_string(const std::string &string) final { + void type_string(const std::wstring &string) final { Utility::TypeRecipient::add_typer(string); } - bool can_type(char c) const final { + bool can_type(const wchar_t c) const final { return Utility::TypeRecipient::can_type(c); } - HalfCycles get_typer_delay(const std::string &) const final { + HalfCycles typer_delay(const std::wstring &) const final { if(m6809_.template get()) { return Cycles(1'000'000); } else { @@ -642,7 +642,7 @@ private: } } - HalfCycles get_typer_frequency() const final { + HalfCycles typer_frequency() const final { return Cycles(20'000); } diff --git a/Machines/Utility/StringSerialiser.cpp b/Machines/Utility/StringSerialiser.cpp index 6b0554a45..4d5d9637a 100644 --- a/Machines/Utility/StringSerialiser.cpp +++ b/Machines/Utility/StringSerialiser.cpp @@ -10,7 +10,7 @@ using namespace Utility; -StringSerialiser::StringSerialiser(const std::string &source, bool use_linefeed_only) { +StringSerialiser::StringSerialiser(const std::wstring &source, const bool use_linefeed_only) { if(!use_linefeed_only) { input_string_ = source; } else { @@ -31,7 +31,7 @@ StringSerialiser::StringSerialiser(const std::string &source, bool use_linefeed_ } } -uint8_t StringSerialiser::head() { +wchar_t StringSerialiser::head() { if(input_string_pointer_ == input_string_.size()) return '\0'; return uint8_t(input_string_[input_string_pointer_]); diff --git a/Machines/Utility/StringSerialiser.hpp b/Machines/Utility/StringSerialiser.hpp index d0ee5522c..d11a63f8b 100644 --- a/Machines/Utility/StringSerialiser.hpp +++ b/Machines/Utility/StringSerialiser.hpp @@ -15,13 +15,13 @@ namespace Utility { class StringSerialiser { public: - StringSerialiser(const std::string &source, bool use_linefeed_only = false); + StringSerialiser(const std::wstring &source, bool use_linefeed_only = false); - uint8_t head(); + wchar_t head(); bool advance(); private: - std::string input_string_; + std::wstring input_string_; std::size_t input_string_pointer_ = 0; }; diff --git a/Machines/Utility/Typer.hpp b/Machines/Utility/Typer.hpp index cd18b99bc..ba7b8a6e6 100644 --- a/Machines/Utility/Typer.hpp +++ b/Machines/Utility/Typer.hpp @@ -87,8 +87,8 @@ public: /// Adds the contents of @c str to the end of the current string. void append(const std::wstring &); - static constexpr char BeginString = 0x02; // i.e. ASCII start of text. - static constexpr char EndString = 0x03; // i.e. ASCII end of text. + static constexpr wchar_t BeginString = 0x02; // i.e. ASCII start of text. + static constexpr wchar_t EndString = 0x03; // i.e. ASCII end of text. private: std::wstring string_; diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index ad78a929a..269ed5ee0 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -214,7 +214,7 @@ struct ActivityObserver: public Activity::Observer { // Use the keyboard as a joystick if the machine has no keyboard, or if it has a 'non-exclusive' keyboard. _inputMode = - (_machine->keyboard_machine() && _machine->keyboard_machine()->get_keyboard().is_exclusive()) + (_machine->keyboard_machine() && _machine->keyboard_machine()->keyboard().is_exclusive()) ? CSMachineKeyboardInputModeKeyboardPhysical : CSMachineKeyboardInputModeJoystick; _joystickMachine = _machine->joystick_machine(); @@ -431,7 +431,7 @@ struct ActivityObserver: public Activity::Observer { - (void)setKey:(uint16_t)key characters:(NSString *)characters isPressed:(BOOL)isPressed isRepeat:(BOOL)isRepeat { [self applyInputEvent:^{ auto keyboard_machine = self->_machine->keyboard_machine(); - if(keyboard_machine && (self.inputMode != CSMachineKeyboardInputModeJoystick || !keyboard_machine->get_keyboard().is_exclusive())) { + if(keyboard_machine && (self.inputMode != CSMachineKeyboardInputModeJoystick || !keyboard_machine->keyboard().is_exclusive())) { Inputs::Keyboard::Key mapped_key = Inputs::Keyboard::Key::Help; // Make an innocuous default guess. #define BIND(source, dest) case source: mapped_key = Inputs::Keyboard::Key::dest; break; // Connect the Carbon-era Mac keyboard scancodes to Clock Signal's 'universal' enumeration in order @@ -555,7 +555,7 @@ struct ActivityObserver: public Activity::Observer { const auto keyboard_machine = _machine->keyboard_machine(); if(keyboard_machine) { [self applyInputEvent:^{ - keyboard_machine->get_keyboard().reset_all_keys(); + keyboard_machine->keyboard().reset_all_keys(); }]; } @@ -733,13 +733,13 @@ struct ActivityObserver: public Activity::Observer { } - (BOOL)hasExclusiveKeyboard { - return !!_machine->keyboard_machine() && _machine->keyboard_machine()->get_keyboard().is_exclusive(); + return !!_machine->keyboard_machine() && _machine->keyboard_machine()->keyboard().is_exclusive(); } - (BOOL)shouldUsurpCommand { if(!_machine->keyboard_machine()) return NO; - const auto essential_modifiers = _machine->keyboard_machine()->get_keyboard().get_essential_modifiers(); + const auto essential_modifiers = _machine->keyboard_machine()->keyboard().get_essential_modifiers(); return essential_modifiers.find(Inputs::Keyboard::Key::LeftMeta) != essential_modifiers.end() || essential_modifiers.find(Inputs::Keyboard::Key::RightMeta) != essential_modifiers.end(); } diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index 6d935ded1..af1b612a5 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -1191,7 +1191,7 @@ int main(int argc, char *argv[]) { // Announce a potential discontinuity in keyboard input. const auto keyboard_machine = machine->keyboard_machine(); if(keyboard_machine) { - keyboard_machine->get_keyboard().reset_all_keys(); + keyboard_machine->keyboard().reset_all_keys(); } break; } @@ -1300,7 +1300,7 @@ int main(int argc, char *argv[]) { // This is a slightly terrible way of obtaining a symbol for the key, e.g. for letters it will always return // the capital letter version, at least empirically. But it'll have to do for now. const char *key_name = SDL_GetKeyName(keypress.keycode); - if(keyboard_machine->get_keyboard().set_key_pressed(key, (strlen(key_name) == 1) ? key_name[0] : 0, keypress.is_down, keypress.repeat)) { + if(keyboard_machine->keyboard().set_key_pressed(key, (strlen(key_name) == 1) ? key_name[0] : 0, keypress.is_down, keypress.repeat)) { continue; } }