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.