Skip to content
This repository was archived by the owner on May 9, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLA.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ By adding your GitHub username to the list below, you agree to the following:
Add your GitHub username as a new entry at the end of the list. Do not alter other entries, and leave one blank line below yours.

- BOLL7708
- chaixshot
45 changes: 24 additions & 21 deletions SuperScreenShotterVR/MainController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Media;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Valve.VR;
using static EasyOpenVR.EasyOpenVRSingleton;
Expand All @@ -34,7 +34,7 @@ public class MainController
private Dictionary<uint, ScreenshotData> _screenshotQueue = new Dictionary<uint, ScreenshotData>();
private uint _lastScreenshotHandle = 0;
private bool _shouldShutDown = false;
private MediaPlayer? _mediaPlayer;
private SoundPlayer? _mediaPlayer;
private string _currentAudio = string.Empty;
private Stopwatch _stopWatch = new Stopwatch();

Expand All @@ -51,7 +51,7 @@ public class MainController
private OverlayTextureSize _reticleTextureSize = new OverlayTextureSize();
private float _displayFrequency = 90f; // Used for how often we should move the overlay to react to the headset.
private bool _overlayIsVisible = false;
private float _screenshotFoV = 0;
private float _screenshotFoV = 100;

private SuperServer _server = new SuperServer();

Expand All @@ -65,7 +65,7 @@ public void Init()
StatusUpdateAction.Invoke(false);
AppUpdateAction.Invoke("");

_mediaPlayer = new MediaPlayer();
_mediaPlayer = new SoundPlayer();

_workerThread = new Thread(WorkerThread);
_workerThread.Start();
Expand Down Expand Up @@ -288,8 +288,10 @@ private void UpdateDisplayFrequency()
private void UpdateTrackedDeviceIndex()
{
var indexes = _ovr.GetIndexesForTrackedDeviceClass(ETrackedDeviceClass.HMD);
float fov = _ovr.GetFloatTrackedDeviceProperty(_trackedDeviceIndex, ETrackedDeviceProperty.Prop_ScreenshotHorizontalFieldOfViewDegrees_Float);

if (indexes.Length > 0) _trackedDeviceIndex = indexes[0];
_screenshotFoV = _ovr.GetFloatTrackedDeviceProperty(_trackedDeviceIndex, ETrackedDeviceProperty.Prop_ScreenshotHorizontalFieldOfViewDegrees_Float);
if (fov > 0) _screenshotFoV = fov;
}

private void ToggleViewfinder(bool visible)
Expand Down Expand Up @@ -461,23 +463,19 @@ private void ShutdownIfWeShould()

private void PlayScreenshotSound(bool onlyLoad = false)
{
_mediaPlayer ??= new MediaPlayer();
_mediaPlayer.Dispatcher.Invoke(() => // Always execute tasks on the media player on the thread it was initiated.
_mediaPlayer ??= new SoundPlayer();
if (_currentAudio != _settings.CustomAudio)
{
if (_currentAudio != _settings.CustomAudio)
_currentAudio = _settings.CustomAudio;
if (_currentAudio != string.Empty && File.Exists(_currentAudio))
{
_currentAudio = _settings.CustomAudio;
if (_currentAudio != string.Empty && File.Exists(_currentAudio))
{
_mediaPlayer.Open(new Uri(_currentAudio));
}
_mediaPlayer.SoundLocation = _currentAudio;
}
}

if (onlyLoad) return true;
_mediaPlayer.Stop();
_mediaPlayer.Play();
return true;
});
if (onlyLoad) return;
_mediaPlayer.Stop();
_mediaPlayer.Play();
}

private class ScreenshotData {
Expand Down Expand Up @@ -522,15 +520,20 @@ private uint TakeScreenshot(bool byUser = true, ScreenshotMessage? screenshotMes
private void TakeDelayedScreenshot(bool shouldTrigger = true, ScreenshotMessage screenshotMessage = null)
{
if (!shouldTrigger) return;

if (_currentAppId.Equals(string.Empty)) return; // There needs to be a running application

ToggleViewfinder(true);
var delay = _settings.DelaySeconds;
if(screenshotMessage != null && screenshotMessage.Delay > 0)
{
delay = screenshotMessage.Delay;
}
Thread.Sleep(delay * 1000);
TakeScreenshot(true, screenshotMessage); // byUser set to true as time-lapse does not use delayed shots

System.Threading.Tasks.Task.Run(async () =>
{
Thread.Sleep(delay * 1000);
TakeScreenshot(true, screenshotMessage); // byUser set to true as time-lapse does not use delayed shots
});
}

private void ScreenShotTaken(VREvent_Data_t eventData)
Expand Down
3 changes: 3 additions & 0 deletions SuperScreenShotterVR/SuperScreenShotterVR.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<None Update="bindings_knuckles.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="bindings_oculus_touch.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Resource Include="resources\logo.ico" />
Expand Down
4 changes: 4 additions & 0 deletions SuperScreenShotterVR/actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"controller_type": "knuckles",
"binding_url": "bindings_knuckles.json"
},
{
"controller_type": "oculus_touch",
"binding_url": "bindings_oculus_touch.json"
},
{
"controller_type": "gamepad",
"binding_url": "bindings_gamepad.json"
Expand Down
65 changes: 65 additions & 0 deletions SuperScreenShotterVR/bindings_oculus_touch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"action_manifest_version": 0,
"alias_info": {},
"app_key": "boll7708.superscreenshottervr",
"bindings": {
"/actions/screenshots": {
"chords": [
{
"inputs": [
[ "/user/hand/left/input/system", "touch" ]
],
"output": "/actions/screenshots/in/show_viewfinder"
},
{
"inputs": [
[ "/user/hand/left/input/system", "touch" ],
[ "/user/hand/left/input/trigger", "click" ]
],
"output": "/actions/screenshots/in/take_screenshot"
},
{
"inputs": [
[ "/user/hand/right/input/system", "touch" ]
],
"output": "/actions/screenshots/in/show_viewfinder"
},
{
"inputs": [
[ "/user/hand/right/input/system", "touch" ],
[ "/user/hand/right/input/trigger", "click" ]
],
"output": "/actions/screenshots/in/take_screenshot"
}
],
"sources": [
{
"inputs": {},
"mode": "button",
"path": "/user/hand/left/input/trigger"
},
{
"inputs": {},
"mode": "button",
"path": "/user/hand/right/input/trigger"
},
{
"inputs": {},
"mode": "button",
"path": "/user/hand/left/input/system"
},
{
"inputs": {},
"mode": "button",
"path": "/user/hand/right/input/system"
}
]
}
},
"category": "steamvr_input",
"controller_type": "oculus_touch",
"description": "Default Oculus Touch Bindings",
"name": "Default SuperScreenShotterVR configuration for Oculus Touch",
"options": {},
"simulated_actions": []
}