Skip to content
Merged
29 changes: 25 additions & 4 deletions DeusExHRVR.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ MotionControls=1
ImmersiveScope=0
ScopeMagnification=4

; Left thumbstick click waits this long (ms) before a hold registers, so the
; two-stick weapon calibration chord doesn't also crouch. 0 sends it at once,
; for layouts that map the left click to something other than crouch.
LeftStickClickDelayMs=150

; Independent directions: Mouse, Headset, or Controller (right-hand aim).
; Mouse retains native mouse/gamepad look direction. Restart after editing.
; Interaction selects doors/items; it does not change weapon aiming.
Expand Down Expand Up @@ -66,6 +71,16 @@ StanceHold=0
; transition speed.
StanceHoldTrigger=60

; Optional: keep the camera on the player's own path instead of following the
; run animation's side-to-side sway (about 1 cm, once per step). The value is
; the averaging window in milliseconds; 667 is one running stride. 0 disables.
SideSwayHoldMs=0

; Optional stutter fix from HRDCfix (github.com/imring/HRDCfix): a wait loop
; in the game sleeps a whole Windows timer tick (~15 ms) at a time; 1 makes it
; only yield instead. Needs no ASI loader when applied here.
SleepFix=0

; Optional filtering of the walk animation's left-right heading swing, in
; milliseconds; 0 disables each stage. Two cascaded stages (walking, then a
; second rhythm for sprinting). Needs YawOnlyCamera=1 to take effect.
Expand All @@ -90,8 +105,13 @@ SnapTurnMouseCounts=300
; The game ignores mouse look while the left stick is deflected, so walking is
; released for at most this long around the injected move.
SnapTurnPauseMs=60
; With SnapTurn=1 the right stick's vertical axis is free: RightStickUp and
; RightStickDown under [Buttons] hold a target while it is pushed up or down.
; Snap turn's mouse move brings up the PC quickbar. 1 turns on the game's own
; quickbar auto-hide (the tilde key) whenever gameplay starts; 0 leaves that
; setting alone.
SnapTurnHideQuickBar=1
; RightStickUp and RightStickDown under [Buttons] hold a target while the right
; stick is pushed up or down during gameplay. With SnapTurn=0, setting either one
; takes the stick's vertical axis for them; smooth turning keeps the horizontal.

; Optional button layout. [Buttons] applies to gameplay and scoped aiming,
; [ScreenButtons] to everything else: the title and pause menus, the in-game
Expand All @@ -100,8 +120,9 @@ SnapTurnPauseMs=60
; Omitted entries keep the stock layout. Inputs: RightA, RightB, LeftX, LeftY,
; LeftGrip, RightGrip, LeftStickClick, RightStickClick, LeftTrigger,
; RightTrigger. Targets: A B X Y LB RB LS RS LT RT Back Start DPadUp DPadDown
; DPadLeft DPadRight None. <Input>HoldMs=250 delays the target until the input
; has been held that long; with a delay set, <Input>Tap=A sends a short pulse
; DPadLeft DPadRight QuickSave None. QuickSave presses F5, the game's quicksave
; key, which has no gamepad binding. <Input>HoldMs=250 delays the target until
; the input has been held that long; with a delay set, <Input>Tap=A sends a short pulse
; when the input is released early.
[Buttons]

Expand Down
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Set `MotionControls=0` under `[VR]` to disable all motion-controller features, i

To adjust a weapon's grip, use full VR with motion-controlled weapons enabled and keep the weapon out of scope mode. Press both thumbsticks and hold for one second, until the gun stops following your hand (a system tone also signals this). Keep holding and move/rotate your right controller into the grip position you want. Release either thumbstick to save, then release the other. Each weapon type keeps its own position and rotation offset in `DeusExHRVR-weapons.ini` beside the game executable, including across restarts. The gun, firing line, muzzle effects and immersive scope share that offset. Repeat to readjust; delete that file while the game is closed to reset all weapons.

The calibration gesture consumes controller movement, turning, firing and button actions until both sticks are released. Left-stick crouch has a 150 ms grace period to allow the two clicks to arrive together; a quick tap still crouches. Tracking loss, menus, recentering or weapon changes cancel an unfinished calibration. Install the matching game DLL and host together: this build uses transport version 5.
The calibration gesture consumes controller movement, turning, firing and button actions until both sticks are released. Left-stick crouch has a 150 ms grace period to allow the two clicks to arrive together; a quick tap still crouches. `LeftStickClickDelayMs` under `[VR]` sets that period; `0` sends the left click at once, for layouts that map it to something other than crouch. Tracking loss, menus, recentering or weapon changes cancel an unfinished calibration. Install the matching game DLL and host together: this build uses transport version 5.

`ImmersiveScope=1` optionally keeps native scoped weapons in full VR. With motion-controlled weapons enabled, raise the right controller near your eye and point forward to enter the scope; lower it to exit. The magnified view follows controller aim, using the rifle's firing line as a shared optical viewpoint for both eyes. `ScopeMagnification=4` controls zoom (1-12). This alignment has been tested in-headset with the sniper rifle. The default remains the automatic virtual screen (`ImmersiveScope=0`). Restart after changing these settings.

Expand Down Expand Up @@ -139,6 +139,10 @@ Measured against the player entity over 9000 frames on the supported build: the

Holding the height instead makes gait offsets and walking bob invisible, while a real stance change - crouched and standing differ by about 300 units - is followed at the speed of the game's own crouch/stand transition (about 1000 units/s, measured) until the camera settles. `StanceHoldTrigger` separates the two: gait offsets are 15-25 units and walking bob is about 2. Defaults to `0`. Ladders, cover, vaulting and elevators have not been tested with it yet.

`SideSwayHoldMs` under `[VR]` does the same for sideways motion. While running, the game sways the camera side to side relative to the player's own position, about 1 cm peak to peak, once per step and once per stride, while the body itself travels straight (measured over two 46-second runs; standing, the camera sits exactly on the body, and running leans it about 3 cm forward). With `SideSwayHoldMs=667` - one running stride - the VR camera stays on the player's path at the camera's average offset over the last 667 ms, which cancels the sway without lag because that offset barely changes while moving; in the measured runs it removed about 85-90% of the stride sway and nearly all of the step sway. It also removes the camera's step-by-step forward-and-back surge relative to the body, since the body's own path is the smoother of the two. Offsets larger than 15 cm (camera cuts, cover and similar) pass through untouched, and the VR camera is never held more than 4 cm from the game's camera, so deliberate camera moves can't lag behind. Defaults to `0` (off).

`SleepFix=1` under `[VR]` applies the stutter fix from [HRDCfix](https://github.com/imring/HRDCfix) by imring (MIT). One of the game's wait loops calls `Sleep(1)` while it waits; the game never raises the Windows timer resolution, so each call can last a whole timer tick (about 15.6 ms, nearly two frames at 120 Hz). The fix changes it to `Sleep(0)`, which only yields. Applying it from the VR mod avoids HRDCfix's DX11 ASI loader, which installs as `d3d11.dll` and would replace the mod's own proxy. The loop's bytes are checked before patching. Defaults to `0` (off).

Optional heading-swing filtering smooths the walk animation's left-right swing of the camera heading out of the VR view, without touching the game's own camera. It needs `YawOnlyCamera=1`. Each setting is a time window in milliseconds and defaults to `0` (off):

```ini
Expand All @@ -150,6 +154,21 @@ The filter reports the time-average of the heading over the last window, extrapo

`BobTrace=1` writes one line per frame to `DeusExHRVR-bob.csv` (camera position and heading, stick input, head pose; capped at 36000 lines) for measuring the walk animation on other hardware. The values above came from such a trace of walking and sprinting in the first hub. Tracing costs frame time - leave it at `0` for play.

`SnapTurn=1` under `[VR]` replaces the right stick's smooth camera turn during gameplay with a snap turn. A flick within 60 degrees of horizontal turns the view instantly by `SnapTurnDegrees` (default 30); the stick must return near center before the next flick. Menus, terminals and scoped aiming keep the native right stick.

The turn is one injected relative mouse move, which avoids the stick's acceleration ramp. `SnapTurnMouseCounts` is the size of that move; the mod measures the resulting heading change after each snap and writes a corrected value back to the INI, so it self-calibrates within a few turns from any starting value. The game appears to ignore mouse look while the gamepad left stick is deflected, so walking is released for up to `SnapTurnPauseMs` (default 60) around the injected move and resumed as soon as the camera has visibly turned.

The injected mouse move also brings up the game's keyboard-and-mouse quickbar (the PC item bar). The game's own quickbar auto-hide, the setting the tilde key toggles, keeps it hidden, so with `SnapTurn=1` the mod turns it on whenever gameplay starts. The setting is checked against the supported build before it is changed. `SnapTurnHideQuickBar=0` leaves it to you.

### Remapping buttons

To change what a motion-controller input sends:

1. Open `DeusExHRVR.ini` beside `DXHRDC.exe` (copy `DeusExHRVR.ini.example` there first if you don't have one).
2. Add a `[Buttons]` section for gameplay, a `[ScreenButtons]` section for everything else, or both.
3. Under it, add one line per input you want to change, in the form `Input=Target`, for example `LeftGrip=Y`.
4. Save the file and restart the game.

Motion-controller buttons can be remapped in `DeusExHRVR.ini` without touching the game's own bindings. `[Buttons]` applies during gameplay and scoped aiming; `[ScreenButtons]` applies to everything else: the title and pause menus, the in-game menu (map, objectives, inventory), the e-reader and news reader, terminals, hacking, videos, game over and loading screens, where one-handed use and a different Select/Back pairing are often easier. Any input not listed keeps the stock layout above. The in-game menu and the readers stay in tracked VR (snap turn still works over a reader); only their buttons follow `[ScreenButtons]`.

```ini
Expand All @@ -166,13 +185,9 @@ LeftTrigger=LT
RightTrigger=RT
```

Inputs are `RightA`, `RightB`, `LeftX`, `LeftY`, `LeftGrip`, `RightGrip`, `LeftStickClick`, `RightStickClick`, `LeftTrigger`, `RightTrigger`. Targets are `A`, `B`, `X`, `Y`, `LB`, `RB`, `LS`/`L3`, `RS`/`R3`, `LT`, `RT`, `Back`, `Start`, `DPadUp`, `DPadDown`, `DPadLeft`, `DPadRight`, or `None`. Triggers may be mapped to buttons and buttons to triggers. `<Input>HoldMs=250` makes that input send its target only after it has been held that long, so accidental taps send nothing; with a hold delay set, `<Input>Tap=A` sends a different target as a 120 ms pulse when the input is released early. Unrecognized names are logged and ignored. Restart after editing.

`SnapTurn=1` under `[VR]` replaces the right stick's smooth camera turn during gameplay with a snap turn. A flick within 60 degrees of horizontal turns the view instantly by `SnapTurnDegrees` (default 30); the stick must return near center before the next flick. Menus, terminals and scoped aiming keep the native right stick.

The turn is one injected relative mouse move, which avoids the stick's acceleration ramp. `SnapTurnMouseCounts` is the size of that move; the mod measures the resulting heading change after each snap and writes a corrected value back to the INI, so it self-calibrates within a few turns from any starting value. The game appears to ignore mouse look while the gamepad left stick is deflected, so walking is released for up to `SnapTurnPauseMs` (default 60) around the injected move and resumed as soon as the camera has visibly turned.
Inputs are `RightA`, `RightB`, `LeftX`, `LeftY`, `LeftGrip`, `RightGrip`, `LeftStickClick`, `RightStickClick`, `LeftTrigger`, `RightTrigger`, plus `RightStickUp` and `RightStickDown` in `[Buttons]` (below). Targets are `A`, `B`, `X`, `Y`, `LB`, `RB`, `LS`/`L3`, `RS`/`R3`, `LT`, `RT`, `Back`, `Start`, `DPadUp`, `DPadDown`, `DPadLeft`, `DPadRight`, `QuickSave`, or `None`. `QuickSave` presses F5, the game's quicksave key, which has no gamepad binding (for example `LeftXHoldMs=500` with `LeftXTap=QuickSave`). Triggers may be mapped to buttons and buttons to triggers. `<Input>HoldMs=250` makes that input send its target only after it has been held that long, so accidental taps send nothing; with a hold delay set, `<Input>Tap=A` sends a different target as a 120 ms pulse when the input is released early. Unrecognized names are logged and ignored. Restart after editing. The left menu button is not remappable: a tap sends Back (in-game menu) and a hold of 1.5 seconds sends Start (pause), as in the table above.

With `SnapTurn=1`, the right stick's vertical axis is free, so `RightStickUp` and `RightStickDown` under `[Buttons]` can hold a button while the stick is pushed within 30 degrees of vertical (for example `RightStickUp=A` to jump and `RightStickDown=LS` to crouch).
`RightStickUp` and `RightStickDown` under `[Buttons]` can hold a button while the right stick is pushed within 30 degrees of vertical during gameplay (for example `RightStickUp=A` to jump and `RightStickDown=LS` to crouch). This gives up vertical stick aiming, which you don't need when aiming with the controller (`ExperimentalMotionControls=1`). It works with snap turn or smooth turn. With `SnapTurn=0`, setting either key takes the stick's vertical axis for these buttons and leaves the horizontal axis for smooth turning; a push inside the 30-degree cone also holds the turn, so jumping or crouching doesn't drift the view. Menus, terminals and the scope keep the native right stick.

## Restore the original game

Expand Down
1 change: 1 addition & 0 deletions src/ControllerInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ControllerInput {
for(auto& a:action)a=XR_NULL_HANDLE;
mapper.Reset();
}
void SetLeftClickDelayMs(uint64_t ms){mapper.SetLeftClickDelay(ms);}
bool Init(XrInstance instance,XrSession session) {
XrActionSetCreateInfo set{XR_TYPE_ACTION_SET_CREATE_INFO};
strcpy_s(set.actionSetName,"motion_controller");strcpy_s(set.localizedActionSetName,"VR gamepad and weapon");
Expand Down
Loading
Loading