diff --git a/.travis.yml b/.travis.yml index c04604b4cb35..d64a5ca2e002 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,13 @@ before_install: brew update; brew update; brew install ccache glew llvm40; fi; + # We need to update binutils to a newer version to link against the ffmpeg libs on. + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then + sudo add-apt-repository ppa:jonathonf/binutils -y ; + sudo apt-get update ; + sudo apt-get install binutils -y; + ld --version ; + fi; before_script: - git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers diff --git a/3rdparty/ffmpeg b/3rdparty/ffmpeg index a2e98d7ba4c7..7b7ae7b06705 160000 --- a/3rdparty/ffmpeg +++ b/3rdparty/ffmpeg @@ -1 +1 @@ -Subproject commit a2e98d7ba4c7c5cac08608732c3058cb46e3e0ef +Subproject commit 7b7ae7b06705bf5539b222e77c779d4b649b53ef diff --git a/rpcs3/evdev_joystick_handler.cpp b/rpcs3/evdev_joystick_handler.cpp index e3f92029bc8b..d1792395f2cf 100644 --- a/rpcs3/evdev_joystick_handler.cpp +++ b/rpcs3/evdev_joystick_handler.cpp @@ -11,6 +11,7 @@ #include #include #include +#include evdev_joystick_config g_evdev_joystick_config; @@ -20,8 +21,6 @@ namespace const u32 THREAD_SLEEP_INACTIVE_USEC = 1000000; const u32 READ_TIMEOUT = 10; const u32 THREAD_TIMEOUT_USEC = 1000000; - - const std::string EVENT_JOYSTICK = "event-joystick"; } evdev_joystick_handler::evdev_joystick_handler() {} @@ -41,17 +40,32 @@ void evdev_joystick_handler::Init(const u32 max_connect) revaxis.emplace_back(g_evdev_joystick_config.rxreverse); revaxis.emplace_back(g_evdev_joystick_config.ryreverse); - fs::dir devdir{"/dev/input/by-path"}; + fs::dir devdir{"/dev/input/"}; fs::dir_entry et; while (devdir.read(et)) { - // Does the entry name end with event-joystick? - if (et.name.size() > EVENT_JOYSTICK.size() && - et.name.compare(et.name.size() - EVENT_JOYSTICK.size(), - EVENT_JOYSTICK.size(), EVENT_JOYSTICK) == 0) + // Check if the entry starts with event (a 5-letter word) + if (et.name.size() > 5 && et.name.compare(0, 5,"event") == 0) { - joy_paths.emplace_back(fmt::format("/dev/input/by-path/%s", et.name)); + int fd = open(("/dev/input/" + et.name).c_str(), O_RDONLY|O_NONBLOCK); + struct libevdev *dev = NULL; + int rc = 1; + rc = libevdev_new_from_fd(fd, &dev); + if (rc < 0) + { + // If it's just a bad file descriptor, don't bother logging, but otherwise, log it. + if (rc == -9) + LOG_WARNING(GENERAL, "Failed to connect to device at %s, the error was: %s", "/dev/input/" + et.name, strerror(-rc)); + continue; + } + if (libevdev_has_event_type(dev, EV_KEY) && + libevdev_has_event_code(dev, EV_ABS, ABS_X) && + libevdev_has_event_code(dev, EV_ABS, ABS_Y)) + { + // It's a joystick. + joy_paths.emplace_back(fmt::format("/dev/input/%s", et.name)); + } } } @@ -61,6 +75,7 @@ void evdev_joystick_handler::Init(const u32 max_connect) { joy_devs.push_back(nullptr); joy_axis_maps.emplace_back(ABS_RZ - ABS_X, -1); + joy_axis.emplace_back(ABS_RZ - ABS_X, -1); joy_button_maps.emplace_back(KEY_MAX - BTN_JOYSTICK, -1); joy_hat_ids.emplace_back(-1); m_pads.emplace_back( @@ -111,6 +126,36 @@ void evdev_joystick_handler::update_devs() m_info.now_connect = connected; } +inline u16 Clamp0To255(f32 input) +{ + if (input > 255.f) + return 255; + else if (input < 0.f) + return 0; + else return static_cast(input); +} + +std::tuple evdev_joystick_handler::ConvertToSquirclePoint(u16 inX, u16 inY) +{ + // convert inX and Y to a (-1, 1) vector; + const f32 x = (inX - 127) / 127.f; + const f32 y = ((inY - 127) / 127.f); + + // compute angle and len of given point to be used for squircle radius + const f32 angle = std::atan2(y, x); + const f32 r = std::sqrt(std::pow(x, 2.f) + std::pow(y, 2.f)); + + // now find len/point on the given squircle from our current angle and radius in polar coords + // https://thatsmaths.com/2016/07/14/squircles/ + const f32 newLen = (1 + std::pow(std::sin(2 * angle), 2.f) / (g_evdev_joystick_config.squirclefactor / 1000.f)) * r; + + // we now have len and angle, convert to cartisian + + const int newX = Clamp0To255(((newLen * std::cos(angle)) + 1) * 127); + const int newY = Clamp0To255(((newLen * std::sin(angle)) + 1) * 127); + return std::tuple(newX, newY); +} + bool evdev_joystick_handler::try_open_dev(u32 index) { libevdev*& dev = joy_devs[index]; @@ -395,8 +440,33 @@ void evdev_joystick_handler::thread_func() LOG_ERROR(GENERAL, "Joystick #%d sent axis event for invalid axis %d", i, axis); break; } - - pad.m_sticks[axis].m_value = scale_axis(evt.code, evt.value); + + if (g_evdev_joystick_config.squirclejoysticks) + { + joy_axis[i][axis] = evt.value; + if (evt.code == ABS_X || evt.code == ABS_Y) + { + int Xaxis = joy_axis_maps[i][ABS_X]; + int Yaxis = joy_axis_maps[i][ABS_Y]; + pad.m_sticks[Xaxis].m_value = scale_axis(ABS_X, joy_axis[i][Xaxis]); + pad.m_sticks[Yaxis].m_value = scale_axis(ABS_Y, joy_axis[i][Yaxis]); + + std::tie(pad.m_sticks[Xaxis].m_value, pad.m_sticks[Yaxis].m_value) = + ConvertToSquirclePoint(pad.m_sticks[Xaxis].m_value, pad.m_sticks[Yaxis].m_value); + } + else + { + int Xaxis = joy_axis_maps[i][ABS_RX]; + int Yaxis = joy_axis_maps[i][ABS_RY]; + pad.m_sticks[Xaxis].m_value = scale_axis(ABS_RX, joy_axis[i][Xaxis]); + pad.m_sticks[Yaxis].m_value = scale_axis(ABS_RY, joy_axis[i][Yaxis]); + + std::tie(pad.m_sticks[Xaxis].m_value, pad.m_sticks[Yaxis].m_value) = + ConvertToSquirclePoint(pad.m_sticks[Xaxis].m_value, pad.m_sticks[Yaxis].m_value); + } + } + else + pad.m_sticks[axis].m_value = scale_axis(evt.code, evt.value); } break; default: diff --git a/rpcs3/evdev_joystick_handler.h b/rpcs3/evdev_joystick_handler.h index 30e8a9a12052..5737be6f684c 100644 --- a/rpcs3/evdev_joystick_handler.h +++ b/rpcs3/evdev_joystick_handler.h @@ -8,7 +8,6 @@ #include #include - enum { EVDEV_DPAD_HAT_AXIS_X = -1, EVDEV_DPAD_HAT_AXIS_Y = -2 }; struct evdev_joystick_config final : cfg::node @@ -45,6 +44,8 @@ struct evdev_joystick_config final : cfg::node cfg::_bool lyreverse{this, "Reverse left stick Y axis", false}; cfg::_bool axistrigger{this, "Z axis triggers", true}; + cfg::_bool squirclejoysticks{this, "Squircle Joysticks", true}; + cfg::int32 squirclefactor{this, "Squircle Factor", 5000}; bool load() { @@ -74,6 +75,7 @@ class evdev_joystick_handler final : public PadHandlerBase private: void update_devs(); + std::tuple ConvertToSquirclePoint(u16 inX, u16 inY); bool try_open_dev(u32 index); int scale_axis(int axis, int value); void thread_func(); @@ -84,6 +86,8 @@ class evdev_joystick_handler final : public PadHandlerBase std::vector joy_devs; std::vector> joy_button_maps; std::vector> joy_axis_maps; + // joy_axis is only used for squircling + std::vector> joy_axis; std::vector joy_hat_ids; bool axistrigger; std::map> axis_ranges; diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 8e56bb924b37..ca6e0fb42da9 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -116,7 +116,7 @@ void main_window::Init() fs::stat_t st; if (!fs::stat(fs::get_config_dir() + "rpcs3.pdb", st) || st.is_directory || st.size < 1024 * 1024 * 100) #else - if (true) + if (false) #endif { QMessageBox msg;