mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	InputCommon: add AnalogFromButton
This commit is contained in:
		
							parent
							
								
									38e800f70d
								
							
						
					
					
						commit
						a6bd7917cb
					
				
					 8 changed files with 162 additions and 0 deletions
				
			
		|  | @ -8,6 +8,7 @@ | |||
| #include "citra/default_ini.h" | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/param_package.h" | ||||
| #include "config.h" | ||||
| #include "core/settings.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, | ||||
| }; | ||||
| 
 | ||||
| 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() { | ||||
|     // Controls
 | ||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||
|  | @ -54,6 +64,16 @@ void Config::ReadValues() { | |||
|             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
 | ||||
|     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, | ||||
| }; | ||||
| 
 | ||||
| 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() { | ||||
|     qt_config->beginGroup("Controls"); | ||||
|     for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||||
|  | @ -34,6 +43,20 @@ void Config::ReadValues() { | |||
|         if (Settings::values.buttons[i].empty()) | ||||
|             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->beginGroup("Core"); | ||||
|  | @ -158,6 +181,10 @@ void Config::SaveValues() { | |||
|         qt_config->setValue(QString::fromStdString(Settings::NativeButton::mapping[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->beginGroup("Core"); | ||||
|  |  | |||
|  | @ -24,5 +24,7 @@ public: | |||
| 
 | ||||
|     void Reload(); | ||||
|     void Save(); | ||||
| 
 | ||||
|     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 | ||||
|             analog_from_button.cpp | ||||
|             keyboard.cpp | ||||
|             main.cpp | ||||
|             ) | ||||
| 
 | ||||
| set(HEADERS | ||||
|             analog_from_button.h | ||||
|             keyboard.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 "common/param_package.h" | ||||
| #include "input_common/analog_from_button.h" | ||||
| #include "input_common/keyboard.h" | ||||
| #include "input_common/main.h" | ||||
| 
 | ||||
|  | @ -14,11 +15,14 @@ static std::shared_ptr<Keyboard> keyboard; | |||
| void Init() { | ||||
|     keyboard = std::make_shared<InputCommon::Keyboard>(); | ||||
|     Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); | ||||
|     Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", | ||||
|                                                 std::make_shared<InputCommon::AnalogFromButton>()); | ||||
| } | ||||
| 
 | ||||
| void Shutdown() { | ||||
|     Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); | ||||
|     keyboard.reset(); | ||||
|     Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); | ||||
| } | ||||
| 
 | ||||
| Keyboard* GetKeyboard() { | ||||
|  | @ -32,4 +36,18 @@ std::string GenerateKeyboardParam(int key_code) { | |||
|     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
 | ||||
|  |  | |||
|  | @ -22,4 +22,8 @@ Keyboard* GetKeyboard(); | |||
| /// Generates a serialized param package for creating a keyboard button device
 | ||||
| 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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue