InputCommon: add AnalogFromButton
This commit is contained in:
		| @@ -8,6 +8,7 @@ | |||||||
| #include "citra/default_ini.h" | #include "citra/default_ini.h" | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|  | #include "common/param_package.h" | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
| #include "input_common/main.h" | #include "input_common/main.h" | ||||||
| @@ -44,6 +45,15 @@ static const std::array<int, Settings::NativeButton::NumButtons> default_buttons | |||||||
|     SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, |     SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs{{ | ||||||
|  |     { | ||||||
|  |         SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_D, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, SDL_SCANCODE_L, SDL_SCANCODE_D, | ||||||
|  |     }, | ||||||
|  | }}; | ||||||
|  |  | ||||||
| void Config::ReadValues() { | void Config::ReadValues() { | ||||||
|     // Controls |     // Controls | ||||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||||
| @@ -54,6 +64,16 @@ void Config::ReadValues() { | |||||||
|             Settings::values.buttons[i] = default_param; |             Settings::values.buttons[i] = default_param; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { | ||||||
|  |         std::string default_param = InputCommon::GenerateAnalogParamFromKeys( | ||||||
|  |             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], | ||||||
|  |             default_analogs[i][3], default_analogs[i][4], 0.5f); | ||||||
|  |         Settings::values.analogs[i] = | ||||||
|  |             sdl2_config->Get("Controls", Settings::NativeAnalog::mapping[i], default_param); | ||||||
|  |         if (Settings::values.analogs[i].empty()) | ||||||
|  |             Settings::values.analogs[i] = default_param; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Core |     // Core | ||||||
|     Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); |     Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,6 +22,15 @@ const std::array<int, Settings::NativeButton::NumButtons> Config::default_button | |||||||
|     Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N, Qt::Key_1, Qt::Key_2, Qt::Key_B, |     Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N, Qt::Key_1, Qt::Key_2, Qt::Key_B, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{ | ||||||
|  |     { | ||||||
|  |         Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, Qt::Key_D, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L, Qt::Key_D, | ||||||
|  |     }, | ||||||
|  | }}; | ||||||
|  |  | ||||||
| void Config::ReadValues() { | void Config::ReadValues() { | ||||||
|     qt_config->beginGroup("Controls"); |     qt_config->beginGroup("Controls"); | ||||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||||
| @@ -34,6 +43,20 @@ void Config::ReadValues() { | |||||||
|         if (Settings::values.buttons[i].empty()) |         if (Settings::values.buttons[i].empty()) | ||||||
|             Settings::values.buttons[i] = default_param; |             Settings::values.buttons[i] = default_param; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { | ||||||
|  |         std::string default_param = InputCommon::GenerateAnalogParamFromKeys( | ||||||
|  |             default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], | ||||||
|  |             default_analogs[i][3], default_analogs[i][4], 0.5f); | ||||||
|  |         Settings::values.analogs[i] = | ||||||
|  |             qt_config | ||||||
|  |                 ->value(Settings::NativeAnalog::mapping[i], QString::fromStdString(default_param)) | ||||||
|  |                 .toString() | ||||||
|  |                 .toStdString(); | ||||||
|  |         if (Settings::values.analogs[i].empty()) | ||||||
|  |             Settings::values.analogs[i] = default_param; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     qt_config->endGroup(); |     qt_config->endGroup(); | ||||||
|  |  | ||||||
|     qt_config->beginGroup("Core"); |     qt_config->beginGroup("Core"); | ||||||
| @@ -158,6 +181,10 @@ void Config::SaveValues() { | |||||||
|         qt_config->setValue(QString::fromStdString(Settings::NativeButton::mapping[i]), |         qt_config->setValue(QString::fromStdString(Settings::NativeButton::mapping[i]), | ||||||
|                             QString::fromStdString(Settings::values.buttons[i])); |                             QString::fromStdString(Settings::values.buttons[i])); | ||||||
|     } |     } | ||||||
|  |     for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { | ||||||
|  |         qt_config->setValue(QString::fromStdString(Settings::NativeAnalog::mapping[i]), | ||||||
|  |                             QString::fromStdString(Settings::values.analogs[i])); | ||||||
|  |     } | ||||||
|     qt_config->endGroup(); |     qt_config->endGroup(); | ||||||
|  |  | ||||||
|     qt_config->beginGroup("Core"); |     qt_config->beginGroup("Core"); | ||||||
|   | |||||||
| @@ -24,5 +24,7 @@ public: | |||||||
|  |  | ||||||
|     void Reload(); |     void Reload(); | ||||||
|     void Save(); |     void Save(); | ||||||
|  |  | ||||||
|     static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; |     static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; | ||||||
|  |     static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,9 +1,11 @@ | |||||||
| set(SRCS | set(SRCS | ||||||
|  |             analog_from_button.cpp | ||||||
|             keyboard.cpp |             keyboard.cpp | ||||||
|             main.cpp |             main.cpp | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
| set(HEADERS | set(HEADERS | ||||||
|  |             analog_from_button.h | ||||||
|             keyboard.h |             keyboard.h | ||||||
|             main.h |             main.h | ||||||
|             ) |             ) | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								src/input_common/analog_from_button.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										58
									
								
								src/input_common/analog_from_button.cpp
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | // Copyright 2017 Citra Emulator Project | ||||||
|  | // Licensed under GPLv2 or any later version | ||||||
|  | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | #include "input_common/analog_from_button.h" | ||||||
|  |  | ||||||
|  | namespace InputCommon { | ||||||
|  |  | ||||||
|  | class Analog final : public Input::AnalogDevice { | ||||||
|  | public: | ||||||
|  |     using Button = std::unique_ptr<Input::ButtonDevice>; | ||||||
|  |  | ||||||
|  |     Analog(Button up_, Button down_, Button left_, Button right_, Button modifier_, | ||||||
|  |            float modifier_scale_) | ||||||
|  |         : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)), | ||||||
|  |           right(std::move(right_)), modifier(std::move(modifier_)), | ||||||
|  |           modifier_scale(modifier_scale_) {} | ||||||
|  |  | ||||||
|  |     std::tuple<float, float> GetStatus() const override { | ||||||
|  |         constexpr float SQRT_HALF = 0.707106781f; | ||||||
|  |         int x = 0, y = 0; | ||||||
|  |  | ||||||
|  |         if (right->GetStatus()) | ||||||
|  |             ++x; | ||||||
|  |         if (left->GetStatus()) | ||||||
|  |             --x; | ||||||
|  |         if (up->GetStatus()) | ||||||
|  |             ++y; | ||||||
|  |         if (down->GetStatus()) | ||||||
|  |             --y; | ||||||
|  |  | ||||||
|  |         float coef = modifier->GetStatus() ? modifier_scale : 1.0f; | ||||||
|  |         return std::make_tuple(x * coef * (y == 0 ? 1.0f : SQRT_HALF), | ||||||
|  |                                y * coef * (x == 0 ? 1.0f : SQRT_HALF)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Button up; | ||||||
|  |     Button down; | ||||||
|  |     Button left; | ||||||
|  |     Button right; | ||||||
|  |     Button modifier; | ||||||
|  |     float modifier_scale; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | std::unique_ptr<Input::AnalogDevice> AnalogFromButton::Create(const Common::ParamPackage& params) { | ||||||
|  |     const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); | ||||||
|  |     auto up = Input::CreateDevice<Input::ButtonDevice>(params.Get("up", null_engine)); | ||||||
|  |     auto down = Input::CreateDevice<Input::ButtonDevice>(params.Get("down", null_engine)); | ||||||
|  |     auto left = Input::CreateDevice<Input::ButtonDevice>(params.Get("left", null_engine)); | ||||||
|  |     auto right = Input::CreateDevice<Input::ButtonDevice>(params.Get("right", null_engine)); | ||||||
|  |     auto modifier = Input::CreateDevice<Input::ButtonDevice>(params.Get("modifier", null_engine)); | ||||||
|  |     auto modifier_scale = params.Get("modifier_scale", 0.5f); | ||||||
|  |     return std::make_unique<Analog>(std::move(up), std::move(down), std::move(left), | ||||||
|  |                                     std::move(right), std::move(modifier), modifier_scale); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace InputCommon | ||||||
							
								
								
									
										31
									
								
								src/input_common/analog_from_button.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								src/input_common/analog_from_button.h
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | // 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 { | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * An analog device factory that takes direction button devices and combines them into a analog | ||||||
|  |  * device. | ||||||
|  |  */ | ||||||
|  | class AnalogFromButton final : public Input::Factory<Input::AnalogDevice> { | ||||||
|  | public: | ||||||
|  |     /** | ||||||
|  |      * Creates an analog device from direction button devices | ||||||
|  |      * @param params contains parameters for creating the device: | ||||||
|  |      *     - "up": a serialized ParamPackage for creating a button device for up direction | ||||||
|  |      *     - "down": a serialized ParamPackage for creating a button device for down direction | ||||||
|  |      *     - "left": a serialized ParamPackage for creating a button device for left direction | ||||||
|  |      *     - "right": a serialized ParamPackage  for creating a button device for right direction | ||||||
|  |      *     - "modifier": a serialized ParamPackage for creating a button device as the modifier | ||||||
|  |      *     - "modifier_scale": a float for the multiplier the modifier gives to the position | ||||||
|  |      */ | ||||||
|  |     std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace InputCommon | ||||||
| @@ -4,6 +4,7 @@ | |||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
| #include "common/param_package.h" | #include "common/param_package.h" | ||||||
|  | #include "input_common/analog_from_button.h" | ||||||
| #include "input_common/keyboard.h" | #include "input_common/keyboard.h" | ||||||
| #include "input_common/main.h" | #include "input_common/main.h" | ||||||
|  |  | ||||||
| @@ -14,11 +15,14 @@ static std::shared_ptr<Keyboard> keyboard; | |||||||
| void Init() { | void Init() { | ||||||
|     keyboard = std::make_shared<InputCommon::Keyboard>(); |     keyboard = std::make_shared<InputCommon::Keyboard>(); | ||||||
|     Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); |     Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); | ||||||
|  |     Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", | ||||||
|  |                                                 std::make_shared<InputCommon::AnalogFromButton>()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Shutdown() { | void Shutdown() { | ||||||
|     Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); |     Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); | ||||||
|     keyboard.reset(); |     keyboard.reset(); | ||||||
|  |     Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); | ||||||
| } | } | ||||||
|  |  | ||||||
| Keyboard* GetKeyboard() { | Keyboard* GetKeyboard() { | ||||||
| @@ -32,4 +36,18 @@ std::string GenerateKeyboardParam(int key_code) { | |||||||
|     return param.Serialize(); |     return param.Serialize(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right, | ||||||
|  |                                         int key_modifier, float modifier_scale) { | ||||||
|  |     Common::ParamPackage circle_pad_param{ | ||||||
|  |         {"engine", "analog_from_button"}, | ||||||
|  |         {"up", GenerateKeyboardParam(key_up)}, | ||||||
|  |         {"down", GenerateKeyboardParam(key_down)}, | ||||||
|  |         {"left", GenerateKeyboardParam(key_left)}, | ||||||
|  |         {"right", GenerateKeyboardParam(key_right)}, | ||||||
|  |         {"modifier", GenerateKeyboardParam(key_modifier)}, | ||||||
|  |         {"modifier_scale", std::to_string(modifier_scale)}, | ||||||
|  |     }; | ||||||
|  |     return circle_pad_param.Serialize(); | ||||||
|  | } | ||||||
|  |  | ||||||
| } // namespace InputCommon | } // namespace InputCommon | ||||||
|   | |||||||
| @@ -22,4 +22,8 @@ Keyboard* GetKeyboard(); | |||||||
| /// Generates a serialized param package for creating a keyboard button device | /// Generates a serialized param package for creating a keyboard button device | ||||||
| std::string GenerateKeyboardParam(int key_code); | std::string GenerateKeyboardParam(int key_code); | ||||||
|  |  | ||||||
|  | /// Generates a serialized param package for creating an analog device taking input from keyboard | ||||||
|  | std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right, | ||||||
|  |                                         int key_modifier, float modifier_scale); | ||||||
|  |  | ||||||
| } // namespace InputCommon | } // namespace InputCommon | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user