diff --git a/.gitignore b/.gitignore index 956d6ba..f54d7c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ Debug +Release .vs diff --git a/OrbiterSteamController/OrbiterSteamController.vcxproj b/OrbiterSteamController/OrbiterSteamController.vcxproj index c4db2ad..359de5d 100644 --- a/OrbiterSteamController/OrbiterSteamController.vcxproj +++ b/OrbiterSteamController/OrbiterSteamController.vcxproj @@ -31,20 +31,20 @@ MultiByte - Application + DynamicLibrary false v140 true MultiByte - Application + DynamicLibrary true v140 MultiByte - Application + DynamicLibrary false v140 true @@ -88,7 +88,14 @@ Level3 Disabled true + C:\Users\Administrator\Desktop\Orbitersdk\include;%(AdditionalIncludeDirectories) + MultiThreaded + + C:\Users\Administrator\Desktop\Orbitersdk\lib;%(AdditionalLibraryDirectories) + msvcirt.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + orbiter.lib;Orbitersdk.lib;Xinput9_1_0.lib;%(AdditionalDependencies) + @@ -97,10 +104,15 @@ true true true + C:\Users\Administrator\Desktop\Orbitersdk\include;%(AdditionalIncludeDirectories) + MultiThreaded true true + C:\Users\Administrator\Desktop\Orbitersdk\lib;%(AdditionalLibraryDirectories) + msvcirt.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + orbiter.lib;Orbitersdk.lib;Xinput9_1_0.lib;%(AdditionalDependencies) @@ -110,14 +122,23 @@ true true true + C:\Users\Administrator\Desktop\Orbitersdk\include;%(AdditionalIncludeDirectories) + MultiThreaded true true + C:\Users\Administrator\Desktop\Orbitersdk\lib;%(AdditionalLibraryDirectories) + msvcirt.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + orbiter.lib;Orbitersdk.lib;Xinput9_1_0.lib;%(AdditionalDependencies) + + + + diff --git a/OrbiterSteamController/OrbiterSteamController.vcxproj.filters b/OrbiterSteamController/OrbiterSteamController.vcxproj.filters index d5fe22c..3e9e016 100644 --- a/OrbiterSteamController/OrbiterSteamController.vcxproj.filters +++ b/OrbiterSteamController/OrbiterSteamController.vcxproj.filters @@ -18,5 +18,13 @@ Source Files + + Source Files + + + + + Header Files + \ No newline at end of file diff --git a/OrbiterSteamController/XinputController.cpp b/OrbiterSteamController/XinputController.cpp index 8ca90ce..9d46875 100644 --- a/OrbiterSteamController/XinputController.cpp +++ b/OrbiterSteamController/XinputController.cpp @@ -1,9 +1,90 @@ #include "XinputController.h" -XinputController::XinputController(int controllerNumber) -{ + +XinputController::XinputController() { + init(); +} + + +XinputController::~XinputController() { + +} + +void XinputController::init() { + setControllerNumber(); + updateState(); +} + +void XinputController::updateState() { + ZeroMemory(&state, sizeof(XINPUT_STATE)); + XInputGetState(controllerNumber, &state); +} + +int XinputController::getLX() { + updateState(); + return state.Gamepad.sThumbLX; +} + +int XinputController::getLY() { + updateState(); + return state.Gamepad.sThumbLY; +} + +int XinputController::getRX() { + updateState(); + return state.Gamepad.sThumbRX; +} + +int XinputController::getRY() { + updateState(); + return state.Gamepad.sThumbRY; } -XinputController::~XinputController() +int XinputController::getRT() { + updateState(); + return state.Gamepad.bRightTrigger; +} + +int XinputController::getLT() { + updateState(); + return state.Gamepad.bLeftTrigger; +} + +double XinputController::getNormLX() { + return max(-1, (double)getLX() / 32767); // Returns from -1 to 1 +} + +double XinputController::getNormLY() { + return max(-1, (double)getLY() / 32767); // Returns from -1 to 1 +} + +double XinputController::getNormRX() { + return max(-1, (double)getRX() / 32767); // Returns from -1 to 1 +} + +double XinputController::getNormRY() { + return max(-1, (double)getRY() / 32767); // Returns from -1 to 1 +} + +double XinputController::getNormRT() { + //return max(-1, (double)((getRT() - 128) / 127)); // Returns from -1 to 1 + return (double)getRT() / 255; // Returns from 0 to 1 +} + +double XinputController::getNormLT() { + //return max(-1, (double)((getLT() - 128) / 127)); // Returns from -1 to 1 + return (double)getLT() / 255; // Returns from 0 to 1 +} + +void XinputController::setControllerNumber() // Sets the controller to the first connected controller { + int controllerId = -1; + for (DWORD i = 0; i < XUSER_MAX_COUNT && controllerId == -1; i++) + { + ZeroMemory(&state, sizeof(XINPUT_STATE)); + + if (XInputGetState(i, &state) == ERROR_SUCCESS) + controllerId = i; + } + controllerNumber = controllerId; } diff --git a/OrbiterSteamController/XinputController.h b/OrbiterSteamController/XinputController.h index 41624de..14274ad 100644 --- a/OrbiterSteamController/XinputController.h +++ b/OrbiterSteamController/XinputController.h @@ -1,14 +1,32 @@ #pragma once +#include #include class XinputController { + int controllerNumber; + XINPUT_STATE state; - //XINPUT_STATE state; public: - XinputController(int controllerNumber); + XinputController(); ~XinputController(); + double getNormLX(); + double getNormLY(); + double getNormRX(); + double getNormRY(); + double getNormRT(); + double getNormLT(); +private: + void setControllerNumber(); + void init(); + void updateState(); + int getLX(); + int getLY(); + int getRX(); + int getRY(); + int getRT(); + int getLT(); }; diff --git a/OrbiterSteamController/main.cpp b/OrbiterSteamController/main.cpp index daf1b6f..303b2ec 100644 --- a/OrbiterSteamController/main.cpp +++ b/OrbiterSteamController/main.cpp @@ -1,82 +1,27 @@ #define STRICT #define ORBITER_MODULE -#include -#include +//#define DEBUG -int getFirstConnectedController(); -int getLX(int controller); +#include +#include "XinputController.h" -int firstConnectedController = -1; -XINPUT_STATE state; +XinputController controller; DLLCLBK void InitModule(HINSTANCE hModule) { - firstConnectedController = getFirstConnectedController(); + controller = XinputController(); } -DLLCLBK void opcPreStep(double simt, double simdt, double mjd) -{ - /*sprintf(oapiDebugString(), "%.2f", oapiGetSimTime());*/ - //firstConnectedController = getFirstConnectedController(); - sprintf(oapiDebugString(), "First Controller: %d", getLX(firstConnectedController)); +DLLCLBK void opcPreStep(double simt, double simdt, double mjd) { + #ifdef DEBUG + sprintf(oapiDebugString(), "LX: %f LY: %f LT+RT: %f RX: %f RY: %f", controller.getNormLX(), controller.getNormLY(), controller.getNormRT() + (controller.getNormLT() * -1), controller.getNormRX(), controller.getNormRY()); + #endif VESSEL* vessel = oapiGetFocusInterface(); - //vessel->SetADCtrlMode(DWORD(0)); - - vessel->SetControlSurfaceLevel(AIRCTRL_ELEVATOR, -1, false); -} - -int getFirstConnectedController() { - int controllerId = -1; - - for (DWORD i = 0; i < XUSER_MAX_COUNT && controllerId == -1; i++) - { - - ZeroMemory(&state, sizeof(XINPUT_STATE)); - - if (XInputGetState(i, &state) == ERROR_SUCCESS) - controllerId = i; - } - return controllerId; -} - -/*XINPUT_STATE updateControllerInputState() { - ZeroMemory(&state, sizeof(XINPUT_STATE)); - XInputGetState(firstConnectedController, &state); -}*/ - -int getLX(int controller) { - if (controller > -1) { - ZeroMemory(&state, sizeof(XINPUT_STATE)); - XInputGetState(controller, &state); - return state.Gamepad.sThumbLX; - } - else { - return -1; - } -} -int getLY(int controller) { - if (controller > -1) { - ZeroMemory(&state, sizeof(XINPUT_STATE)); - XInputGetState(controller, &state); - return state.Gamepad.sThumbLY; - } - else { - return -1; - } -} - + vessel->SetControlSurfaceLevel(AIRCTRL_ELEVATOR, controller.getNormLY() * -1, false); + vessel->SetControlSurfaceLevel(AIRCTRL_AILERON, controller.getNormLX(), false); + vessel->SetControlSurfaceLevel(AIRCTRL_RUDDER, controller.getNormRT() + (controller.getNormLT() * -1), false); -/* -int getLX() { - int controller = getFirstConnectedController(); - if (controller > -1) { - XINPUT_STATE state; - ZeroMemory(&state, sizeof(XINPUT_STATE)); - XInputGetState(controller, &state); - return state.Gamepad.sThumbLX; - } else { - return -1; - } + // An experiment with controlling the view with the RS directly. Not really needed as you can bind either pad to a mouse with the right button held down + //oapiCameraSetCockpitDir((roundf(controller.getNormRX() * 1000) / 1000) * -1, roundf(controller.getNormRY() * 1000) / 1000, false); } -*/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..5916b77 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# OrbiterSteamController + +## Intro + +I love the Steam Controller, however it presents itself to the running process directly as an xinput controller. Unfortunately this means Orbiter can't detect it during launch. + +This plugin detects the xinput controller presented by the Steam Controller and maps the analog inputs to the flight control surfaces. + +## Install + +Unzip the contents into your Orbiter install directory. + +## Setup + +1. Enable OrbiterSteamController in the Orbiter _Modules_ menu +2. Add Orbiter as a non-Steam game +3. Configure the controller in the Steam Overlay + * Configure the analog stick as _Joystick Move_ with Output set to _Left Joystick_ + * For the left and right triggers, configure the Trigger Analog Output as _Left Trigger_ and _Right Trigger_ respectively and disable Full Pull and Soft Pull Actions + +## Use + +The analog stick will now control pitch and roll. The left and right triggers will control yaw. + +## Additional Tips + +* Outside of the analog functions, you can configure almost everything else directly in the Steam Overlay by mapping keys to the Steam Controller. +* You can configure one of the pads as a mouse with a _Touch Binding_ of "RIGHT MOUSE" - and a click action of the _HOME_ key. This will give you a nice touchpad for changing your view, looking around in the cockpit.