Skip to content

Commit

Permalink
Add user-bindable keyboard hotkeys
Browse files Browse the repository at this point in the history
  • Loading branch information
oneup03 committed Jun 12, 2024
1 parent f55b34e commit aa72d7c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 33 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,19 @@ Windows-only solution, but there are other solutions on Linux like MonadoVR.
| `convergence` | `float` | Where the left and right images converge. Adjusts frustum. | `0.1` |
| `tab_enable` | `bool` | Enable or disable top-and-bottom (TaB) 3D output (Side by Side is default) | `false` |
| `half_enable` | `bool` | Enable or disable half SbS/TaB 3D output. | `true` |
| `reverse_enable` | `bool` | Flip Left and Right eyes. | `false` |
| `reverse_enable` | `bool` | Enable or disable reversed 3D output. | `false` |
| `ss_enable` | `bool` | Enable or disable supersampling. | `false` |
| `hdr_enable` | `bool` | Enable or disable HDR rendering. | `false` |
| `ss_scale` | `float` | The supersampling scale factor. | `1.0` |
| `display_latency` | `float` | The latency from V-Sync to photons hitting the display, in seconds. | `0.011` |
| `hdr_enable` | `bool` | Enable or disable HDR. | `false` |
| `depth_gauge` | `bool` | Enable or disable SteamVR IPD depth gauge display. | `false` |
| `ss_scale` | `float` | The supersample scale. | `1.0` |
| `display_latency` | `float` | The display latency in seconds. | `0.011` |
| `display_frequency` | `float` | The display refresh rate, in Hz. | `60.0` |
| `num_user_settings` | `int` | The number of user settings defined below. | `3` |
| `user_load_key#` | `string`| The [Hexadecimal Virtual-Key Code](https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) to load user setting # (replace # with integer number) | `"0x61"` |
| `user_store_key#` | `string`| The Hexadecimal Virtual-Key Code to store user setting # (replace # with integer number) | `"0x64"` |
| `user_depth#` | `float` | The depth value for user setting # (replace # with integer number) | `0.5` |
| `user_convergence#` | `float` | The convergence value for user setting # (replace # with integer number) | `0.1` |
| `user_hold#` | `bool` | User setting # (replace # with integer number) requires holding the button | `false` |


## Installation
Expand Down Expand Up @@ -54,6 +61,13 @@ Windows-only solution, but there are other solutions on Linux like MonadoVR.
- Several mods/games may override your supersample and other settings
- DLSS, TAA, and other temporal based settings often create a halo around objects. UEVR has a halo fix that lets you use TAA, but others may not
- Depth and Convergence are saved to your `Steam\config\steamvr.vrsettings` when SteamVR is closed. There are only global settings, no per-game ones.
- User Depth and Convergence Binds
- The `num_user_settings` field must match the number of user defined configurations
- Each configuration's Field Names should end with an integer, starting from 1
- Currently keyboard binds can be setup using Microsoft's Virtual-Key Codes
- A Load key and a Store key can be configured to load and save Depth and Convergence settings for a configuration set
- All User Depth and Convergence settings will be saved to `Steam\config\steamvr.vrsettings` when SteamVR is closed
- If a User Depth and Convergence setting is in `Steam\config\steamvr.vrsettings` then it will override `Steam\steamapps\common\SteamVR\drivers\vrto3d\resources\settings\default.vrsettings`


## Building
Expand Down
78 changes: 53 additions & 25 deletions vrto3d/src/hmd_device_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ MockControllerDeviceDriver::MockControllerDeviceDriver()
display_configuration.user_store_key.resize(display_configuration.num_user_settings);
display_configuration.user_depth.resize(display_configuration.num_user_settings);
display_configuration.user_convergence.resize(display_configuration.num_user_settings);
display_configuration.user_hold.resize(display_configuration.num_user_settings);
display_configuration.was_held.resize(display_configuration.num_user_settings);
for (int i = 0; i < display_configuration.num_user_settings; i++)
{
char user_key[1024];
Expand All @@ -64,13 +66,16 @@ MockControllerDeviceDriver::MockControllerDeviceDriver()
display_configuration.user_depth[i] = vr::VRSettings()->GetFloat(stereo_display_settings_section, temp.c_str());
temp = "user_convergence" + std::to_string(i + 1);
display_configuration.user_convergence[i] = vr::VRSettings()->GetFloat(stereo_display_settings_section, temp.c_str());
temp = "user_hold" + std::to_string(i + 1);
display_configuration.user_hold[i] = vr::VRSettings()->GetBool(stereo_display_settings_section, temp.c_str());
}

display_configuration.tab_enable = vr::VRSettings()->GetBool(stereo_display_settings_section, "tab_enable");
display_configuration.half_enable = vr::VRSettings()->GetBool(stereo_display_settings_section, "half_enable");
display_configuration.reverse_enable = vr::VRSettings()->GetBool(stereo_display_settings_section, "reverse_enable");
display_configuration.ss_enable = vr::VRSettings()->GetBool(stereo_display_settings_section, "ss_enable");
display_configuration.hdr_enable = vr::VRSettings()->GetBool(stereo_display_settings_section, "hdr_enable");
display_configuration.depth_gauge = vr::VRSettings()->GetBool(stereo_display_settings_section, "depth_gauge");

display_configuration.ss_scale = vr::VRSettings()->GetFloat(stereo_display_settings_section, "ss_scale");
display_configuration.display_latency = vr::VRSettings()->GetFloat(stereo_display_settings_section, "display_latency");
Expand Down Expand Up @@ -117,6 +122,14 @@ vr::EVRInitError MockControllerDeviceDriver::Activate( uint32_t unObjectId )
vr::VRProperties()->SetBoolProperty( container, vr::Prop_HasDriverDirectModeComponent_Bool, false);
vr::VRProperties()->SetBoolProperty( container, vr::Prop_Hmd_SupportsHDR10_Bool, stereo_display_component_->GetConfig().hdr_enable);
vr::VRProperties()->SetBoolProperty( container, vr::Prop_Hmd_AllowSupersampleFiltering_Bool, stereo_display_component_->GetConfig().ss_enable);
if (stereo_display_component_->GetConfig().depth_gauge)
{
vr::VRProperties()->SetFloatProperty(container, vr::Prop_DashboardScale_Float, 1.0f);
}
else
{
vr::VRProperties()->SetFloatProperty(container, vr::Prop_DashboardScale_Float, 0.0f);
}

// Set the chaperone JSON property
// Get the current time
Expand Down Expand Up @@ -273,14 +286,14 @@ void MockControllerDeviceDriver::PoseUpdateThread()
while ( is_active_ )
{
// Get the state of the first controller (index 0)
DWORD dwResult = XInputGetState(0, &state);
if (dwResult == ERROR_SUCCESS) {
// Controller is connected
// Check the state of the buttons
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) {
stereo_display_component_->AdjustDepth(0.001f, true, device_index_);
}
}
//DWORD dwResult = XInputGetState(0, &state);
//if (dwResult == ERROR_SUCCESS) {
// // Controller is connected
// // Check the state of the buttons
// if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) {
// stereo_display_component_->AdjustDepth(0.001f, true, device_index_);
// }
//}

// Inform the vrserver that our tracked device's pose has updated, giving it the pose returned by our GetPose().
vr::VRServerDriverHost()->TrackedDevicePoseUpdated( device_index_, GetPose(), sizeof( vr::DriverPose_t ) );
Expand All @@ -303,19 +316,7 @@ void MockControllerDeviceDriver::PoseUpdateThread()
}

// Check User binds
for (int i = 0; i < stereo_display_component_->GetConfig().num_user_settings; i++)
{
if (GetAsyncKeyState(stereo_display_component_->GetConfig().user_load_key[i]) & 0x8000)
{
stereo_display_component_->AdjustDepth(stereo_display_component_->GetConfig().user_depth[i], false, device_index_);
stereo_display_component_->AdjustConvergence(stereo_display_component_->GetConfig().user_convergence[i], false, device_index_);
}

if (GetAsyncKeyState(stereo_display_component_->GetConfig().user_store_key[i]) & 0x8000)
{
stereo_display_component_->SaveUserSetting(i);
}
}
stereo_display_component_->CheckUserSettings(device_index_);

// Update our pose every 30 milliseconds.
std::this_thread::sleep_for( std::chrono::milliseconds( 30 ) );
Expand Down Expand Up @@ -552,10 +553,37 @@ float StereoDisplayComponent::GetConvergence()


//-----------------------------------------------------------------------------
// Purpose: Store current Depth and Convergence into user setting i
// Purpose: Check User Settings and act on them
//-----------------------------------------------------------------------------
void StereoDisplayComponent::SaveUserSetting(int i)
void StereoDisplayComponent::CheckUserSettings(uint32_t device_index)
{
config_.user_depth[i] = GetDepth();
config_.user_convergence[i] = GetConvergence();
for (int i = 0; i < config_.num_user_settings; i++)
{
// Load stored convergence
if (GetAsyncKeyState(config_.user_load_key[i]) & 0x8000)
{
// Used for holding a setting briefly
if (config_.user_hold[i] && !config_.was_held[i])
{
prev_depth_ = GetDepth();
prev_conv_ = GetConvergence();
config_.was_held[i] = true;
}
AdjustDepth(config_.user_depth[i], false, device_index);
AdjustConvergence(config_.user_convergence[i], false, device_index);
}
// Release depth&convergence back to normal
else if (config_.user_hold[i] && config_.was_held[i])
{
config_.was_held[i] = false;
AdjustDepth(prev_depth_, false, device_index);
AdjustConvergence(prev_conv_, false, device_index);
}
// Store current depth&convergence to user setting
if (GetAsyncKeyState(config_.user_store_key[i]) & 0x8000)
{
config_.user_depth[i] = GetDepth();
config_.user_convergence[i] = GetConvergence();
}
}
}
8 changes: 7 additions & 1 deletion vrto3d/src/hmd_device_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ struct StereoDisplayDriverConfiguration
std::vector<int32_t> user_store_key;
std::vector<float> user_depth;
std::vector<float> user_convergence;
std::vector<bool> user_hold;
std::vector<bool> was_held;

bool tab_enable;
bool half_enable;
bool reverse_enable;
bool ss_enable;
bool hdr_enable;
bool depth_gauge;

float ss_scale;
float display_latency;
Expand All @@ -69,12 +72,15 @@ class StereoDisplayComponent : public vr::IVRDisplayComponent
void AdjustConvergence(float new_conv, bool is_delta, uint32_t device_index);
float GetDepth();
float GetConvergence();
void SaveUserSetting(int i);
void CheckUserSettings(uint32_t device_index);

private:
StereoDisplayDriverConfiguration config_;
std::atomic< float > depth_;
std::atomic< float > convergence_;

float prev_depth_;
float prev_conv_;
};

//-----------------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions vrto3d/vrto3d.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@
<Project>{89689a91-fb38-4893-ba67-3d6f45eb2712}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\.github\workflows\Build.yml" />
<None Include="..\README.md" />
<None Include="vrto3d\resources\settings\default.vrsettings" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
14 changes: 11 additions & 3 deletions vrto3d/vrto3d/resources/settings/default.vrsettings
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@
"reverse_enable": false,
"ss_enable": false,
"hdr_enable": false,
"depth_gauge": false,
"ss_scale": 1.0,
"display_latency": 0.011,
"display_frequency": 60.0,
"num_user_settings": 2,
"num_user_settings": 3,
"user_load_key1": "0x61",
"user_store_key1": "0x64",
"user_depth1": 0.5,
"user_depth1": 1.0,
"user_convergence1": 0.1,
"user_hold1": true,
"user_load_key2": "0x62",
"user_store_key2": "0x65",
"user_depth2": 0.1,
"user_convergence2": 0.5
"user_convergence2": 0.5,
"user_hold2": false,
"user_load_key3": "0x63",
"user_store_key3": "0x66",
"user_depth3": 0.5,
"user_convergence3": 0.1,
"user_hold3": false
}
}

0 comments on commit aa72d7c

Please sign in to comment.