InputCommon: add Keyboard
This commit is contained in:
		| @@ -5,6 +5,7 @@ add_subdirectory(common) | ||||
| add_subdirectory(core) | ||||
| add_subdirectory(video_core) | ||||
| add_subdirectory(audio_core) | ||||
| add_subdirectory(input_common) | ||||
| add_subdirectory(tests) | ||||
| if (ENABLE_SDL2) | ||||
|     add_subdirectory(citra) | ||||
|   | ||||
| @@ -18,7 +18,7 @@ create_directory_groups(${SRCS} ${HEADERS}) | ||||
| include_directories(${SDL2_INCLUDE_DIR}) | ||||
|  | ||||
| add_executable(citra ${SRCS} ${HEADERS}) | ||||
| target_link_libraries(citra core video_core audio_core common) | ||||
| target_link_libraries(citra core video_core audio_core common input_common) | ||||
| target_link_libraries(citra ${SDL2_LIBRARY} ${OPENGL_gl_LIBRARY} inih glad) | ||||
| if (MSVC) | ||||
|     target_link_libraries(citra getopt) | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "config.h" | ||||
| #include "core/settings.h" | ||||
| #include "input_common/main.h" | ||||
|  | ||||
| Config::Config() { | ||||
|     // TODO: Don't hardcode the path; let the frontend decide where to put the config files. | ||||
| @@ -37,25 +38,21 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) { | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { | ||||
|     // directly mapped keys | ||||
|     SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_Q, SDL_SCANCODE_W, | ||||
|     SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_B, SDL_SCANCODE_T, | ||||
|     SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, | ||||
|     SDL_SCANCODE_L, | ||||
|  | ||||
|     // indirectly mapped keys | ||||
|     SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_D, | ||||
| static const std::array<int, Settings::NativeButton::NumButtons> default_buttons = { | ||||
|     SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, | ||||
|     SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, | ||||
|     SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, | ||||
| }; | ||||
|  | ||||
| void Config::ReadValues() { | ||||
|     // Controls | ||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||
|         Settings::values.input_mappings[Settings::NativeInput::All[i]] = | ||||
|             sdl2_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); | ||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||
|         std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); | ||||
|         Settings::values.buttons[i] = | ||||
|             sdl2_config->Get("Controls", Settings::NativeButton::mapping[i], default_param); | ||||
|         if (Settings::values.buttons[i].empty()) | ||||
|             Settings::values.buttons[i] = default_param; | ||||
|     } | ||||
|     Settings::values.pad_circle_modifier_scale = | ||||
|         (float)sdl2_config->GetReal("Controls", "pad_circle_modifier_scale", 0.5); | ||||
|  | ||||
|     // Core | ||||
|     Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); | ||||
|   | ||||
| @@ -12,9 +12,9 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "common/scm_rev.h" | ||||
| #include "common/string_util.h" | ||||
| #include "core/frontend/key_map.h" | ||||
| #include "core/hle/service/hid/hid.h" | ||||
| #include "core/settings.h" | ||||
| #include "input_common/keyboard.h" | ||||
| #include "input_common/main.h" | ||||
| #include "video_core/video_core.h" | ||||
|  | ||||
| void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { | ||||
| @@ -40,9 +40,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { | ||||
|  | ||||
| void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { | ||||
|     if (state == SDL_PRESSED) { | ||||
|         KeyMap::PressKey(*this, {key, keyboard_id}); | ||||
|         InputCommon::GetKeyboard()->PressKey(key); | ||||
|     } else if (state == SDL_RELEASED) { | ||||
|         KeyMap::ReleaseKey(*this, {key, keyboard_id}); | ||||
|         InputCommon::GetKeyboard()->ReleaseKey(key); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -57,9 +57,8 @@ void EmuWindow_SDL2::OnResize() { | ||||
| } | ||||
|  | ||||
| EmuWindow_SDL2::EmuWindow_SDL2() { | ||||
|     keyboard_id = KeyMap::NewDeviceId(); | ||||
|     InputCommon::Init(); | ||||
|  | ||||
|     ReloadSetKeymaps(); | ||||
|     motion_emu = std::make_unique<Motion::MotionEmu>(*this); | ||||
|  | ||||
|     SDL_SetMainReady(); | ||||
| @@ -117,6 +116,7 @@ EmuWindow_SDL2::~EmuWindow_SDL2() { | ||||
|     SDL_GL_DeleteContext(gl_context); | ||||
|     SDL_Quit(); | ||||
|     motion_emu = nullptr; | ||||
|     InputCommon::Shutdown(); | ||||
| } | ||||
|  | ||||
| void EmuWindow_SDL2::SwapBuffers() { | ||||
| @@ -169,15 +169,6 @@ void EmuWindow_SDL2::DoneCurrent() { | ||||
|     SDL_GL_MakeCurrent(render_window, nullptr); | ||||
| } | ||||
|  | ||||
| void EmuWindow_SDL2::ReloadSetKeymaps() { | ||||
|     KeyMap::ClearKeyMapping(keyboard_id); | ||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||
|         KeyMap::SetKeyMapping( | ||||
|             {Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, | ||||
|             KeyMap::mapping_targets[i]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest( | ||||
|     const std::pair<unsigned, unsigned>& minimal_size) { | ||||
|  | ||||
|   | ||||
| @@ -31,9 +31,6 @@ public: | ||||
|     /// Whether the window is still open, and a close request hasn't yet been sent | ||||
|     bool IsOpen() const; | ||||
|  | ||||
|     /// Load keymap from configuration | ||||
|     void ReloadSetKeymaps() override; | ||||
|  | ||||
| private: | ||||
|     /// Called by PollEvents when a key is pressed or released. | ||||
|     void OnKeyEvent(int key, u8 state); | ||||
| @@ -61,9 +58,6 @@ private: | ||||
|     /// The OpenGL context associated with the window | ||||
|     SDL_GLContext gl_context; | ||||
|  | ||||
|     /// Device id of keyboard for use with KeyMap | ||||
|     int keyboard_id; | ||||
|  | ||||
|     /// Motion sensors emulation | ||||
|     std::unique_ptr<Motion::MotionEmu> motion_emu; | ||||
| }; | ||||
|   | ||||
| @@ -97,7 +97,7 @@ if (APPLE) | ||||
| else() | ||||
|     add_executable(citra-qt ${SRCS} ${HEADERS} ${UI_HDRS}) | ||||
| endif() | ||||
| target_link_libraries(citra-qt core video_core audio_core common) | ||||
| target_link_libraries(citra-qt core video_core audio_core common input_common) | ||||
| target_link_libraries(citra-qt ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS}) | ||||
| target_link_libraries(citra-qt ${PLATFORM_LIBRARIES} Threads::Threads) | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,8 @@ | ||||
| #include "common/scm_rev.h" | ||||
| #include "common/string_util.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/key_map.h" | ||||
| #include "input_common/keyboard.h" | ||||
| #include "input_common/main.h" | ||||
| #include "video_core/debug_utils/debug_utils.h" | ||||
| #include "video_core/video_core.h" | ||||
|  | ||||
| @@ -99,14 +100,17 @@ private: | ||||
| }; | ||||
|  | ||||
| GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) | ||||
|     : QWidget(parent), child(nullptr), keyboard_id(0), emu_thread(emu_thread) { | ||||
|     : QWidget(parent), child(nullptr), emu_thread(emu_thread) { | ||||
|  | ||||
|     std::string window_title = Common::StringFromFormat("Citra %s| %s-%s", Common::g_build_name, | ||||
|                                                         Common::g_scm_branch, Common::g_scm_desc); | ||||
|     setWindowTitle(QString::fromStdString(window_title)); | ||||
|  | ||||
|     keyboard_id = KeyMap::NewDeviceId(); | ||||
|     ReloadSetKeymaps(); | ||||
|     InputCommon::Init(); | ||||
| } | ||||
|  | ||||
| GRenderWindow::~GRenderWindow() { | ||||
|     InputCommon::Shutdown(); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::moveContext() { | ||||
| @@ -197,11 +201,11 @@ void GRenderWindow::closeEvent(QCloseEvent* event) { | ||||
| } | ||||
|  | ||||
| void GRenderWindow::keyPressEvent(QKeyEvent* event) { | ||||
|     KeyMap::PressKey(*this, {event->key(), keyboard_id}); | ||||
|     InputCommon::GetKeyboard()->PressKey(event->key()); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { | ||||
|     KeyMap::ReleaseKey(*this, {event->key(), keyboard_id}); | ||||
|     InputCommon::GetKeyboard()->ReleaseKey(event->key()); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::mousePressEvent(QMouseEvent* event) { | ||||
| @@ -230,14 +234,7 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { | ||||
|         motion_emu->EndTilt(); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::ReloadSetKeymaps() { | ||||
|     KeyMap::ClearKeyMapping(keyboard_id); | ||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||
|         KeyMap::SetKeyMapping( | ||||
|             {Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, | ||||
|             KeyMap::mapping_targets[i]); | ||||
|     } | ||||
| } | ||||
| void GRenderWindow::ReloadSetKeymaps() {} | ||||
|  | ||||
| void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) { | ||||
|     NotifyClientAreaSizeChanged(std::make_pair(width, height)); | ||||
|   | ||||
| @@ -104,6 +104,7 @@ class GRenderWindow : public QWidget, public EmuWindow { | ||||
|  | ||||
| public: | ||||
|     GRenderWindow(QWidget* parent, EmuThread* emu_thread); | ||||
|     ~GRenderWindow(); | ||||
|  | ||||
|     // EmuWindow implementation | ||||
|     void SwapBuffers() override; | ||||
| @@ -127,7 +128,7 @@ public: | ||||
|     void mouseMoveEvent(QMouseEvent* event) override; | ||||
|     void mouseReleaseEvent(QMouseEvent* event) override; | ||||
|  | ||||
|     void ReloadSetKeymaps() override; | ||||
|     void ReloadSetKeymaps(); | ||||
|  | ||||
|     void OnClientAreaResized(unsigned width, unsigned height); | ||||
|  | ||||
| @@ -152,9 +153,6 @@ private: | ||||
|  | ||||
|     QByteArray geometry; | ||||
|  | ||||
|     /// Device id of keyboard for use with KeyMap | ||||
|     int keyboard_id; | ||||
|  | ||||
|     EmuThread* emu_thread; | ||||
|  | ||||
|     /// Motion sensors emulation | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include "citra_qt/config.h" | ||||
| #include "citra_qt/ui_settings.h" | ||||
| #include "common/file_util.h" | ||||
| #include "input_common/main.h" | ||||
|  | ||||
| Config::Config() { | ||||
|     // TODO: Don't hardcode the path; let the frontend decide where to put the config files. | ||||
| @@ -16,25 +17,23 @@ Config::Config() { | ||||
|     Reload(); | ||||
| } | ||||
|  | ||||
| const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> Config::defaults = { | ||||
|     // directly mapped keys | ||||
|     Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2, | ||||
|     Qt::Key_M, Qt::Key_N, Qt::Key_B, Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, Qt::Key_I, | ||||
|     Qt::Key_K, Qt::Key_J, Qt::Key_L, | ||||
|  | ||||
|     // indirectly mapped keys | ||||
|     Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, Qt::Key_D, | ||||
| const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = { | ||||
|     Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, | ||||
|     Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N, Qt::Key_1, Qt::Key_2, Qt::Key_B, | ||||
| }; | ||||
|  | ||||
| void Config::ReadValues() { | ||||
|     qt_config->beginGroup("Controls"); | ||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||
|         Settings::values.input_mappings[Settings::NativeInput::All[i]] = | ||||
|             qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]) | ||||
|                 .toInt(); | ||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||
|         std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); | ||||
|         Settings::values.buttons[i] = | ||||
|             qt_config | ||||
|                 ->value(Settings::NativeButton::mapping[i], QString::fromStdString(default_param)) | ||||
|                 .toString() | ||||
|                 .toStdString(); | ||||
|         if (Settings::values.buttons[i].empty()) | ||||
|             Settings::values.buttons[i] = default_param; | ||||
|     } | ||||
|     Settings::values.pad_circle_modifier_scale = | ||||
|         qt_config->value("pad_circle_modifier_scale", 0.5).toFloat(); | ||||
|     qt_config->endGroup(); | ||||
|  | ||||
|     qt_config->beginGroup("Core"); | ||||
| @@ -155,12 +154,10 @@ void Config::ReadValues() { | ||||
|  | ||||
| void Config::SaveValues() { | ||||
|     qt_config->beginGroup("Controls"); | ||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||
|         qt_config->setValue(QString::fromStdString(Settings::NativeInput::Mapping[i]), | ||||
|                             Settings::values.input_mappings[Settings::NativeInput::All[i]]); | ||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||
|         qt_config->setValue(QString::fromStdString(Settings::NativeButton::mapping[i]), | ||||
|                             QString::fromStdString(Settings::values.buttons[i])); | ||||
|     } | ||||
|     qt_config->setValue("pad_circle_modifier_scale", | ||||
|                         (double)Settings::values.pad_circle_modifier_scale); | ||||
|     qt_config->endGroup(); | ||||
|  | ||||
|     qt_config->beginGroup("Core"); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <array> | ||||
| #include <string> | ||||
| #include <QVariant> | ||||
| #include "core/settings.h" | ||||
| @@ -23,5 +24,5 @@ public: | ||||
|  | ||||
|     void Reload(); | ||||
|     void Save(); | ||||
|     static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults; | ||||
|     static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; | ||||
| }; | ||||
|   | ||||
| @@ -92,14 +92,7 @@ void ConfigureInput::loadConfiguration() { | ||||
|     updateButtonLabels(); | ||||
| } | ||||
|  | ||||
| void ConfigureInput::restoreDefaults() { | ||||
|     for (const auto& input_id : Settings::NativeInput::All) { | ||||
|         const size_t index = static_cast<size_t>(input_id); | ||||
|         key_map[input_id] = static_cast<Qt::Key>(Config::defaults[index].toInt()); | ||||
|     } | ||||
|     updateButtonLabels(); | ||||
|     applyConfiguration(); | ||||
| } | ||||
| void ConfigureInput::restoreDefaults() {} | ||||
|  | ||||
| void ConfigureInput::updateButtonLabels() { | ||||
|     for (const auto& input_id : Settings::NativeInput::All) { | ||||
|   | ||||
| @@ -52,8 +52,6 @@ public: | ||||
|     /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread | ||||
|     virtual void DoneCurrent() = 0; | ||||
|  | ||||
|     virtual void ReloadSetKeymaps() = 0; | ||||
|  | ||||
|     /** | ||||
|      * Signals a button press action to the HID module. | ||||
|      * @param pad_state indicates which button to press | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/input_common/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/input_common/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| set(SRCS | ||||
|             keyboard.cpp | ||||
|             main.cpp | ||||
|             ) | ||||
|  | ||||
| set(HEADERS | ||||
|             keyboard.h | ||||
|             main.h | ||||
|             ) | ||||
|  | ||||
| create_directory_groups(${SRCS} ${HEADERS}) | ||||
|  | ||||
| add_library(input_common STATIC ${SRCS} ${HEADERS}) | ||||
| target_link_libraries(input_common common core) | ||||
|  | ||||
							
								
								
									
										82
									
								
								src/input_common/keyboard.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/input_common/keyboard.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <atomic> | ||||
| #include <list> | ||||
| #include <mutex> | ||||
| #include "input_common/keyboard.h" | ||||
|  | ||||
| namespace InputCommon { | ||||
|  | ||||
| class KeyButton final : public Input::ButtonDevice { | ||||
| public: | ||||
|     explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) | ||||
|         : key_button_list(key_button_list_) {} | ||||
|  | ||||
|     ~KeyButton(); | ||||
|  | ||||
|     bool GetStatus() const override { | ||||
|         return status.load(); | ||||
|     } | ||||
|  | ||||
|     friend class KeyButtonList; | ||||
|  | ||||
| private: | ||||
|     std::shared_ptr<KeyButtonList> key_button_list; | ||||
|     std::atomic<bool> status{false}; | ||||
| }; | ||||
|  | ||||
| struct KeyButtonPair { | ||||
|     int key_code; | ||||
|     KeyButton* key_button; | ||||
| }; | ||||
|  | ||||
| class KeyButtonList { | ||||
| public: | ||||
|     void AddKeyButton(int key_code, KeyButton* key_button) { | ||||
|         std::lock_guard<std::mutex> guard(mutex); | ||||
|         list.push_back(KeyButtonPair{key_code, key_button}); | ||||
|     } | ||||
|  | ||||
|     void RemoveKeyButton(const KeyButton* key_button) { | ||||
|         std::lock_guard<std::mutex> guard(mutex); | ||||
|         list.remove_if( | ||||
|             [key_button](const KeyButtonPair& pair) { return pair.key_button == key_button; }); | ||||
|     } | ||||
|  | ||||
|     void ChangeKeyStatus(int key_code, bool pressed) { | ||||
|         std::lock_guard<std::mutex> guard(mutex); | ||||
|         for (const KeyButtonPair& pair : list) { | ||||
|             if (pair.key_code == key_code) | ||||
|                 pair.key_button->status.store(pressed); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     std::mutex mutex; | ||||
|     std::list<KeyButtonPair> list; | ||||
| }; | ||||
|  | ||||
| Keyboard::Keyboard() : key_button_list{std::make_shared<KeyButtonList>()} {} | ||||
|  | ||||
| KeyButton::~KeyButton() { | ||||
|     key_button_list->RemoveKeyButton(this); | ||||
| } | ||||
|  | ||||
| std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) { | ||||
|     int key_code = params.Get("code", 0); | ||||
|     std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list); | ||||
|     key_button_list->AddKeyButton(key_code, button.get()); | ||||
|     return std::move(button); | ||||
| } | ||||
|  | ||||
| void Keyboard::PressKey(int key_code) { | ||||
|     key_button_list->ChangeKeyStatus(key_code, true); | ||||
| } | ||||
|  | ||||
| void Keyboard::ReleaseKey(int key_code) { | ||||
|     key_button_list->ChangeKeyStatus(key_code, false); | ||||
| } | ||||
|  | ||||
| } // namespace InputCommon | ||||
							
								
								
									
										45
									
								
								src/input_common/keyboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/input_common/keyboard.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include "core/frontend/input.h" | ||||
|  | ||||
| namespace InputCommon { | ||||
|  | ||||
| class KeyButtonList; | ||||
|  | ||||
| /** | ||||
|  * A button device factory representing a keyboard. It receives keyboard events and forward them | ||||
|  * to all button devices it created. | ||||
|  */ | ||||
| class Keyboard final : public Input::Factory<Input::ButtonDevice> { | ||||
| public: | ||||
|     Keyboard(); | ||||
|  | ||||
|     /** | ||||
|      * Creates a button device from a keyboard key | ||||
|      * @param params contains parameters for creating the device: | ||||
|      *     - "code": the code of the key to bind with the button | ||||
|      */ | ||||
|     std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; | ||||
|  | ||||
|     /** | ||||
|      * Sets the status of all buttons bound with the key to pressed | ||||
|      * @param key_code the code of the key to press | ||||
|      */ | ||||
|     void PressKey(int key_code); | ||||
|  | ||||
|     /** | ||||
|      * Sets the status of all buttons bound with the key to released | ||||
|      * @param key_code the code of the key to release | ||||
|      */ | ||||
|     void ReleaseKey(int key_code); | ||||
|  | ||||
| private: | ||||
|     std::shared_ptr<KeyButtonList> key_button_list; | ||||
| }; | ||||
|  | ||||
| } // namespace InputCommon | ||||
							
								
								
									
										35
									
								
								src/input_common/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/input_common/main.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <memory> | ||||
| #include "common/param_package.h" | ||||
| #include "input_common/keyboard.h" | ||||
| #include "input_common/main.h" | ||||
|  | ||||
| namespace InputCommon { | ||||
|  | ||||
| static std::shared_ptr<Keyboard> keyboard; | ||||
|  | ||||
| void Init() { | ||||
|     keyboard = std::make_shared<InputCommon::Keyboard>(); | ||||
|     Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); | ||||
| } | ||||
|  | ||||
| void Shutdown() { | ||||
|     Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); | ||||
|     keyboard.reset(); | ||||
| } | ||||
|  | ||||
| Keyboard* GetKeyboard() { | ||||
|     return keyboard.get(); | ||||
| } | ||||
|  | ||||
| std::string GenerateKeyboardParam(int key_code) { | ||||
|     Common::ParamPackage param{ | ||||
|         {"engine", "keyboard"}, {"code", std::to_string(key_code)}, | ||||
|     }; | ||||
|     return param.Serialize(); | ||||
| } | ||||
|  | ||||
| } // namespace InputCommon | ||||
							
								
								
									
										25
									
								
								src/input_common/main.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/input_common/main.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace InputCommon { | ||||
|  | ||||
| /// Initializes and registers all built-in input device factories. | ||||
| void Init(); | ||||
|  | ||||
| /// Unresisters all build-in input device factories and shut them down. | ||||
| void Shutdown(); | ||||
|  | ||||
| class Keyboard; | ||||
|  | ||||
| /// Gets the keyboard button device factory. | ||||
| Keyboard* GetKeyboard(); | ||||
|  | ||||
| /// Generates a serialized param package for creating a keyboard button device | ||||
| std::string GenerateKeyboardParam(int key_code); | ||||
|  | ||||
| } // namespace InputCommon | ||||
		Reference in New Issue
	
	Block a user