diff --git a/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp b/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp index ab8f46acc4..862640c239 100644 --- a/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp +++ b/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp @@ -1,5 +1,5 @@ -#include "SimJoyStick.h" - +#include "SimJoyStick.h" + #if defined _WIN32 || defined _WIN64 #include "common/common_utils/StrictMode.hpp" @@ -12,7 +12,7 @@ STRICT_MODE_OFF //Below is old way of doing it? //#include "AllowWindowsPlatformTypes.h" //#define WIN32_LEAN_AND_MEAN -//#define NOMINMAX +//#define NOMINMAX //#include //#include //#include "HideWindowsPlatformTypes.h" @@ -63,28 +63,158 @@ struct SimJoyStick::impl { #else +#include +#include +#include +#include +#include +#include "unistd.h" + //implementation for unsupported OS struct SimJoyStick::impl { +private: + + + + class JoystickEvent + { + public: + /** Minimum value of axes range */ + static const short MIN_AXES_VALUE = -32768; + + /** Maximum value of axes range */ + static const short MAX_AXES_VALUE = 32767; + + /** + * The timestamp of the event, in milliseconds. + */ + unsigned int time; + + /** + * The value associated with this joystick event. + * For buttons this will be either 1 (down) or 0 (up). + * For axes, this will range between MIN_AXES_VALUE and MAX_AXES_VALUE. + */ + short value; + + /** + * The event type. + */ + unsigned char type; + + /** + * The axis/button number. + */ + unsigned char number; + + /** + * Returns true if this event is the result of a button press. + */ + bool isButton() + { + static constexpr unsigned char JS_EVENT_BUTTON = 0x01; // button pressed/released + return (type & JS_EVENT_BUTTON) != 0; + } + + /** + * Returns true if this event is the result of an axis movement. + */ + bool isAxis() + { + static constexpr unsigned char JS_EVENT_AXIS = 0x02; // joystick moved + return (type & JS_EVENT_AXIS) != 0; + } + + /** + * Returns true if this event is part of the initial state obtained when + * the joystick is first connected to. + */ + bool isInitialState() + { + static constexpr unsigned char JS_EVENT_INIT = 0x80; // initial state of device + return (type & JS_EVENT_INIT) != 0; + } + + /** + * The ostream inserter needs to be a friend so it can access the + * internal data structures. + */ + friend std::ostream& operator<<(std::ostream& os, const JoystickEvent& e); + }; + + public: + ~impl() + { + if (fd_ >= 0) + close(fd_); + } + void getJoyStickState(unsigned int index, SimJoyStick::State& state) { - //not implemented - state.is_connected = false; + static constexpr bool blocking = false; + + if (index != last_index_) { + if (fd_ >= 0) + close(fd_); + + std::stringstream devicePath; + devicePath << "/dev/input/js" << index; + + fd_ = open(devicePath.str().c_str(), blocking ? O_RDONLY : O_RDONLY | O_NONBLOCK); + + last_index_ = index; + } + + if (fd_ >= 0) { + int bytes = read(fd_, &event_, sizeof(event_)); + + if (bytes == -1 || bytes != sizeof(event_)) { + // NOTE if this condition is not met, we're probably out of sync and this + // Joystick instance is likely unusable + state.is_connected = false; + } + else { + state.is_connected = true; + + if (event_.isButton()) { + if (event_.value == 0) + state.buttons &= ~(1 << event_.number); + else + state.buttons |= (1 << event_.number); + } + else if (event_.isAxis()) { + switch(event_.number) { + case 0: state.left_y = event_.value; break; + case 1: state.right_x = event_.value; break; + case 2: state.right_y = event_.value; break; + case 3: state.left_x = event_.value; break; + default: break; + } + } + //else ignore + } + } } + +private: + unsigned int last_index_ = -1; + int fd_ = -1; + JoystickEvent event_; }; #endif bool SimJoyStick::initialized_success_ = false; -void SimJoyStick::setInitializedSuccess(bool success) -{ - initialized_success_ = success; +void SimJoyStick::setInitializedSuccess(bool success) +{ + initialized_success_ = success; +} +bool SimJoyStick::isInitializedSuccess() +{ + return initialized_success_; } -bool SimJoyStick::isInitializedSuccess() -{ - return initialized_success_; -} SimJoyStick::SimJoyStick() { diff --git a/docs/linux_build.md b/docs/linux_build.md index 7dbffe8176..4baa926c3c 100644 --- a/docs/linux_build.md +++ b/docs/linux_build.md @@ -11,7 +11,7 @@ It's super simple 1-2-3! 2. Clone Unreal in your favorite folder and run setup.sh (this may take a while!). Note: We only support Unreal 4.16 and newer. ``` # go to folder where you clone GitHub projects - git clone -b 4.16 https://github.com/EpicGames/UnrealEngine.git + git clone -b 4.17 https://github.com/EpicGames/UnrealEngine.git cd UnrealEngine ./Setup.sh ./GenerateProjectFiles.sh diff --git a/install_run_all.sh b/install_run_all.sh index 44402037ed..d659e327de 100644 --- a/install_run_all.sh +++ b/install_run_all.sh @@ -23,7 +23,7 @@ fi #install unreal if [[ !(-d "$UnrealDir") ]]; then - git clone -b 4.16 https://github.com/EpicGames/UnrealEngine.git "$UnrealDir" + git clone -b 4.17 https://github.com/EpicGames/UnrealEngine.git "$UnrealDir" pushd "$UnrealDir" >/dev/null ./Setup.sh