duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

input_source.cpp (5240B)


      1 // SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #include "input_source.h"
      5 #include "common/string_util.h"
      6 
      7 InputSource::InputSource() = default;
      8 
      9 InputSource::~InputSource() = default;
     10 
     11 void InputSource::UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity,
     12                                    float small_intensity)
     13 {
     14   if (large_key.bits != 0)
     15     UpdateMotorState(large_key, large_intensity);
     16   if (small_key.bits != 0)
     17     UpdateMotorState(small_key, small_intensity);
     18 }
     19 
     20 InputBindingKey InputSource::MakeGenericControllerAxisKey(InputSourceType clazz, u32 controller_index, s32 axis_index)
     21 {
     22   InputBindingKey key = {};
     23   key.source_type = clazz;
     24   key.source_index = controller_index;
     25   key.source_subtype = InputSubclass::ControllerAxis;
     26   key.data = static_cast<u32>(axis_index);
     27   return key;
     28 }
     29 
     30 InputBindingKey InputSource::MakeGenericControllerButtonKey(InputSourceType clazz, u32 controller_index,
     31                                                             s32 button_index)
     32 {
     33   InputBindingKey key = {};
     34   key.source_type = clazz;
     35   key.source_index = controller_index;
     36   key.source_subtype = InputSubclass::ControllerButton;
     37   key.data = static_cast<u32>(button_index);
     38   return key;
     39 }
     40 
     41 InputBindingKey InputSource::MakeGenericControllerHatKey(InputSourceType clazz, u32 controller_index, s32 hat_index,
     42                                                          u8 hat_direction, u32 num_directions)
     43 {
     44   InputBindingKey key = {};
     45   key.source_type = clazz;
     46   key.source_index = controller_index;
     47   key.source_subtype = InputSubclass::ControllerHat;
     48   key.data = static_cast<u32>(hat_index) * num_directions + hat_direction;
     49   return key;
     50 }
     51 
     52 InputBindingKey InputSource::MakeGenericControllerMotorKey(InputSourceType clazz, u32 controller_index, s32 motor_index)
     53 {
     54   InputBindingKey key = {};
     55   key.source_type = clazz;
     56   key.source_index = controller_index;
     57   key.source_subtype = InputSubclass::ControllerMotor;
     58   key.data = static_cast<u32>(motor_index);
     59   return key;
     60 }
     61 
     62 std::optional<InputBindingKey> InputSource::ParseGenericControllerKey(InputSourceType clazz,
     63                                                                       std::string_view source,
     64                                                                       std::string_view sub_binding)
     65 {
     66   // try to find the number, this function doesn't care about whether it's xinput or sdl or whatever
     67   std::string_view::size_type pos = 0;
     68   while (pos < source.size())
     69   {
     70     if (source[pos] >= '0' && source[pos] <= '9')
     71       break;
     72     pos++;
     73   }
     74   if (pos == source.size())
     75     return std::nullopt;
     76 
     77   const std::optional<s32> source_index = StringUtil::FromChars<s32>(source.substr(pos));
     78   if (!source_index.has_value() || source_index.value() < 0)
     79     return std::nullopt;
     80 
     81   InputBindingKey key = {};
     82   key.source_type = clazz;
     83   key.source_index = source_index.value();
     84 
     85   if (sub_binding.starts_with("+Axis") || sub_binding.starts_with("-Axis"))
     86   {
     87     const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(5));
     88     if (!axis_number.has_value() || axis_number.value() < 0)
     89       return std::nullopt;
     90 
     91     key.source_subtype = InputSubclass::ControllerAxis;
     92     key.data = static_cast<u32>(axis_number.value());
     93 
     94     if (sub_binding[0] == '+')
     95       key.modifier = InputModifier::None;
     96     else if (sub_binding[0] == '-')
     97       key.modifier = InputModifier::Negate;
     98     else
     99       return std::nullopt;
    100   }
    101   else if (sub_binding.starts_with("FullAxis"))
    102   {
    103     const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(8));
    104     if (!axis_number.has_value() || axis_number.value() < 0)
    105       return std::nullopt;
    106     key.source_subtype = InputSubclass::ControllerAxis;
    107     key.data = static_cast<u32>(axis_number.value());
    108     key.modifier = InputModifier::FullAxis;
    109   }
    110   else if (sub_binding.starts_with("Button"))
    111   {
    112     const std::optional<s32> button_number = StringUtil::FromChars<s32>(sub_binding.substr(6));
    113     if (!button_number.has_value() || button_number.value() < 0)
    114       return std::nullopt;
    115 
    116     key.source_subtype = InputSubclass::ControllerButton;
    117     key.data = static_cast<u32>(button_number.value());
    118   }
    119   else
    120   {
    121     return std::nullopt;
    122   }
    123 
    124   return key;
    125 }
    126 
    127 std::string InputSource::ConvertGenericControllerKeyToString(InputBindingKey key)
    128 {
    129   if (key.source_subtype == InputSubclass::ControllerAxis)
    130   {
    131     const char* modifier = "";
    132     switch (key.modifier)
    133     {
    134       case InputModifier::None:
    135         modifier = "+";
    136         break;
    137       case InputModifier::Negate:
    138         modifier = "-";
    139         break;
    140       case InputModifier::FullAxis:
    141         modifier = "Full";
    142         break;
    143     }
    144     return fmt::format("{}-{}/{}Axis{}", InputManager::InputSourceToString(key.source_type),
    145                        static_cast<u32>(key.source_index), modifier, key.data);
    146   }
    147   else if (key.source_subtype == InputSubclass::ControllerButton)
    148   {
    149     return fmt::format("{}{}/Button{}", InputManager::InputSourceToString(key.source_type),
    150                        static_cast<u32>(key.source_index), key.data);
    151   }
    152   else
    153   {
    154     return {};
    155   }
    156 }