├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── dependabot.yml
├── .gitignore
├── DS4Windows
├── App.xaml
├── App.xaml.cs
├── ArgumentParser.cs
├── AutoProfileChecker.cs
├── AutoProfileHolder.cs
├── BezierCurveEditor
│ ├── BezierCurve.cs
│ ├── build.js
│ └── index.html
├── Changelog.json
├── Changelog.min.json
├── DS4Control
│ ├── ControlService.cs
│ ├── ControlServiceDeviceOptions.cs
│ ├── ControllerSlotManager.cs
│ ├── DS4LightBar.cs
│ ├── DS4OutDevice.cs
│ ├── DS4OutDevices
│ │ ├── DS4OutDeviceBasic.cs
│ │ ├── DS4OutDeviceExt.cs
│ │ ├── DS4OutDeviceExtras.cs
│ │ └── DS4OutDeviceFactory.cs
│ ├── DS4StateFieldMapping.cs
│ ├── HidHideAPIDevice.cs
│ ├── ITouchpadBehaviour.cs
│ ├── InputMethods.cs
│ ├── Log.cs
│ ├── MacroParser.cs
│ ├── Mapping.cs
│ ├── Mouse.cs
│ ├── MouseCursor.cs
│ ├── MouseWheel.cs
│ ├── OutSlotDevice.cs
│ ├── OutputDevice.cs
│ ├── OutputKBM
│ │ ├── FakerInputHandler.cs
│ │ ├── FakerInputMapping.cs
│ │ ├── SendInputHandler.cs
│ │ ├── SendInputMapping.cs
│ │ ├── VirtualKBMBase.cs
│ │ ├── VirtualKBMFactory.cs
│ │ └── VirtualKBMMapping.cs
│ ├── OutputSlotManager.cs
│ ├── OutputSlotPersist.cs
│ ├── PresetOption.cs
│ ├── ProfileMigration.cs
│ ├── ProfilePropGroups.cs
│ ├── Program.cs
│ ├── ScpUtil.cs
│ ├── UdpServer.cs
│ ├── Util.cs
│ └── Xbox360OutDevice.cs
├── DS4Forms
│ ├── About.xaml
│ ├── About.xaml.cs
│ ├── AutoProfiles.xaml
│ ├── AutoProfiles.xaml.cs
│ ├── AxialStickUserControl.xaml
│ ├── AxialStickUserControl.xaml.cs
│ ├── BindingWindow.xaml
│ ├── BindingWindow.xaml.cs
│ ├── ChangelogWindow.xaml
│ ├── ChangelogWindow.xaml.cs
│ ├── ColorPickerWindow.xaml
│ ├── ColorPickerWindow.xaml.cs
│ ├── ControllerReadingsControl.xaml
│ ├── ControllerReadingsControl.xaml.cs
│ ├── ControllerRegisterOptionsWindow.xaml
│ ├── ControllerRegisterOptionsWindow.xaml.cs
│ ├── Converters
│ │ ├── EscapeAccessKeysConverter.cs
│ │ └── InvertBoolToVisibilityConverter.cs
│ ├── DupBox.xaml
│ ├── DupBox.xaml.cs
│ ├── LanguagePackControl.xaml
│ ├── LanguagePackControl.xaml.cs
│ ├── LogMessageDisplay.xaml
│ ├── LogMessageDisplay.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── OutputSlotManagerControl.xaml
│ ├── OutputSlotManagerControl.xaml.cs
│ ├── PluginOutDevWindow.xaml
│ ├── PluginOutDevWindow.xaml.cs
│ ├── PresetOptionWindow.xaml
│ ├── PresetOptionWindow.xaml.cs
│ ├── ProfileEditor.xaml
│ ├── ProfileEditor.xaml.cs
│ ├── RecordBox.xaml
│ ├── RecordBox.xaml.cs
│ ├── RecordBoxWindow.xaml
│ ├── RecordBoxWindow.xaml.cs
│ ├── RenameProfileWindow.xaml
│ ├── RenameProfileWindow.xaml.cs
│ ├── SaveWhere.xaml
│ ├── SaveWhere.xaml.cs
│ ├── SpecialActionEditor.xaml
│ ├── SpecialActionEditor.xaml.cs
│ ├── Themes
│ │ ├── DarkTheme.xaml
│ │ └── DefaultTheme.xaml
│ ├── UpdaterWindow.xaml
│ ├── UpdaterWindow.xaml.cs
│ ├── UtilMethods.cs
│ ├── ViewModels
│ │ ├── AutoProfilesViewModel.cs
│ │ ├── AxialStickControlViewModel.cs
│ │ ├── BindingWindowViewModel.cs
│ │ ├── ChangelogViewModel.cs
│ │ ├── ControllerListViewModel.cs
│ │ ├── ControllerRegDeviceOptsViewModel.cs
│ │ ├── CurrentOutDeviceViewModel.cs
│ │ ├── LanguagePackViewModel.cs
│ │ ├── LogViewModel.cs
│ │ ├── MainWindowsViewModel.cs
│ │ ├── MappingListViewModel.cs
│ │ ├── PresetOptionViewModel.cs
│ │ ├── ProfileSettingsViewModel.cs
│ │ ├── RecordBoxViewModel.cs
│ │ ├── RenameProfileViewModel.cs
│ │ ├── SettingsViewModel.cs
│ │ ├── SpecialActEditorViewModel.cs
│ │ ├── SpecialActions
│ │ │ ├── CheckBatteryViewModel.cs
│ │ │ ├── DisconnectBTViewModel.cs
│ │ │ ├── LaunchProgramViewModel.cs
│ │ │ ├── LoadProfileViewModel.cs
│ │ │ ├── MacroViewModel.cs
│ │ │ ├── MultiActButtonViewModel.cs
│ │ │ ├── PressKeyViewModel.cs
│ │ │ └── SASteeringWheelViewModel.cs
│ │ ├── SpecialActionsListViewModel.cs
│ │ ├── TrayIconViewModel.cs
│ │ ├── UpdaterWindowViewModel.cs
│ │ └── Util
│ │ │ ├── EnumChoiceSelection.cs
│ │ │ └── NotifyDataErrorBase.cs
│ ├── WelcomeDialog.xaml
│ └── WelcomeDialog.xaml.cs
├── DS4Library
│ ├── Crc32.cs
│ ├── DS4Device.cs
│ ├── DS4Devices.cs
│ ├── DS4Sixaxis.cs
│ ├── DS4State.cs
│ ├── DS4StateExposed.cs
│ ├── DS4Touchpad.cs
│ ├── InputDevices
│ │ ├── DualSenseDevice.cs
│ │ ├── InputDeviceFactory.cs
│ │ ├── JoyConDevice.cs
│ │ ├── SwitchProDevice.cs
│ │ └── TriggerEffects.cs
│ └── LICENSE-Crc32.txt
├── DS4W.ico
├── DS4WinWPF.csproj
├── DateTimeJsonConverter.cs
├── HidLibrary
│ ├── Extensions.cs
│ ├── HidDevice.cs
│ ├── HidDeviceAttributes.cs
│ ├── HidDeviceCapabilities.cs
│ ├── HidDevices.cs
│ ├── LICENSE
│ └── NativeMethods.cs
├── LogItem.cs
├── LogWriter.cs
├── LoggerHolder.cs
├── NLog.config
├── OneEuroFilter.cs
├── ProfileEntity.cs
├── ProfileList.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.ja.resx
│ ├── Resources.resx
│ ├── Resources.ru.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── ReaderWriteLockSlimWrappers.cs
├── Resources
│ ├── 360 fades.png
│ ├── 360 highlight.png
│ ├── 360 map.png
│ ├── A.PNG
│ ├── B.png
│ ├── BACK.png
│ ├── BT.png
│ ├── BT_white.png
│ ├── DOWN.png
│ ├── DS4 Config.png
│ ├── DS4 Config_white.png
│ ├── DS4 Controller.png
│ ├── DS4 lightbar.png
│ ├── DS4-Config_Circle.png
│ ├── DS4-Config_Cross.png
│ ├── DS4-Config_Down.png
│ ├── DS4-Config_L1.png
│ ├── DS4-Config_L2.png
│ ├── DS4-Config_LS.png
│ ├── DS4-Config_Left.png
│ ├── DS4-Config_PS.png
│ ├── DS4-Config_R1.png
│ ├── DS4-Config_R2.png
│ ├── DS4-Config_RS.png
│ ├── DS4-Config_Right.png
│ ├── DS4-Config_Share.png
│ ├── DS4-Config_Square.png
│ ├── DS4-Config_TouchLeft.png
│ ├── DS4-Config_TouchMulti.png
│ ├── DS4-Config_TouchRight.png
│ ├── DS4-Config_TouchUpper.png
│ ├── DS4-Config_Triangle.png
│ ├── DS4-Config_Up.png
│ ├── DS4-Config_options.png
│ ├── DS4.ico
│ ├── DS4W - Black.ico
│ ├── DS4W - White.ico
│ ├── DS4W.ico
│ ├── LB.png
│ ├── LEFT.png
│ ├── LS.png
│ ├── LSD.png
│ ├── LSL.png
│ ├── LSR.png
│ ├── LSU.png
│ ├── LT.png
│ ├── Pairmode.png
│ ├── RB.png
│ ├── RIGHT.png
│ ├── RS.png
│ ├── RSD.png
│ ├── RSL.png
│ ├── RSR.png
│ ├── RSU.png
│ ├── RT.png
│ ├── Red Circle.png
│ ├── START.png
│ ├── UP.png
│ ├── USB.png
│ ├── USB_white.png
│ ├── UpperTouch.png
│ ├── X.png
│ ├── Y.png
│ ├── cancel.png
│ ├── cancel_white.png
│ ├── checked.png
│ ├── checked_white.png
│ ├── clock.png
│ ├── clock_white.png
│ ├── copy.png
│ ├── copy_white.png
│ ├── delete.png
│ ├── delete_white.png
│ ├── edit.png
│ ├── edit_white.png
│ ├── export.png
│ ├── export_white.png
│ ├── import.png
│ ├── import_white.png
│ ├── key-solid.png
│ ├── key-solid_white.png
│ ├── keydown.png
│ ├── keydown_white.png
│ ├── keyup.png
│ ├── keyup_white.png
│ ├── left touch.png
│ ├── mouse.png
│ ├── newprofile.png
│ ├── newprofile_white.png
│ ├── none.png
│ ├── rainbow.png
│ ├── rainbowC.png
│ ├── rainbowCCrop.png
│ ├── right touch.png
│ ├── saveprofile.png
│ ├── size.png
│ ├── social
│ │ ├── GitHub-Mark-64px.png
│ │ ├── GitHub-Mark-Light-64px.png
│ │ ├── bittube.png
│ │ ├── twitter_logo_initial.png
│ │ └── youtube_social_icon_red.png
│ ├── x360test.png
│ └── xbox_360_controller.png
├── StartupMethods.cs
├── StatusLogMsg.cs
├── Translations
│ ├── Strings.Designer.cs
│ ├── Strings.ar.resx
│ ├── Strings.cs.resx
│ ├── Strings.de.resx
│ ├── Strings.es.resx
│ ├── Strings.fr.resx
│ ├── Strings.he.resx
│ ├── Strings.hu-HU.resx
│ ├── Strings.it.resx
│ ├── Strings.ja.resx
│ ├── Strings.nl.resx
│ ├── Strings.pl.resx
│ ├── Strings.pt-BR.resx
│ ├── Strings.pt.resx
│ ├── Strings.resx
│ ├── Strings.ru.resx
│ ├── Strings.uk-UA.resx
│ ├── Strings.zh-Hans.resx
│ └── Strings.zh-Hant.resx
├── VJoyFeeder
│ └── vJoyFeeder.cs
├── app.manifest
├── libs
│ ├── x64
│ │ ├── FakerInputWrapper
│ │ │ ├── FakerInputDll.dll
│ │ │ └── FakerInputWrapper.dll
│ │ ├── Nefarius.ViGEm.Client
│ │ │ └── Nefarius.ViGEm.Client.dll
│ │ └── SharpOSC
│ │ │ └── SharpOSC.dll
│ └── x86
│ │ ├── FakerInputWrapper
│ │ ├── FakerInputDll.dll
│ │ └── FakerInputWrapper.dll
│ │ ├── Nefarius.ViGEm.Client
│ │ └── Nefarius.ViGEm.Client.dll
│ │ └── SharpOSC
│ │ └── SharpOSC.dll
├── newest.txt
└── runtimeconfig.template.json
├── DS4WindowsWPF.sln
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── TODO.md
├── contributors.txt
├── disabled_device_example.png
├── disabled_device_example_small.png
├── doc
└── dev
│ └── profile_version_info.md
├── ds4winwpf_screen_20200412.png
├── extras
├── ViGEmBusInstaller_DS4Win.zip
└── Virtual Bus Driver.zip
└── utils
└── inject_deps_path.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots and Logs**
24 | If applicable, add screenshots to help explain your problem. Also, please add the most
25 | log file (ds4windows_log.txt) from the Logs folder in your DS4Windows config folder.
26 |
27 | **Desktop (please complete the following information):**
28 | - Controller Make and Model: Sony DS4 v.2 (CUH-ZCT2U)
29 | - OS: [e.g. Windows 10 Pro Build 2004]
30 | - DS4Windows Version [e.g. 3.0.3]
31 |
32 | **Additional context**
33 | Add any other context about the problem here.
34 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "nuget"
4 | directory: "/"
5 | schedule:
6 | interval: "monthly"
7 |
--------------------------------------------------------------------------------
/DS4Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/DS4Windows/ArgumentParser.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Collections.Generic;
3 | using DS4Windows.DS4Control;
4 |
5 | namespace DS4WinWPF
6 | {
7 | public class ArgumentParser
8 | {
9 | private bool mini;
10 | private bool stop;
11 | private bool driverinstall;
12 | private bool reenableDevice;
13 | private string deviceInstanceId;
14 | private bool runtask;
15 | private bool command;
16 | private string commandArgs;
17 | private string virtualkbmHandler = VirtualKBMFactory.DEFAULT_IDENTIFIER;
18 |
19 | private Dictionary errors =
20 | new Dictionary();
21 |
22 | public bool Mini { get => mini; }
23 | public bool Stop { get => stop; }
24 | public bool Driverinstall { get => driverinstall; }
25 | public bool ReenableDevice { get => reenableDevice; }
26 | public bool Runtask { get => runtask; }
27 | public bool Command { get => command; }
28 | public string DeviceInstanceId { get => deviceInstanceId; }
29 | public string CommandArgs { get => commandArgs; }
30 | public string VirtualkbmHandler { get => virtualkbmHandler; }
31 | public Dictionary Errors { get => errors; }
32 |
33 | public bool HasErrors => errors.Count > 0;
34 |
35 | public void Parse(string[] args)
36 | {
37 | errors.Clear();
38 | //foreach (string arg in args)
39 | for (int i = 0; i < args.Length; i++)
40 | {
41 | string arg = args[i];
42 | switch(arg)
43 | {
44 | case "driverinstall":
45 | case "-driverinstall":
46 | driverinstall = true;
47 | break;
48 |
49 | case "re-enabledevice":
50 | case "-re-enabledevice":
51 | reenableDevice = true;
52 | if (i + 1 < args.Length)
53 | {
54 | deviceInstanceId = args[++i];
55 | }
56 |
57 | break;
58 |
59 | case "runtask":
60 | case "-runtask":
61 | runtask = true;
62 | break;
63 |
64 | case "-stop":
65 | stop = true;
66 | break;
67 |
68 | case "-m":
69 | mini = true;
70 | break;
71 |
72 | case "command":
73 | case "-command":
74 | command = true;
75 | if (i + 1 < args.Length)
76 | {
77 | i++;
78 | string temp = args[i];
79 | if (temp.Length > 0 && temp.Length <= 256)
80 | {
81 | commandArgs = temp;
82 | }
83 | else
84 | {
85 | command = false;
86 | errors["Command"] = "Command length is invalid";
87 | }
88 | }
89 | else
90 | {
91 | errors["Command"] = "Command string not given";
92 | }
93 | break;
94 | case "-virtualkbm":
95 | if (i + 1 < args.Length)
96 | {
97 | i++;
98 | string temp = args[i];
99 | bool valid = VirtualKBMFactory.IsValidHandler(temp);
100 | if (valid)
101 | {
102 | virtualkbmHandler = temp;
103 | }
104 | }
105 |
106 | break;
107 |
108 | default: break;
109 | }
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/DS4Windows/BezierCurveEditor/build.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/BezierCurveEditor/build.js
--------------------------------------------------------------------------------
/DS4Windows/BezierCurveEditor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bezier Curve Editor for DS4Windows
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/ControllerSlotManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 |
5 | namespace DS4Windows
6 | {
7 | public class ControllerSlotManager
8 | {
9 | private ReaderWriterLockSlim collectionLocker = new ReaderWriterLockSlim();
10 | public ReaderWriterLockSlim CollectionLocker { get => collectionLocker; }
11 |
12 | private List controllerColl;
13 | public List ControllerColl { get => controllerColl; set => controllerColl = value; }
14 |
15 | private Dictionary controllerDict;
16 | private Dictionary reverseControllerDict;
17 | public Dictionary ControllerDict { get => controllerDict; }
18 | public Dictionary ReverseControllerDict { get => reverseControllerDict; }
19 |
20 | public ControllerSlotManager()
21 | {
22 | controllerColl = new List();
23 | controllerDict = new Dictionary();
24 | reverseControllerDict = new Dictionary();
25 | }
26 |
27 | public void AddController(DS4Device device, int slotIdx)
28 | {
29 | using (WriteLocker locker = new WriteLocker(collectionLocker))
30 | {
31 | controllerColl.Add(device);
32 | controllerDict.Add(slotIdx, device);
33 | reverseControllerDict.Add(device, slotIdx);
34 | }
35 | }
36 |
37 | public void RemoveController(DS4Device device, int slotIdx)
38 | {
39 | using (WriteLocker locker = new WriteLocker(collectionLocker))
40 | {
41 | controllerColl.Remove(device);
42 | controllerDict.Remove(slotIdx);
43 | reverseControllerDict.Remove(device);
44 | }
45 | }
46 |
47 | public void ClearControllerList()
48 | {
49 | using (WriteLocker locker = new WriteLocker(collectionLocker))
50 | {
51 | controllerColl.Clear();
52 | controllerDict.Clear();
53 | reverseControllerDict.Clear();
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/DS4OutDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Nefarius.ViGEm.Client;
7 | using Nefarius.ViGEm.Client.Targets;
8 | using Nefarius.ViGEm.Client.Targets.DualShock4;
9 |
10 | namespace DS4Windows
11 | {
12 | abstract class DS4OutDevice : OutputDevice
13 | {
14 | public const string devtype = "DS4";
15 |
16 | public IDualShock4Controller cont;
17 | //public DualShock4FeedbackReceivedEventHandler forceFeedbackCall;
18 | public Dictionary forceFeedbacksDict =
19 | new Dictionary();
20 |
21 | public DS4OutDevice(ViGEmClient client)
22 | {
23 | cont = client.CreateDualShock4Controller();
24 | //cont = client.CreateDualShock4Controller(0x054C, 0x09CC);
25 | cont.AutoSubmitReport = false;
26 | }
27 |
28 | public override void Connect()
29 | {
30 | cont.Connect();
31 | connected = true;
32 | }
33 | public override void Disconnect()
34 | {
35 | foreach (KeyValuePair pair in forceFeedbacksDict)
36 | {
37 | cont.FeedbackReceived -= pair.Value;
38 | }
39 |
40 | forceFeedbacksDict.Clear();
41 |
42 | connected = false;
43 | cont.Disconnect();
44 | //cont.Dispose();
45 | cont = null;
46 | }
47 | public override string GetDeviceType() => devtype;
48 |
49 | public override void RemoveFeedbacks()
50 | {
51 | foreach (KeyValuePair pair in forceFeedbacksDict)
52 | {
53 | cont.FeedbackReceived -= pair.Value;
54 | }
55 |
56 | forceFeedbacksDict.Clear();
57 | }
58 |
59 | public override void RemoveFeedback(int inIdx)
60 | {
61 | if (forceFeedbacksDict.TryGetValue(inIdx, out DualShock4FeedbackReceivedEventHandler handler))
62 | {
63 | cont.FeedbackReceived -= handler;
64 | forceFeedbacksDict.Remove(inIdx);
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/DS4OutDevices/DS4OutDeviceExtras.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace DS4Windows
9 | {
10 | [StructLayout(LayoutKind.Sequential, Size = 9)]
11 | unsafe struct DS4_TOUCH
12 | {
13 | public byte bPacketCounter;
14 | public byte bIsUpTrackingNum1;
15 | public fixed byte bTouchData1[3];
16 | public byte bIsUpTrackingNum2;
17 | public fixed byte bTouchData2[3];
18 | }
19 |
20 | [StructLayout(LayoutKind.Explicit)]
21 | unsafe struct DS4_REPORT_UNION
22 | {
23 | [FieldOffset(0)]
24 | public DS4_REPORT_EX reportStruct;
25 |
26 | [FieldOffset(0)]
27 | public fixed byte Report[63];
28 | }
29 |
30 | ///
31 | /// Used to set data for DS4 Extended output report. StructLayout
32 | /// will be used to align data for a raw byte array of 63 bytes.
33 | /// ViGEmBus will place report ID byte into the output so this data
34 | /// will technically start with byte 1 of the final output report
35 | ///
36 | [StructLayout(LayoutKind.Explicit, Size = 63)]
37 | unsafe struct DS4_REPORT_EX
38 | {
39 | [FieldOffset(0)]
40 | public byte bThumbLX;
41 | [FieldOffset(1)]
42 | public byte bThumbLY;
43 | [FieldOffset(2)]
44 | public byte bThumbRX;
45 | [FieldOffset(3)]
46 | public byte bThumbRY;
47 | [FieldOffset(4)]
48 | public ushort wButtons;
49 | [FieldOffset(6)]
50 | public byte bSpecial;
51 | [FieldOffset(7)]
52 | public byte bTriggerL;
53 | [FieldOffset(8)]
54 | public byte bTriggerR;
55 | [FieldOffset(9)]
56 | public ushort wTimestamp;
57 | [FieldOffset(11)]
58 | public byte bBatteryLvl;
59 | [FieldOffset(12)]
60 | public short wGyroX;
61 | [FieldOffset(14)]
62 | public short wGyroY;
63 | [FieldOffset(16)]
64 | public short wGyroZ;
65 | [FieldOffset(18)]
66 | public short wAccelX;
67 | [FieldOffset(20)]
68 | public short wAccelY;
69 | [FieldOffset(22)]
70 | public short wAccelZ;
71 | [FieldOffset(24)]
72 | public fixed byte _bUnknown1[5];
73 | [FieldOffset(29)]
74 | public byte bBatteryLvlSpecial;
75 | [FieldOffset(30)]
76 | public fixed byte _bUnknown2[2];
77 | [FieldOffset(32)]
78 | public byte bTouchPacketsN;
79 | [FieldOffset(33)]
80 | public DS4_TOUCH sCurrentTouch;
81 | [FieldOffset(42)]
82 | public DS4_TOUCH sPreviousTouch1;
83 | [FieldOffset(51)]
84 | public DS4_TOUCH sPreviousTouch2;
85 | }
86 |
87 | internal static class DS4OutDeviceExtras
88 | {
89 | public static void CopyBytes(ref DS4_REPORT_EX outReport, byte[] outBuffer)
90 | {
91 | GCHandle h = GCHandle.Alloc(outReport, GCHandleType.Pinned);
92 | Marshal.Copy(h.AddrOfPinnedObject(), outBuffer, 0, 63);
93 | h.Free();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/DS4OutDevices/DS4OutDeviceFactory.cs:
--------------------------------------------------------------------------------
1 | using Nefarius.ViGEm.Client;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace DS4Windows
9 | {
10 | static class DS4OutDeviceFactory
11 | {
12 | private static Version extAPIMinVersion = new Version("1.17.333.0");
13 |
14 | public static DS4OutDevice CreateDS4Device(ViGEmClient client,
15 | Version driverVersion)
16 | {
17 | DS4OutDevice result = null;
18 | if (extAPIMinVersion.CompareTo(driverVersion) <= 0)
19 | {
20 | result = new DS4OutDeviceExt(client);
21 | }
22 | else
23 | {
24 | result = new DS4OutDeviceBasic(client);
25 | }
26 |
27 | return result;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/ITouchpadBehaviour.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4Windows
4 | {
5 | interface ITouchpadBehaviour
6 | {
7 | void touchesBegan(DS4Touchpad sender, TouchpadEventArgs arg);
8 | void touchesMoved(DS4Touchpad sender, TouchpadEventArgs arg);
9 | void touchButtonUp(DS4Touchpad sender, TouchpadEventArgs arg);
10 | void touchButtonDown(DS4Touchpad sender, TouchpadEventArgs arg);
11 | void touchesEnded(DS4Touchpad sender, TouchpadEventArgs arg);
12 | void sixaxisMoved(DS4SixAxis sender, SixAxisEventArgs unused);
13 | void touchUnchanged(DS4Touchpad sender, EventArgs unused);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/Log.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4Windows
4 | {
5 | public class AppLogger
6 | {
7 | public static event EventHandler TrayIconLog;
8 | public static event EventHandler GuiLog;
9 |
10 | public static void LogToGui(string data, bool warning, bool temporary = false)
11 | {
12 | if (GuiLog != null)
13 | {
14 | GuiLog(null, new DebugEventArgs(data, warning, temporary));
15 | }
16 | }
17 |
18 | public static void LogToTray(string data, bool warning = false, bool ignoreSettings = false)
19 | {
20 | if (TrayIconLog != null)
21 | {
22 | if (ignoreSettings)
23 | TrayIconLog(ignoreSettings, new DebugEventArgs(data, warning));
24 | else
25 | TrayIconLog(null, new DebugEventArgs(data, warning));
26 | }
27 | }
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/MouseWheel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4Windows
4 | {
5 | class MouseWheel
6 | {
7 | private readonly int deviceNumber;
8 | public MouseWheel(int deviceNum)
9 | {
10 | deviceNumber = deviceNum;
11 | }
12 |
13 | // Keep track of remainders when performing scrolls or we lose fractional parts.
14 | private double horizontalRemainder = 0.0, verticalRemainder = 0.0;
15 |
16 | public void touchesBegan(TouchpadEventArgs arg)
17 | {
18 | if (arg.touches.Length == 2)
19 | horizontalRemainder = verticalRemainder = 0.0;
20 | }
21 |
22 | public void touchesMoved(TouchpadEventArgs arg, bool dragging)
23 | {
24 | if (arg.touches.Length != 2 || dragging)
25 | return;
26 |
27 | Touch lastT0 = arg.touches[0].previousTouch;
28 | Touch lastT1 = arg.touches[1].previousTouch;
29 | Touch T0 = arg.touches[0];
30 | Touch T1 = arg.touches[1];
31 |
32 | //mouse wheel 120 == 1 wheel click according to Windows API
33 | double lastMidX = (lastT0.hwX + lastT1.hwX) / 2d, lastMidY = (lastT0.hwY + lastT1.hwY) / 2d,
34 | currentMidX = (T0.hwX + T1.hwX) / 2d, currentMidY = (T0.hwY + T1.hwY) / 2d;
35 |
36 | // Express coefficient as a ratio
37 | double coefficient = Global.ScrollSensitivity[deviceNumber] / 100.0;
38 |
39 | // Adjust for touch distance: "standard" distance is 960 pixels, i.e. half the width. Scroll farther if fingers are farther apart, and vice versa, in linear proportion.
40 | double touchXDistance = T1.hwX - T0.hwX, touchYDistance = T1.hwY - T0.hwY, touchDistance = Math.Sqrt(touchXDistance * touchXDistance + touchYDistance * touchYDistance);
41 | coefficient *= touchDistance / 960.0;
42 |
43 | // Collect rounding errors instead of losing motion.
44 | double xMotion = coefficient * (currentMidX - lastMidX);
45 | if ((xMotion > 0.0 && horizontalRemainder > 0.0) || (xMotion < 0.0 && horizontalRemainder < 0.0))
46 | {
47 | xMotion += horizontalRemainder;
48 | }
49 |
50 | int xAction = (int)xMotion;
51 | horizontalRemainder = xMotion - xAction;
52 |
53 | double yMotion = coefficient * (lastMidY - currentMidY);
54 | if ((yMotion > 0.0 && verticalRemainder > 0.0) || (yMotion < 0.0 && verticalRemainder < 0.0))
55 | {
56 | yMotion += verticalRemainder;
57 | }
58 |
59 | int yAction = (int)yMotion;
60 | verticalRemainder = yMotion - yAction;
61 |
62 | if (yAction != 0 || xAction != 0)
63 | {
64 | yAction = yAction < 0 ? yAction * -1 * Global.outputKBMMapping.WHEEL_TICK_DOWN :
65 | yAction * Global.outputKBMMapping.WHEEL_TICK_UP;
66 |
67 | xAction = xAction < 0 ? xAction * -1 * Global.outputKBMMapping.WHEEL_TICK_DOWN :
68 | xAction * Global.outputKBMMapping.WHEEL_TICK_UP;
69 |
70 | Global.outputKBMHandler.PerformMouseWheelEvent(yAction, xAction);
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4Windows
4 | {
5 | public abstract class OutputDevice
6 | {
7 | protected bool connected;
8 |
9 | public abstract void ConvertandSendReport(DS4State state, int device);
10 | public abstract void Connect();
11 | public abstract void Disconnect();
12 | public abstract void ResetState(bool submit=true);
13 | public abstract string GetDeviceType();
14 |
15 | public abstract void RemoveFeedbacks();
16 |
17 | public abstract void RemoveFeedback(int inIdx);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputKBM/SendInputMapping.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace DS4Windows.DS4Control
3 | {
4 | public class SendInputMapping : VirtualKBMMapping
5 | {
6 | public override void PopulateConstants()
7 | {
8 | MOUSEEVENTF_LEFTDOWN = 2; MOUSEEVENTF_LEFTUP = 4;
9 | MOUSEEVENTF_RIGHTDOWN = 8; MOUSEEVENTF_RIGHTUP = 16;
10 | MOUSEEVENTF_MIDDLEDOWN = 32; MOUSEEVENTF_MIDDLEUP = 64;
11 | MOUSEEVENTF_XBUTTONDOWN = 128; MOUSEEVENTF_XBUTTONUP = 256;
12 | MOUSEEVENTF_WHEEL = 0x0800; MOUSEEVENTF_HWHEEL = 0x1000;
13 | }
14 |
15 | ///
16 | /// Not really needed as Window keys are the standard being mapped against
17 | ///
18 | public override void PopulateMappings()
19 | {
20 | }
21 |
22 | ///
23 | /// Not really needed here as Window keys are the standard being mapped against. Just return key
24 | ///
25 | /// Windows Virtual Key value
26 | /// Windows Virtual Key value
27 | public override uint GetRealEventKey(uint winVkKey)
28 | {
29 | return winVkKey;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputKBM/VirtualKBMBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DS4Windows.DS4Control
8 | {
9 | public abstract class VirtualKBMBase
10 | {
11 | protected string errorMessage = string.Empty;
12 | public string ErrorMessage { get => errorMessage; }
13 |
14 | public bool fakeKeyRepeat = false;
15 |
16 | public Version version = new Version("0.0.0.0");
17 | public string Version
18 | {
19 | get => version.ToString();
20 | set => version = new Version(value);
21 | }
22 |
23 | public abstract bool Connect();
24 | public abstract bool Disconnect();
25 |
26 | public abstract void MoveRelativeMouse(int x, int y);
27 |
28 | public abstract void MoveAbsoluteMouse(double x, double y);
29 |
30 | public abstract void PerformMouseWheelEvent(int vertical, int horizontal);
31 | public abstract void PerformMouseButtonEvent(uint mouseButton);
32 | public virtual void PerformMouseButtonEventAlt(uint mouseButton, int type)
33 | {
34 |
35 | }
36 |
37 | public abstract void PerformMouseButtonPress(uint mouseButton);
38 | public abstract void PerformMouseButtonRelease(uint mouseButton);
39 |
40 | public abstract void PerformKeyPress(uint key);
41 | public abstract void PerformKeyPressAlt(uint key);
42 | public abstract void PerformKeyRelease(uint key);
43 | public abstract void PerformKeyReleaseAlt(uint key);
44 |
45 | public virtual void Sync()
46 | {
47 | }
48 |
49 | public abstract string GetDisplayName();
50 | public abstract string GetIdentifier();
51 |
52 | public abstract string GetFullDisplayName();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputKBM/VirtualKBMFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4Windows.DS4Control
4 | {
5 | public static class VirtualKBMFactory
6 | {
7 | public const string DEFAULT_IDENTIFIER = "default";
8 |
9 | public static VirtualKBMBase DetermineHandler(string identifier =
10 | SendInputHandler.IDENTIFIER)
11 | {
12 | VirtualKBMBase handler = null;
13 | if (identifier == DEFAULT_IDENTIFIER)
14 | {
15 | // Run through event handler discovery routine
16 | if (Global.fakerInputInstalled)
17 | {
18 | handler = new FakerInputHandler();
19 | }
20 | else
21 | {
22 | // Virtual KB+M driver not found. Use fallback system instead
23 | handler = GetFallbackHandler();
24 | }
25 | }
26 | else if (identifier == SendInputHandler.IDENTIFIER)
27 | {
28 | handler = new SendInputHandler();
29 | }
30 | else if (identifier == FakerInputHandler.IDENTIFIER)
31 | {
32 | handler = new FakerInputHandler();
33 | }
34 | else
35 | {
36 | handler = GetFallbackHandler();
37 | }
38 |
39 | return handler;
40 | //return new SendInputHandler();
41 | //return new FakerInputMapping();
42 | }
43 |
44 | public static VirtualKBMMapping GetMappingInstance(string identifier =
45 | SendInputHandler.IDENTIFIER)
46 | {
47 | VirtualKBMMapping temp = null;
48 | if (identifier == SendInputHandler.IDENTIFIER)
49 | {
50 | temp = new SendInputMapping();
51 | }
52 | else if (identifier == FakerInputHandler.IDENTIFIER)
53 | {
54 | temp = new FakerInputMapping();
55 | }
56 | else
57 | {
58 | temp = GetFallbackMapping();
59 | }
60 |
61 | //VirtualKBMMapping temp = new VMultiMapping();
62 | //temp.PopulateConstants();
63 | return temp;
64 | }
65 |
66 | public static VirtualKBMBase GetFallbackHandler()
67 | {
68 | return new SendInputHandler();
69 | }
70 |
71 | public static VirtualKBMMapping GetFallbackMapping()
72 | {
73 | return new SendInputMapping();
74 | }
75 |
76 | ///
77 | /// Retrieves identifier string of fallback virtualkbm handler without
78 | /// creating an instance of the handler
79 | ///
80 | /// Identifier string of the default virtualkbm handler
81 | public static string GetFallbackHandlerIdentifier()
82 | {
83 | return SendInputHandler.IDENTIFIER;
84 | }
85 |
86 | public static bool IsValidHandler(string identifier)
87 | {
88 | bool result = false;
89 | switch (identifier)
90 | {
91 | case SendInputHandler.IDENTIFIER:
92 | result = true;
93 | break;
94 | case FakerInputHandler.IDENTIFIER:
95 | result = true;
96 | break;
97 | default:
98 | break;
99 | }
100 |
101 | return result;
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputKBM/VirtualKBMMapping.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace DS4Windows.DS4Control
3 | {
4 | public abstract class VirtualKBMMapping
5 | {
6 | public uint MOUSEEVENTF_LEFTDOWN = 2, MOUSEEVENTF_LEFTUP = 4,
7 | MOUSEEVENTF_RIGHTDOWN = 8, MOUSEEVENTF_RIGHTUP = 16,
8 | MOUSEEVENTF_MIDDLEDOWN = 32, MOUSEEVENTF_MIDDLEUP = 64,
9 | MOUSEEVENTF_XBUTTONDOWN = 128, MOUSEEVENTF_XBUTTONUP = 256,
10 | MOUSEEVENTF_WHEEL = 0x0800, MOUSEEVENTF_HWHEEL = 0x1000;
11 |
12 | public uint KEY_TAB = 0x09, KEY_LALT = 0x12;
13 | public int WHEEL_TICK_DOWN = -120, WHEEL_TICK_UP = 120;
14 | public bool macroKeyTranslate = false;
15 |
16 | public abstract void PopulateConstants();
17 | public abstract void PopulateMappings();
18 | public abstract uint GetRealEventKey(uint winVkKey);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/OutputSlotPersist.cs:
--------------------------------------------------------------------------------
1 | using DS4Windows;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Xml;
9 |
10 | namespace DS4WinWPF.DS4Control
11 | {
12 | public static class OutputSlotPersist
13 | {
14 | private const string CONFIG_FILENAME = "OutputSlots.xml";
15 |
16 | public static bool ReadConfig(OutputSlotManager slotManager)
17 | {
18 | bool result = false;
19 | string output_path = Path.Combine(Global.appdatapath, CONFIG_FILENAME);
20 | if (File.Exists(output_path))
21 | {
22 | XmlDocument m_Xdoc = new XmlDocument();
23 | try { m_Xdoc.Load(output_path); }
24 | catch (UnauthorizedAccessException) { }
25 | catch (XmlException) { }
26 |
27 | XmlElement rootElement = m_Xdoc.DocumentElement;
28 | if (rootElement == null) return false;
29 |
30 | foreach(XmlElement element in rootElement.GetElementsByTagName("Slot"))
31 | {
32 | OutSlotDevice tempDev = null;
33 | string temp = element.GetAttribute("idx");
34 | if (int.TryParse(temp, out int idx) && idx >= 0 && idx <= 3)
35 | {
36 | tempDev = slotManager.OutputSlots[idx];
37 | }
38 |
39 | if (tempDev != null)
40 | {
41 | tempDev.CurrentReserveStatus = OutSlotDevice.ReserveStatus.Permanent;
42 | XmlNode tempNode = element.SelectSingleNode("DeviceType");
43 | if (tempNode != null && Enum.TryParse(tempNode.InnerText, out OutContType tempType))
44 | {
45 | tempDev.PermanentType = tempType;
46 | }
47 | }
48 | }
49 |
50 | result = true;
51 | }
52 |
53 | return result;
54 | }
55 |
56 | public static bool WriteConfig(OutputSlotManager slotManager)
57 | {
58 | bool result = false;
59 | XmlDocument m_Xdoc = new XmlDocument();
60 | XmlNode rootNode;
61 | rootNode = m_Xdoc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
62 | m_Xdoc.AppendChild(rootNode);
63 |
64 | rootNode = m_Xdoc.CreateComment(string.Format(" Made with DS4Windows version {0} ", Global.exeversion));
65 | m_Xdoc.AppendChild(rootNode);
66 |
67 | rootNode = m_Xdoc.CreateWhitespace("\r\n");
68 | m_Xdoc.AppendChild(rootNode);
69 |
70 | XmlElement baseElement = m_Xdoc.CreateElement("OutputSlots", null);
71 | baseElement.SetAttribute("app_version", Global.exeversion);
72 |
73 | int idx = 0;
74 | foreach (OutSlotDevice dev in slotManager.OutputSlots)
75 | {
76 | if (dev.CurrentReserveStatus == OutSlotDevice.ReserveStatus.Permanent)
77 | {
78 | XmlElement slotElement = m_Xdoc.CreateElement("Slot");
79 | slotElement.SetAttribute("idx", idx.ToString());
80 |
81 | XmlElement propElement;
82 | propElement = m_Xdoc.CreateElement("DeviceType");
83 | propElement.InnerText = dev.PermanentType.ToString();
84 | slotElement.AppendChild(propElement);
85 |
86 | baseElement.AppendChild(slotElement);
87 | }
88 |
89 | idx++;
90 | }
91 |
92 | m_Xdoc.AppendChild(baseElement);
93 |
94 | string output_path = Path.Combine(Global.appdatapath, CONFIG_FILENAME);
95 | try { m_Xdoc.Save(output_path); result = true; }
96 | catch (UnauthorizedAccessException) { result = false; }
97 |
98 | return result;
99 | }
100 | }
101 | }
--------------------------------------------------------------------------------
/DS4Windows/DS4Control/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DS4Windows
8 | {
9 | public class Program
10 | {
11 | public static ControlService rootHub;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/About.xaml.cs:
--------------------------------------------------------------------------------
1 | using DS4Windows;
2 | using System.Windows;
3 |
4 | namespace DS4WinWPF.DS4Forms
5 | {
6 | ///
7 | /// Interaction logic for About.xaml
8 | ///
9 | public partial class About : Window
10 | {
11 | public About()
12 | {
13 | InitializeComponent();
14 |
15 | string version = Global.exeversion;
16 | headerLb.Content += version + ")";
17 | }
18 |
19 | private void ChangeLogLink_Click(object sender, RoutedEventArgs e)
20 | {
21 | Util.StartProcessHelper("https://docs.google.com/document/d/1CovpH08fbPSXrC6TmEprzgPwCe0tTjQ_HTFfDotpmxk/edit?usp=sharing");
22 | }
23 |
24 | private void PaypalLink_Click(object sender, RoutedEventArgs e)
25 | {
26 | Util.StartProcessHelper("https://paypal.me/ryochan7");
27 | }
28 |
29 | private void PatreonLink_Click(object sender, RoutedEventArgs e)
30 | {
31 | Util.StartProcessHelper("https://patreon.com/user?u=501036");
32 | }
33 |
34 | private void SubscribeStartLink_Click(object sender, RoutedEventArgs e)
35 | {
36 | Util.StartProcessHelper("https://subscribestar.com/ryochan7");
37 | }
38 |
39 | private void SiteLink_Click(object sender, RoutedEventArgs e)
40 | {
41 | Util.StartProcessHelper("https://ryochan7.github.io/ds4windows-site/");
42 | }
43 |
44 | private void SourceLink_Click(object sender, RoutedEventArgs e)
45 | {
46 | Util.StartProcessHelper("https://github.com/Ryochan7/DS4Windows");
47 | }
48 |
49 | private void Jays2KingsLink_Click(object sender, RoutedEventArgs e)
50 | {
51 | Util.StartProcessHelper("https://github.com/Jays2Kings/");
52 | }
53 |
54 | private void InhexSTERLink_Click(object sender, RoutedEventArgs e)
55 | {
56 | Util.StartProcessHelper("https://code.google.com/p/ds4-tool/");
57 | }
58 |
59 | private void ElectrobrainsLink_Click(object sender, RoutedEventArgs e)
60 | {
61 | Util.StartProcessHelper("https://code.google.com/r/brianfundakowskifeldman-ds4windows/");
62 | }
63 |
64 | private void YoutubeSocialBtn_Click(object sender, RoutedEventArgs e)
65 | {
66 | Util.StartProcessHelper("https://www.youtube.com/channel/UCIoUA_XLlCSZbvZGeg3Byeg");
67 | }
68 |
69 | private void BittubeSocialBtn_Click(object sender, RoutedEventArgs e)
70 | {
71 | Util.StartProcessHelper("https://bittube.tv/profile/ds4windows");
72 | }
73 |
74 | private void TwitterSocialBtn_Click(object sender, RoutedEventArgs e)
75 | {
76 | Util.StartProcessHelper("https://twitter.com/ds4windows");
77 | }
78 |
79 | private void GithubSocialBtn_Click(object sender, RoutedEventArgs e)
80 | {
81 | Util.StartProcessHelper("https://github.com/Ryochan7/DS4Windows");
82 | }
83 |
84 | private void ViGEmBusLink_Click(object sender, RoutedEventArgs e)
85 | {
86 | Util.StartProcessHelper("https://vigem.org/");
87 | }
88 |
89 | private void HidHideLink_Click(object sender, RoutedEventArgs e)
90 | {
91 | Util.StartProcessHelper("https://vigem.org/projects/HidHide/");
92 | }
93 |
94 | private void Crc32Link_Click(object sender, RoutedEventArgs e)
95 | {
96 | Util.StartProcessHelper("https://github.com/dariogriffo/Crc32");
97 | }
98 |
99 | private void OneEuroLink_Click(object sender, RoutedEventArgs e)
100 | {
101 | Util.StartProcessHelper("http://cristal.univ-lille.fr/~casiez/1euro/");
102 | }
103 |
104 | private void FakerInputLink_Click(object sender, RoutedEventArgs e)
105 | {
106 | Util.StartProcessHelper("https://github.com/Ryochan7/FakerInput/");
107 | }
108 |
109 | private void HNotifyIconLink_Click(object sender, RoutedEventArgs e)
110 | {
111 | Util.StartProcessHelper("https://github.com/HavenDV/H.NotifyIcon/");
112 | }
113 | }
114 |
115 | public class AboutImgPathLocations
116 | {
117 | private string gitHubImg =
118 | $"{Global.RESOURCES_PREFIX}/social/GitHub-Mark-64px.png";
119 | public string GitHubImg { get => gitHubImg; }
120 |
121 | public AboutImgPathLocations()
122 | {
123 | App current = App.Current as App;
124 | if (current != null)
125 | {
126 | PopulateFromAppResources(current);
127 | }
128 | }
129 |
130 | private void PopulateFromAppResources(App currentApp)
131 | {
132 | gitHubImg = $"{Global.RESOURCES_PREFIX}/social/{currentApp.FindResource("GitHubImg")}";
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/AxialStickUserControl.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
43 |
44 |
45 |
47 |
49 |
50 |
51 |
53 |
55 |
56 |
57 |
59 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/AxialStickUserControl.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Controls;
3 | using DS4Windows;
4 | using DS4WinWPF.DS4Forms.ViewModels;
5 |
6 | namespace DS4WinWPF.DS4Forms
7 | {
8 | ///
9 | /// Interaction logic for AxialStickUserControl.xaml
10 | ///
11 | public partial class AxialStickUserControl : UserControl
12 | {
13 | private AxialStickControlViewModel axialVM;
14 | public AxialStickControlViewModel AxialVM
15 | {
16 | get => axialVM;
17 | }
18 |
19 | public AxialStickUserControl()
20 | {
21 | InitializeComponent();
22 | }
23 |
24 | public void UseDevice(StickDeadZoneInfo stickDeadInfo)
25 | {
26 | axialVM = new AxialStickControlViewModel(stickDeadInfo);
27 | mainGrid.DataContext = axialVM;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ChangelogWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
35 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ChangelogWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using DS4WinWPF.DS4Forms.ViewModels;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Shapes;
15 |
16 | namespace DS4WinWPF.DS4Forms
17 | {
18 | ///
19 | /// Interaction logic for ChangelogWindow.xaml
20 | ///
21 | public partial class ChangelogWindow : Window
22 | {
23 | private ChangelogViewModel changelogVM;
24 |
25 | public ChangelogWindow()
26 | {
27 | InitializeComponent();
28 |
29 | changelogVM = new ChangelogViewModel();
30 |
31 | DataContext = changelogVM;
32 |
33 | SetupEvents();
34 |
35 | changelogVM.RetrieveChangelogInfo();
36 |
37 | }
38 |
39 | private void SetupEvents()
40 | {
41 | changelogVM.ChangelogDocumentChanged += ChangelogVM_ChangelogDocumentChanged;
42 | }
43 |
44 | private void ChangelogVM_ChangelogDocumentChanged(object sender, EventArgs e)
45 | {
46 | richChangelogTxtBox.Document = changelogVM.ChangelogDocument;
47 | }
48 |
49 | private void CloseBtn_Click(object sender, RoutedEventArgs e)
50 | {
51 | Close();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ColorPickerWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ColorPickerWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace DS4WinWPF.DS4Forms
16 | {
17 | ///
18 | /// Interaction logic for ColorPickerWindow.xaml
19 | ///
20 | public partial class ColorPickerWindow : Window
21 | {
22 | public delegate void ColorChangedHandler(ColorPickerWindow sender, Color color);
23 | public event ColorChangedHandler ColorChanged;
24 |
25 | public ColorPickerWindow()
26 | {
27 | InitializeComponent();
28 | }
29 |
30 | private void ColorPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs e)
31 | {
32 | ColorChanged?.Invoke(this, e.NewValue.GetValueOrDefault());
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ControllerRegisterOptionsWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using DS4WinWPF.DS4Forms.ViewModels;
15 | using DS4Windows;
16 |
17 | namespace DS4WinWPF.DS4Forms
18 | {
19 | ///
20 | /// Interaction logic for ControllerRegisterOptions.xaml
21 | ///
22 | public partial class ControllerRegisterOptionsWindow : Window
23 | {
24 | private ControllerRegDeviceOptsViewModel deviceOptsVM;
25 |
26 | public ControllerRegisterOptionsWindow(ControlServiceDeviceOptions deviceOptions, ControlService service)
27 | {
28 | InitializeComponent();
29 |
30 | deviceOptsVM = new ControllerRegDeviceOptsViewModel(deviceOptions, service);
31 |
32 | devOptionsDockPanel.DataContext = deviceOptsVM;
33 | deviceOptsVM.ControllerSelectedIndexChanged += ChangeActiveDeviceTab;
34 | }
35 |
36 | private void ChangeActiveDeviceTab(object sender, EventArgs e)
37 | {
38 | TabItem currentTab = deviceSettingsTabControl.SelectedItem as TabItem;
39 | if (currentTab != null)
40 | {
41 | currentTab.DataContext = null;
42 | }
43 |
44 | int tabIdx = deviceOptsVM.FindTabOptionsIndex();
45 | if (tabIdx >= 0)
46 | {
47 | TabItem pendingTab = deviceSettingsTabControl.Items[tabIdx] as TabItem;
48 | deviceOptsVM.FindFittingDataContext();
49 | pendingTab.DataContext = deviceOptsVM.DataContextObject;
50 | }
51 |
52 | deviceOptsVM.CurrentTabSelectedIndex = tabIdx;
53 | }
54 |
55 | private void Window_Closed(object sender, EventArgs e)
56 | {
57 | deviceOptsVM.SaveControllerConfigs();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/Converters/EscapeAccessKeysConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Text.RegularExpressions;
4 | using System.Windows.Data;
5 |
6 | namespace DS4WinWPF.DS4Forms.Converters
7 | {
8 | public class EscapeAccessKeysConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | string temp = value.ToString();
13 | temp = Regex.Replace(temp, "_{1}", "__");
14 | return temp;
15 | }
16 |
17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
18 | {
19 | string temp = value.ToString();
20 | temp = Regex.Replace(temp, "_{2}", "_");
21 | return temp;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/Converters/InvertBoolToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Data;
9 |
10 | namespace DS4WinWPF.DS4Forms.Converters
11 | {
12 | public class InvertBoolToVisibilityConverter : IValueConverter
13 | {
14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
15 | {
16 | bool temp = System.Convert.ToBoolean(value);
17 | temp = !temp;
18 | Visibility result = Visibility.Visible;
19 | if (!temp)
20 | {
21 | result = Visibility.Hidden;
22 | }
23 |
24 | return result;
25 | }
26 |
27 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
28 | {
29 | throw new NotImplementedException();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/DupBox.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/DupBox.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace DS4WinWPF.DS4Forms
17 | {
18 | ///
19 | /// Interaction logic for DupBox.xaml
20 | ///
21 | public partial class DupBox : UserControl
22 | {
23 | private string oldfilename;
24 | public string OldFilename { get => oldfilename; set => oldfilename = value; }
25 |
26 | public event EventHandler Cancel;
27 | public delegate void SaveHandler(DupBox sender, string profilename);
28 | public event SaveHandler Save;
29 |
30 | public DupBox()
31 | {
32 | InitializeComponent();
33 | }
34 |
35 | private void SaveBtn_Click(object sender, RoutedEventArgs e)
36 | {
37 | string profile = profileTxt.Text;
38 | if (!string.IsNullOrWhiteSpace(profile) &&
39 | profile.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) == -1)
40 | {
41 | System.IO.File.Copy(DS4Windows.Global.appdatapath + "\\Profiles\\" + oldfilename + ".xml",
42 | DS4Windows.Global.appdatapath + "\\Profiles\\" + profile + ".xml", true);
43 | Save?.Invoke(this, profile);
44 | }
45 | else
46 | {
47 | MessageBox.Show(Properties.Resources.ValidName, Properties.Resources.NotValid,
48 | MessageBoxButton.OK, MessageBoxImage.Exclamation);
49 | }
50 | }
51 |
52 | private void CancelBtn_Click(object sender, RoutedEventArgs e)
53 | {
54 | Cancel?.Invoke(this, EventArgs.Empty);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/LanguagePackControl.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/LanguagePackControl.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 | using DS4WinWPF.DS4Forms.ViewModels;
16 |
17 | namespace DS4WinWPF.DS4Forms
18 | {
19 | ///
20 | /// Interaction logic for LanguagePackControl.xaml
21 | ///
22 | public partial class LanguagePackControl : UserControl
23 | {
24 | private LanguagePackViewModel langPackVM;
25 |
26 | public LanguagePackControl()
27 | {
28 | InitializeComponent();
29 |
30 | langPackVM = new LanguagePackViewModel();
31 | this.DataContext = null;
32 | langPackVM.ScanFinished += LangPackVM_ScanFinished;
33 | langPackVM.SelectedIndexChanged += CheckForCultureChange;
34 |
35 | langPackVM.ScanForLangPacks();
36 | }
37 |
38 | private void CheckForCultureChange(object sender, EventArgs e)
39 | {
40 | if (langPackVM.ChangeLanguagePack())
41 | {
42 | MessageBox.Show(Properties.Resources.LanguagePackApplyRestartRequired,
43 | "DS4Windows", MessageBoxButton.OK, MessageBoxImage.Information);
44 | }
45 | }
46 |
47 | private void LangPackVM_ScanFinished(object sender, EventArgs e)
48 | {
49 | Dispatcher.BeginInvoke((Action)(() =>
50 | {
51 | cbCulture.IsEnabled = true;
52 | this.DataContext = langPackVM;
53 | }));
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/LogMessageDisplay.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/LogMessageDisplay.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text.RegularExpressions;
4 | using System.Windows;
5 | using System.Windows.Documents;
6 | using System.Windows.Input;
7 | using MarkdownEngine = MdXaml.Markdown;
8 |
9 | namespace DS4WinWPF.DS4Forms
10 | {
11 | ///
12 | /// Interaction logic for LogMessageDisplay.xaml
13 | ///
14 | public partial class LogMessageDisplay : Window
15 | {
16 | public LogMessageDisplay()
17 | {
18 | InitializeComponent();
19 | }
20 |
21 | public LogMessageDisplay(string message) : this()
22 | {
23 | Regex urlReg = new Regex(@"http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?");
24 | message = urlReg.Replace(message, "[$0]($0)");
25 |
26 | MarkdownEngine engine = new MarkdownEngine();
27 | FlowDocument tmpDoc = engine.Transform(message);
28 | tmpDoc.TextAlignment = TextAlignment.Center;
29 |
30 | richMessageBox.CommandBindings.Add(new CommandBinding(
31 | NavigationCommands.GoToPage,
32 | (sender, e) =>
33 | {
34 | Process proc = new Process();
35 | proc.StartInfo.UseShellExecute = true;
36 | proc.StartInfo.FileName = (string)e.Parameter;
37 |
38 | proc.Start();
39 | }));
40 |
41 | richMessageBox.Document = tmpDoc;
42 | }
43 |
44 | private void OkayButton_Click(object sender, RoutedEventArgs e)
45 | {
46 | Close();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/OutputSlotManagerControl.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/OutputSlotManagerControl.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 | using DS4WinWPF.DS4Forms.ViewModels;
16 |
17 | namespace DS4WinWPF.DS4Forms
18 | {
19 | ///
20 | /// Interaction logic for OutputSlotManager.xaml
21 | ///
22 | public partial class OutputSlotManagerControl : UserControl
23 | {
24 | private DS4Windows.ControlService controlService;
25 | private CurrentOutDeviceViewModel currentOutDevVM;
26 | //private PermanentOutDevViewModel permanentDevVM;
27 |
28 | public OutputSlotManagerControl()
29 | {
30 | InitializeComponent();
31 | }
32 |
33 | public void SetupDataContext(DS4Windows.ControlService controlService,
34 | DS4Windows.OutputSlotManager outputMan)
35 | {
36 | this.controlService = controlService;
37 |
38 | currentOutDevVM = new CurrentOutDeviceViewModel(controlService, outputMan);
39 | currentOutDevVM.SelectedIndexChanged += CurrentOutDevVM_SelectedIndexChanged;
40 | currentOutDevLV.DataContext = currentOutDevVM;
41 | sideStackPanel.DataContext = currentOutDevVM;
42 | plugDevStackPanel.DataContext = currentOutDevVM;
43 | outSlotStackPanel.DataContext = null;
44 |
45 | //permanentDevVM = new PermanentOutDevViewModel(controlService, outputMan);
46 | //permanentOutDevLV.DataContext = permanentDevVM;
47 | }
48 |
49 | private void CurrentOutDevVM_SelectedIndexChanged(object sender, EventArgs e)
50 | {
51 | int idx = currentOutDevVM.SelectedIndex;
52 | if (idx >= 0)
53 | {
54 | outSlotStackPanel.DataContext = currentOutDevVM.SlotDeviceEntries[idx];
55 | }
56 | else
57 | {
58 | outSlotStackPanel.DataContext = null;
59 | }
60 | }
61 |
62 | public void SetupLateEvents()
63 | {
64 |
65 | }
66 |
67 | private void PluginBtn_Click(object sender, RoutedEventArgs e)
68 | {
69 | int idx = currentOutDevVM.SelectedIndex;
70 | SlotDeviceEntry tempEntry = null;
71 | if (idx >= 0)
72 | {
73 | tempEntry = currentOutDevVM.SlotDeviceEntries[idx];
74 | }
75 |
76 | if (tempEntry != null &&
77 | tempEntry.OutSlotDevice.CurrentReserveStatus ==
78 | DS4Control.OutSlotDevice.ReserveStatus.Permanent &&
79 | tempEntry.OutSlotDevice.PermanentType != DS4Windows.OutContType.None)
80 | {
81 | tempEntry.OutSlotDevice.CurrentType = tempEntry.OutSlotDevice.PermanentType;
82 | tempEntry.RequestPlugin();
83 | }
84 | else
85 | {
86 | PluginOutDevWindow devWindow = new PluginOutDevWindow();
87 | devWindow.ShowDialog();
88 | MessageBoxResult result = devWindow.Result;
89 | if (result == MessageBoxResult.OK)
90 | {
91 | tempEntry.OutSlotDevice.CurrentType = devWindow.ContType;
92 | tempEntry.OutSlotDevice.CurrentReserveStatus = devWindow.ReserveType;
93 | if (tempEntry.OutSlotDevice.CurrentReserveStatus ==
94 | DS4Control.OutSlotDevice.ReserveStatus.Permanent)
95 | {
96 | tempEntry.OutSlotDevice.PermanentType = devWindow.ContType;
97 | }
98 |
99 | tempEntry.RequestPlugin();
100 | }
101 | }
102 | }
103 |
104 | private void UnplugBtn_Click(object sender, RoutedEventArgs e)
105 | {
106 | int idx = currentOutDevVM.SelectedIndex;
107 | if (idx >= 0)
108 | {
109 | currentOutDevVM.SlotDeviceEntries[idx].RequestUnplug();
110 | }
111 | }
112 |
113 | private void SlotChangeAcceptBtn_Click(object sender, RoutedEventArgs e)
114 | {
115 | int idx = currentOutDevVM.SelectedIndex;
116 | if (idx >= 0)
117 | {
118 | currentOutDevVM.SlotDeviceEntries[idx].ApplyChanges();
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/PluginOutDevWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/PluginOutDevWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using DS4Windows;
15 | using DS4WinWPF.DS4Control;
16 |
17 | namespace DS4WinWPF.DS4Forms
18 | {
19 | ///
20 | /// Interaction logic for PluginOutDevWindow.xaml
21 | ///
22 | public partial class PluginOutDevWindow : Window
23 | {
24 | private MessageBoxResult result = MessageBoxResult.Cancel;
25 | public MessageBoxResult Result { get => result; }
26 |
27 | private DS4Windows.OutContType contType = DS4Windows.OutContType.None;
28 | public OutContType ContType { get => contType; }
29 |
30 | private DS4Control.OutSlotDevice.ReserveStatus reserveType;
31 | public OutSlotDevice.ReserveStatus ReserveType { get => reserveType; }
32 |
33 | public PluginOutDevWindow()
34 | {
35 | InitializeComponent();
36 | }
37 |
38 | private void AcceptBtn_Click(object sender, RoutedEventArgs e)
39 | {
40 | switch (devTypeCombo.SelectedIndex)
41 | {
42 | case 0:
43 | contType = OutContType.X360;
44 | break;
45 | case 1:
46 | contType = OutContType.DS4;
47 | break;
48 | default:
49 | break;
50 | }
51 |
52 | switch(reserveTypeCombo.SelectedIndex)
53 | {
54 | case 0:
55 | reserveType = OutSlotDevice.ReserveStatus.Dynamic;
56 | break;
57 | case 1:
58 | reserveType = OutSlotDevice.ReserveStatus.Permanent;
59 | break;
60 | default:
61 | break;
62 | }
63 |
64 | if (contType != OutContType.None)
65 | {
66 | result = MessageBoxResult.OK;
67 | }
68 |
69 | Close();
70 | }
71 |
72 | private void CancelBtn_Click(object sender, RoutedEventArgs e)
73 | {
74 | contType = OutContType.None;
75 | result = MessageBoxResult.Cancel;
76 |
77 | Close();
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/PresetOptionWindow.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/PresetOptionWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using DS4WinWPF.DS4Forms.ViewModels;
15 |
16 | namespace DS4WinWPF.DS4Forms
17 | {
18 | ///
19 | /// Interaction logic for PresetOptionWindow.xaml
20 | ///
21 | public partial class PresetOptionWindow : Window
22 | {
23 | private MessageBoxResult result = MessageBoxResult.Cancel;
24 | public MessageBoxResult Result { get => result; }
25 |
26 | private int deviceIndex;
27 | private PresetOptionViewModel presetOptionVM;
28 | private bool delayPresetApply;
29 | public bool DelayPresetApply { get => delayPresetApply; set => delayPresetApply = value; }
30 |
31 | public PresetOptionWindow()
32 | {
33 | InitializeComponent();
34 |
35 | presetOptionVM = new PresetOptionViewModel();
36 |
37 | // Hide tab headers. Tab content will still be visible
38 | IntroTab.Visibility = Visibility.Collapsed;
39 | PresetListTab.Visibility = Visibility.Collapsed;
40 | }
41 |
42 | public void SetupData(int index)
43 | {
44 | deviceIndex = index;
45 | PresetListTab.DataContext = presetOptionVM;
46 | }
47 |
48 | public void ToPresetsScreen()
49 | {
50 | screensTabControl.SelectedItem = PresetListTab;
51 | }
52 |
53 | public void ApplyPreset()
54 | {
55 | presetOptionVM.ApplyPreset(deviceIndex);
56 | }
57 |
58 | private void NoPresetBtn_Click(object sender, RoutedEventArgs e)
59 | {
60 | Close();
61 | }
62 |
63 | private void YesPresetBtn_Click(object sender, RoutedEventArgs e)
64 | {
65 | screensTabControl.SelectedItem = PresetListTab;
66 | //PresetListTab.DataContext = presetOptionVM;
67 | }
68 |
69 | private void PresetCancelBtn_Click(object sender, RoutedEventArgs e)
70 | {
71 | Close();
72 | }
73 |
74 | private void PresetApplyBtn_Click(object sender, RoutedEventArgs e)
75 | {
76 | if (!delayPresetApply)
77 | {
78 | presetOptionVM.ApplyPreset(deviceIndex);
79 | }
80 |
81 | result = MessageBoxResult.OK;
82 | Close();
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/RecordBoxWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/RecordBoxWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace DS4WinWPF.DS4Forms
16 | {
17 | ///
18 | /// Interaction logic for RecordBoxWindow.xaml
19 | ///
20 | public partial class RecordBoxWindow : Window
21 | {
22 | public event EventHandler Saved;
23 |
24 | public RecordBoxWindow(int deviceNum, DS4Windows.DS4ControlSettings settings, bool repeatable = true)
25 | {
26 | InitializeComponent();
27 |
28 | RecordBox box = new RecordBox(deviceNum, settings, false, repeatable: repeatable);
29 | mainPanel.Children.Add(box);
30 |
31 | box.Save += RecordBox_Save;
32 | box.Cancel += Box_Cancel;
33 | }
34 |
35 | private void Box_Cancel(object sender, EventArgs e)
36 | {
37 | Close();
38 | }
39 |
40 | private void RecordBox_Save(object sender, EventArgs e)
41 | {
42 | Saved?.Invoke(this, EventArgs.Empty);
43 | Close();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/RenameProfileWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Please type the new name to use for the selected profile XML file.
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/RenameProfileWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using DS4WinWPF.DS4Forms.ViewModels;
3 |
4 | namespace DS4WinWPF.DS4Forms
5 | {
6 | ///
7 | /// Interaction logic for RenameProfileWindow.xaml
8 | ///
9 | public partial class RenameProfileWindow : Window
10 | {
11 | private RenameProfileViewModel renameProfileVM;
12 | public RenameProfileViewModel RenameProfileVM
13 | {
14 | get => renameProfileVM;
15 | }
16 |
17 | public RenameProfileWindow()
18 | {
19 | InitializeComponent();
20 |
21 | renameProfileVM = new RenameProfileViewModel();
22 | mainDockPanel.DataContext = renameProfileVM;
23 | }
24 |
25 | ///
26 | /// Method used to carry over current name of profile and copy
27 | /// it to ViewModel
28 | ///
29 | /// name of current profile
30 | public void ChangeProfileName(string profileName)
31 | {
32 | renameProfileVM.ProfileName = profileName;
33 | }
34 |
35 | private void CancelBtn_Click(object sender, RoutedEventArgs e)
36 | {
37 | DialogResult = false;
38 | }
39 |
40 | private void ConfirmBtn_Click(object sender, RoutedEventArgs e)
41 | {
42 | if (!string.IsNullOrEmpty(renameProfileVM.ProfileName))
43 | {
44 | bool validChars = renameProfileVM.ProfileName.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) == -1;
45 | if (validChars)
46 | {
47 | bool existingFile = renameProfileVM.ProfileFileExists();
48 | if (existingFile)
49 | {
50 | e.Handled = true;
51 | MessageBox.Show("Profile with name already exists. Please try again.");
52 | }
53 | else
54 | {
55 | DialogResult = true;
56 | Close();
57 | }
58 | }
59 | else
60 | {
61 | e.Handled = true;
62 | MessageBox.Show("Invalid characters used in filename. Please change text.");
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/SaveWhere.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 | For those who prefer a portable program.
22 | Note: this option does not work if in an admin folder w/o UAC
23 |
24 |
25 |
26 |
27 |
28 | For those who prefer a regular install. Settings saved at %appdata%\DS4Windows
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/SaveWhere.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Windows;
4 |
5 |
6 | namespace DS4WinWPF.DS4Forms
7 | {
8 | ///
9 | /// Interaction logic for SaveWhere.xaml
10 | ///
11 | public partial class SaveWhere : Window
12 | {
13 | private bool multisaves;
14 | private bool choiceMade = false;
15 |
16 | public SaveWhere(bool multisavespots)
17 | {
18 | InitializeComponent();
19 | multisaves = multisavespots;
20 | if (!multisavespots)
21 | {
22 | multipleSavesDockP.Visibility = Visibility.Collapsed;
23 | pickWhereTxt.Text += Properties.Resources.OtherFileLocation;
24 | }
25 |
26 | if (DS4Windows.Global.AdminNeeded())
27 | {
28 | progFolderPanel.IsEnabled = false;
29 | }
30 | }
31 |
32 | private void ProgFolderBtn_Click(object sender, RoutedEventArgs e)
33 | {
34 | DS4Windows.Global.SaveWhere(DS4Windows.Global.exedirpath);
35 | if (multisaves && dontDeleteCk.IsChecked == false)
36 | {
37 | try
38 | {
39 | if (Directory.Exists(DS4Windows.Global.appDataPpath))
40 | {
41 | Directory.Delete(DS4Windows.Global.appDataPpath, true);
42 | }
43 | }
44 | catch { }
45 | }
46 | else if (!multisaves)
47 | {
48 | DS4Windows.Global.SaveDefault(DS4Windows.Global.exedirpath + "\\Profiles.xml");
49 | }
50 |
51 | choiceMade = true;
52 | Close();
53 | }
54 |
55 | private void AppdataBtn_Click(object sender, RoutedEventArgs e)
56 | {
57 | if (multisaves && dontDeleteCk.IsChecked == false)
58 | {
59 | try
60 | {
61 | Directory.Delete(DS4Windows.Global.exedirpath + "\\Profiles", true);
62 | File.Delete(DS4Windows.Global.exedirpath + "\\Profiles.xml");
63 | File.Delete(DS4Windows.Global.exedirpath + "\\Auto Profiles.xml");
64 | }
65 | catch (UnauthorizedAccessException)
66 | {
67 | MessageBox.Show("Cannot Delete old settings, please manaully delete", "DS4Windows");
68 | }
69 | }
70 | else if (!multisaves)
71 | {
72 | DS4Windows.Global.SaveDefault(Path.Combine(DS4Windows.Global.appDataPpath, "Profiles.xml"));
73 | }
74 |
75 | DS4Windows.Global.SaveWhere(DS4Windows.Global.appDataPpath);
76 | choiceMade = true;
77 | Close();
78 | }
79 |
80 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
81 | {
82 | if (!choiceMade)
83 | {
84 | e.Cancel = true;
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/Themes/DefaultTheme.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | key-solid.png
12 | cancel.png
13 | checked.png
14 | BT.png
15 | USB.png
16 | keyup.png
17 | keydown.png
18 | clock.png
19 | DS4 Config.png
20 |
21 | copy.png
22 | delete.png
23 | edit.png
24 | export.png
25 | import.png
26 | newprofile.png
27 |
28 | GitHub-Mark-64px.png
29 |
30 |
31 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/UpdaterWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
37 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/UpdaterWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using DS4WinWPF.DS4Forms.ViewModels;
2 | using System;
3 | using System.Windows;
4 |
5 | namespace DS4WinWPF.DS4Forms
6 | {
7 | ///
8 | /// Interaction logic for UpdaterWindow.xaml
9 | ///
10 | public partial class UpdaterWindow : Window
11 | {
12 | private MessageBoxResult result = MessageBoxResult.No;
13 | public MessageBoxResult Result { get => result; }
14 |
15 | private UpdaterWindowViewModel updaterWinVM;
16 |
17 | public UpdaterWindow(string newversion)
18 | {
19 | InitializeComponent();
20 |
21 | Title = Properties.Resources.DS4Update;
22 | captionTextBlock.Text = Properties.Resources.DownloadVersion.Replace("*number*",
23 | newversion);
24 | updaterWinVM = new UpdaterWindowViewModel(newversion);
25 | updaterWinVM.BlankSkippedVersion();
26 |
27 | DataContext = updaterWinVM;
28 |
29 | SetupEvents();
30 |
31 | updaterWinVM.RetrieveChangelogInfo();
32 | }
33 |
34 | private void SetupEvents()
35 | {
36 | updaterWinVM.ChangelogDocumentChanged += UpdaterWinVM_ChangelogDocumentChanged;
37 | }
38 |
39 | private void UpdaterWinVM_ChangelogDocumentChanged(object sender, EventArgs e)
40 | {
41 | richChangelogTxtBox.Document = updaterWinVM.ChangelogDocument;
42 | }
43 |
44 | private void YesBtn_Click(object sender, RoutedEventArgs e)
45 | {
46 | result = MessageBoxResult.Yes;
47 | Close();
48 | }
49 |
50 | private void NoBtn_Click(object sender, RoutedEventArgs e)
51 | {
52 | result = MessageBoxResult.No;
53 | Close();
54 | }
55 |
56 | private void SkipVersionBtn_Click(object sender, RoutedEventArgs e)
57 | {
58 | result = MessageBoxResult.No;
59 | updaterWinVM.SetSkippedVersion();
60 | Close();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/UtilMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Media;
8 |
9 | namespace DS4WinWPF.DS4Forms
10 | {
11 | public static class UtilMethods
12 | {
13 | public static IEnumerable FindVisualChildren(DependencyObject depObj)
14 | where T : DependencyObject
15 | {
16 | if (depObj != null)
17 | {
18 | for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
19 | {
20 | DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
21 | if (child != null && child is T)
22 | {
23 | yield return (T)child;
24 | }
25 |
26 | foreach (T childOfChild in FindVisualChildren(child))
27 | {
28 | yield return childOfChild;
29 | }
30 | }
31 | }
32 | }
33 |
34 | public static childItem FindVisualChild(DependencyObject obj)
35 | where childItem : DependencyObject
36 | {
37 | foreach (childItem child in FindVisualChildren(obj))
38 | {
39 | return child;
40 | }
41 |
42 | return null;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/AxialStickControlViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DS4Windows;
3 |
4 | namespace DS4WinWPF.DS4Forms.ViewModels
5 | {
6 | public class AxialStickControlViewModel
7 | {
8 | private StickDeadZoneInfo stickInfo;
9 |
10 | public double DeadZoneX
11 | {
12 | get => Math.Round(stickInfo.xAxisDeadInfo.deadZone / 127d, 2);
13 | set
14 | {
15 | double temp = Math.Round(stickInfo.xAxisDeadInfo.deadZone / 127d, 2);
16 | if (temp == value) return;
17 | stickInfo.xAxisDeadInfo.deadZone = (int)Math.Round(value * 127d);
18 | DeadZoneXChanged?.Invoke(this, EventArgs.Empty);
19 | }
20 | }
21 | public event EventHandler DeadZoneXChanged;
22 |
23 | public double DeadZoneY
24 | {
25 | get => Math.Round(stickInfo.yAxisDeadInfo.deadZone / 127d, 2);
26 | set
27 | {
28 | double temp = Math.Round(stickInfo.yAxisDeadInfo.deadZone / 127d, 2);
29 | if (temp == value) return;
30 | stickInfo.yAxisDeadInfo.deadZone = (int)Math.Round(value * 127d);
31 | DeadZoneYChanged?.Invoke(this, EventArgs.Empty);
32 | }
33 | }
34 | public event EventHandler DeadZoneYChanged;
35 |
36 | public double MaxZoneX
37 | {
38 | get => stickInfo.xAxisDeadInfo.maxZone / 100.0;
39 | set => stickInfo.xAxisDeadInfo.maxZone = (int)(value * 100.0);
40 | }
41 |
42 | public double MaxZoneY
43 | {
44 | get => stickInfo.yAxisDeadInfo.maxZone / 100.0;
45 | set => stickInfo.yAxisDeadInfo.maxZone = (int)(value * 100.0);
46 | }
47 |
48 | public double AntiDeadZoneX
49 | {
50 | get => stickInfo.xAxisDeadInfo.antiDeadZone / 100.0;
51 | set => stickInfo.xAxisDeadInfo.antiDeadZone = (int)(value * 100.0);
52 | }
53 |
54 | public double AntiDeadZoneY
55 | {
56 | get => stickInfo.yAxisDeadInfo.antiDeadZone / 100.0;
57 | set => stickInfo.yAxisDeadInfo.antiDeadZone = (int)(value * 100.0);
58 | }
59 |
60 | public double MaxOutputX
61 | {
62 | get => stickInfo.xAxisDeadInfo.maxOutput / 100.0;
63 | set => stickInfo.xAxisDeadInfo.maxOutput = value * 100.0;
64 | }
65 |
66 | public double MaxOutputY
67 | {
68 | get => stickInfo.yAxisDeadInfo.maxOutput / 100.0;
69 | set => stickInfo.yAxisDeadInfo.maxOutput = value * 100.0;
70 | }
71 |
72 | public AxialStickControlViewModel(StickDeadZoneInfo deadInfo)
73 | {
74 | this.stickInfo = deadInfo;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/ChangelogViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Documents;
8 | using HttpProgress;
9 | using System.Text.Json;
10 | using MarkdownEngine = MdXaml.Markdown;
11 |
12 | namespace DS4WinWPF.DS4Forms.ViewModels
13 | {
14 | public class ChangelogViewModel
15 | {
16 | private FlowDocument changelogDocument;
17 | public FlowDocument ChangelogDocument
18 | {
19 | get => changelogDocument;
20 | private set
21 | {
22 | if (changelogDocument == value) return;
23 | changelogDocument = value;
24 | ChangelogDocumentChanged?.Invoke(this, EventArgs.Empty);
25 | }
26 | }
27 | public event EventHandler ChangelogDocumentChanged;
28 |
29 | public ChangelogViewModel()
30 | {
31 | BuildTempDocument("Retrieving changelog info.Please wait...");
32 | }
33 |
34 | private void BuildTempDocument(string message)
35 | {
36 | FlowDocument flow = new FlowDocument();
37 | flow.Blocks.Add(new Paragraph(new Run(message)));
38 | ChangelogDocument = flow;
39 | }
40 |
41 | public async void RetrieveChangelogInfo()
42 | {
43 | // Sorry other devs, gonna have to find your own server
44 | Uri url = new Uri(UpdaterWindowViewModel.CHANGELOG_URI);
45 | string filename = Path.Combine(Path.GetTempPath(), "Changelog.min.json");
46 | bool readFile = false;
47 | using (var downloadStream = new FileStream(filename, FileMode.Create))
48 | {
49 | Task temp = App.requestClient.GetAsync(url.ToString(), downloadStream);
50 | try
51 | {
52 | await temp.ConfigureAwait(true);
53 | if (temp.Result.IsSuccessStatusCode) readFile = true;
54 | }
55 | catch (System.Net.Http.HttpRequestException) { }
56 | }
57 |
58 | bool fileExists = File.Exists(filename);
59 | if (fileExists && readFile)
60 | {
61 | string temp = File.ReadAllText(filename).Trim();
62 | try
63 | {
64 | JsonSerializerOptions options = new JsonSerializerOptions()
65 | {
66 | PropertyNameCaseInsensitive = true,
67 | };
68 | options.Converters.Add(new DateTimeJsonConverter.DateTimeConverterUsingDateTimeParse());
69 | ChangelogInfo tempInfo = JsonSerializer.Deserialize(temp, options);
70 | BuildChangelogDocument(tempInfo);
71 | }
72 | catch (JsonException) {}
73 | }
74 | else if (!readFile)
75 | {
76 | BuildTempDocument("Failed to retrieve information");
77 | }
78 |
79 | if (fileExists)
80 | {
81 | File.Delete(filename);
82 | }
83 | }
84 |
85 | private void BuildChangelogDocument(ChangelogInfo tempInfo)
86 | {
87 | MarkdownEngine engine = new MarkdownEngine();
88 | FlowDocument flow = new FlowDocument();
89 | foreach (ChangeVersionInfo versionInfo in tempInfo.Changelog.Versions)
90 | {
91 | VersionLogLocale tmpLog = versionInfo.ApplicableInfo(DS4Windows.Global.UseLang);
92 | if (tmpLog != null)
93 | {
94 | Paragraph tmpPar = new Paragraph();
95 | string tmp = tmpLog.Header;
96 | tmpPar.Inlines.Add(new Run(tmp) { Tag = "Header" });
97 | flow.Blocks.Add(tmpPar);
98 |
99 | tmpPar.Inlines.Add(new LineBreak());
100 | tmpPar.Inlines.Add(new Run(versionInfo.ReleaseDate.ToUniversalTime().ToString("r")) { Tag = "ReleaseDate" });
101 |
102 | tmpLog.BuildDisplayText();
103 |
104 | FlowDocument tmpDoc = engine.Transform(tmpLog.DisplayLogText);
105 | flow.Blocks.AddRange(new List(tmpDoc.Blocks));
106 |
107 | tmpPar = new Paragraph();
108 | flow.Blocks.Add(tmpPar);
109 | }
110 | }
111 |
112 | ChangelogDocument = flow;
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/LanguagePackViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using DS4Windows;
11 |
12 | namespace DS4WinWPF.DS4Forms.ViewModels
13 | {
14 | public class LanguagePackViewModel
15 | {
16 | private List langPackList;
17 | private const string invariantCultureTextValue = "No (English UI)";
18 |
19 | // If probing path has been changed in App.config, add the same string here.
20 | private const string probingPath = "Lang";
21 |
22 | // Filter language assembly file names in order to ont include irrelevant assemblies to the combo box.
23 | private const string languageAssemblyName = "DS4Windows.resources.dll";
24 | //private const string languageAssemblyName = "DS4WinWPF.resources.dll";
25 |
26 | private int selectedIndex;
27 |
28 | public List LangPackList { get => langPackList; }
29 | public int SelectedIndex
30 | {
31 | get => selectedIndex;
32 | set
33 | {
34 | if (selectedIndex == value) return;
35 | selectedIndex = value;
36 | SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
37 | }
38 | }
39 | public event EventHandler SelectedIndexChanged;
40 | public event EventHandler ScanFinished;
41 |
42 | public LanguagePackViewModel()
43 | {
44 | }
45 |
46 | public void ScanForLangPacks()
47 | {
48 | string tempculture = Thread.CurrentThread.CurrentUICulture.Name;
49 | //string tempculture = new CultureInfo(Global.UseLang).Name;
50 | Task.Run(() =>
51 | {
52 | CreateLanguageAssembliesBindingSource();
53 |
54 | int index = langPackList.Select((item, idx) => new { item, idx })
55 | .Where(x => x.item.Name == tempculture)
56 | .Select(x => x.idx)
57 | .DefaultIfEmpty(-1)
58 | .First();
59 | if (index > -1)
60 | {
61 | selectedIndex = index;
62 | }
63 |
64 | ScanFinished?.Invoke(this, EventArgs.Empty);
65 | });
66 | }
67 |
68 | public bool ChangeLanguagePack()
69 | {
70 | bool result = false;
71 | if (selectedIndex > -1)
72 | {
73 | LangPackItem item = langPackList[selectedIndex];
74 | string newValue = item.Name;
75 | if (newValue != Global.UseLang)
76 | {
77 | Global.UseLang = newValue;
78 | //Global.Save();
79 | result = true;
80 | }
81 | }
82 |
83 | return result;
84 | }
85 |
86 | private void CreateLanguageAssembliesBindingSource()
87 | {
88 | // Find the location where application installed.
89 | string exeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
90 | List lookupPaths = probingPath.Split(';')
91 | .Select(path => Path.Combine(exeLocation, path))
92 | .Where(path => path != exeLocation)
93 | .ToList();
94 | lookupPaths.Insert(0, exeLocation);
95 |
96 | // Get all culture for which satellite folder found with culture code, then insert invariant culture at the beginning.
97 | langPackList = CultureInfo.GetCultures(CultureTypes.AllCultures)
98 | .Where(c => IsLanguageAssemblyAvailable(lookupPaths, c))
99 | .Select(c => new LangPackItem(c.Name, c.NativeName))
100 | .ToList();
101 | langPackList.Insert(0, new LangPackItem("", invariantCultureTextValue));
102 | }
103 |
104 | private bool IsLanguageAssemblyAvailable(List lookupPaths, CultureInfo culture)
105 | {
106 | return lookupPaths.Select(path => Path.Combine(path, culture.Name, languageAssemblyName))
107 | .Where(path => File.Exists(path))
108 | .Count() > 0;
109 | }
110 | }
111 |
112 | public class LangPackItem
113 | {
114 | private string name;
115 | private string nativeName;
116 |
117 | public string Name { get => name; }
118 | public string NativeName { get => nativeName; }
119 |
120 | public LangPackItem(string name, string nativeName)
121 | {
122 | this.name = name;
123 | this.nativeName = nativeName;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/LogViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.ObjectModel;
4 | using System.Threading;
5 | using System.Windows.Data;
6 | using DS4Windows;
7 |
8 | namespace DS4WinWPF.DS4Forms.ViewModels
9 | {
10 | public class LogViewModel
11 | {
12 | //private object _colLockobj = new object();
13 | private ReaderWriterLockSlim _logListLocker = new ReaderWriterLockSlim();
14 | private ObservableCollection logItems = new ObservableCollection();
15 |
16 | public ObservableCollection LogItems => logItems;
17 |
18 | public ReaderWriterLockSlim LogListLocker => _logListLocker;
19 |
20 | public LogViewModel(DS4Windows.ControlService service)
21 | {
22 | string version = DS4Windows.Global.exeversion;
23 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"DS4Windows version {version}" });
24 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"DS4Windows Assembly Architecture: {(Environment.Is64BitProcess ? "x64" : "x86")}" });
25 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"OS Version: {Environment.OSVersion}" });
26 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"OS Product Name: {DS4Windows.Util.GetOSProductName()}" });
27 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"OS Release ID: {DS4Windows.Util.GetOSReleaseId()}" });
28 | logItems.Add(new LogItem { Datetime = DateTime.Now, Message = $"System Architecture: {(Environment.Is64BitOperatingSystem ? "x64" : "x32")}" });
29 |
30 | //logItems.Add(new LogItem { Datetime = DateTime.Now, Message = "DS4Windows version 2.0" });
31 | //BindingOperations.EnableCollectionSynchronization(logItems, _colLockobj);
32 | BindingOperations.EnableCollectionSynchronization(logItems, _logListLocker, LogLockCallback);
33 | service.Debug += AddLogMessage;
34 | DS4Windows.AppLogger.GuiLog += AddLogMessage;
35 | }
36 |
37 | private void LogLockCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
38 | {
39 | if (writeAccess)
40 | {
41 | using (WriteLocker locker = new WriteLocker(_logListLocker))
42 | {
43 | accessMethod?.Invoke();
44 | }
45 | }
46 | else
47 | {
48 | using (ReadLocker locker = new ReadLocker(_logListLocker))
49 | {
50 | accessMethod?.Invoke();
51 | }
52 | }
53 | }
54 |
55 | private void AddLogMessage(object sender, DS4Windows.DebugEventArgs e)
56 | {
57 | LogItem item = new LogItem { Datetime = e.Time, Message = e.Data, Warning = e.Warning };
58 | _logListLocker.EnterWriteLock();
59 | logItems.Add(item);
60 | _logListLocker.ExitWriteLock();
61 | //lock (_colLockobj)
62 | //{
63 | // logItems.Add(item);
64 | //}
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/PresetOptionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using DS4WinWPF.DS4Control;
4 | using DS4WinWPF.DS4Forms.ViewModels.Util;
5 |
6 | namespace DS4WinWPF.DS4Forms.ViewModels
7 | {
8 | public class PresetOptionViewModel
9 | {
10 | private int presetIndex;
11 | private PresetOption.OutputContChoice controllerChoice =
12 | PresetOption.OutputContChoice.Xbox360;
13 |
14 | public int PresetIndex
15 | {
16 | get => presetIndex;
17 | set
18 | {
19 | if (presetIndex == value) return;
20 | presetIndex = value;
21 | PresetIndexChanged?.Invoke(this, EventArgs.Empty);
22 | }
23 | }
24 | public event EventHandler PresetIndexChanged;
25 |
26 | private List presetList;
27 | public List PresetsList { get => presetList; }
28 |
29 | public string PresetDescription
30 | {
31 | get => presetList[presetIndex].Description;
32 | }
33 | public event EventHandler PresetDescriptionChanged;
34 |
35 | public bool PresetDisplayOutputCont
36 | {
37 | get => presetList[presetIndex].OutputControllerChoice;
38 | }
39 | public event EventHandler PresetDisplayOutputContChanged;
40 |
41 | public PresetOption.OutputContChoice ControllerChoice
42 | {
43 | get => controllerChoice;
44 | set => controllerChoice = value;
45 | }
46 |
47 | private List> outputChoices =
48 | new List>()
49 | {
50 | new EnumChoiceSelection("Xbox 360", PresetOption.OutputContChoice.Xbox360),
51 | new EnumChoiceSelection("DualShock 4", PresetOption.OutputContChoice.DualShock4),
52 | };
53 |
54 | public List> OutputChoices { get => outputChoices; }
55 |
56 | public PresetOptionViewModel()
57 | {
58 | presetList = new List();
59 | presetList.Add(new GamepadPreset());
60 | presetList.Add(new GamepadGyroCamera());
61 | presetList.Add(new MixedPreset());
62 | presetList.Add(new MixedGyroMousePreset());
63 | presetList.Add(new KBMPreset());
64 | presetList.Add(new KBMGyroMouse());
65 |
66 | PresetIndexChanged += PresetOptionViewModel_PresetIndexChanged;
67 | }
68 |
69 | private void PresetOptionViewModel_PresetIndexChanged(object sender, EventArgs e)
70 | {
71 | PresetDescriptionChanged?.Invoke(this, EventArgs.Empty);
72 | PresetDisplayOutputContChanged?.Invoke(this, EventArgs.Empty);
73 | }
74 |
75 | public void ApplyPreset(int index)
76 | {
77 | if (presetIndex >= 0)
78 | {
79 | PresetOption current = presetList[presetIndex];
80 | if (current.OutputControllerChoice &&
81 | controllerChoice != PresetOption.OutputContChoice.None)
82 | {
83 | current.OutputCont = controllerChoice;
84 | }
85 |
86 | current.ApplyPreset(index);
87 | }
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/RenameProfileViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using DS4Windows;
8 |
9 | namespace DS4WinWPF.DS4Forms.ViewModels
10 | {
11 | public class RenameProfileViewModel
12 | {
13 | private string profileName;
14 | public string ProfileName
15 | {
16 | get => profileName;
17 | set
18 | {
19 | profileName = value;
20 | ProfileNameChanged?.Invoke(this, EventArgs.Empty);
21 | }
22 | }
23 | public event EventHandler ProfileNameChanged;
24 |
25 | public bool ProfileFileExists()
26 | {
27 | string filePath = Path.Combine(Global.appdatapath,
28 | "Profiles", $"{profileName}.xml");
29 | return File.Exists(filePath);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/SpecialActions/DisconnectBTViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using DS4Windows;
7 | using DS4WinWPF.DS4Forms.ViewModels.Util;
8 |
9 | namespace DS4WinWPF.DS4Forms.ViewModels.SpecialActions
10 | {
11 | public class DisconnectBTViewModel : NotifyDataErrorBase
12 | {
13 | private double holdInterval;
14 | public double HoldInterval { get => holdInterval; set => holdInterval = value; }
15 |
16 | public void LoadAction(SpecialAction action)
17 | {
18 | holdInterval = action.delayTime;
19 | }
20 |
21 | public void SaveAction(SpecialAction action, bool edit = false)
22 | {
23 | Global.SaveAction(action.name, action.controls, 5, $"{holdInterval.ToString("#.##", Global.configFileDecimalCulture)}", edit);
24 | }
25 |
26 | public override bool IsValid(SpecialAction action)
27 | {
28 | ClearOldErrors();
29 |
30 | bool valid = true;
31 | List holdIntervalErrors = new List();
32 |
33 | if (holdInterval < 0 || holdInterval > 60)
34 | {
35 | holdIntervalErrors.Add("Interval not valid");
36 | errors["HoldInterval"] = holdIntervalErrors;
37 | RaiseErrorsChanged("HoldInterval");
38 | }
39 |
40 | return valid;
41 | }
42 |
43 | public override void ClearOldErrors()
44 | {
45 | if (errors.Count > 0)
46 | {
47 | errors.Clear();
48 | RaiseErrorsChanged("HoldInterval");
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/SpecialActions/LaunchProgramViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 | using System.Windows.Interop;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using DS4Windows;
13 | using DS4WinWPF.DS4Forms.ViewModels.Util;
14 |
15 | namespace DS4WinWPF.DS4Forms.ViewModels.SpecialActions
16 | {
17 | public class LaunchProgramViewModel : NotifyDataErrorBase
18 | {
19 | private string filepath;
20 | private double delay;
21 | private string arguments;
22 |
23 | public string Filepath
24 | {
25 | get => filepath;
26 | set
27 | {
28 | if (filepath == value) return;
29 | filepath = value;
30 | FilepathChanged?.Invoke(this, EventArgs.Empty);
31 | }
32 | }
33 | public event EventHandler FilepathChanged;
34 | public double Delay { get => delay; set => delay = value; }
35 | public string Arguments { get => arguments; set => arguments = value; }
36 |
37 | public ImageSource ProgramIcon
38 | {
39 | get
40 | {
41 | ImageSource exeicon = null;
42 | string path = filepath;
43 | if (File.Exists(path) && Path.GetExtension(path).ToLower() == ".exe")
44 | {
45 | using (Icon ico = Icon.ExtractAssociatedIcon(path))
46 | {
47 | exeicon = Imaging.CreateBitmapSourceFromHIcon(ico.Handle, Int32Rect.Empty,
48 | BitmapSizeOptions.FromEmptyOptions());
49 | exeicon.Freeze();
50 | }
51 | }
52 |
53 | return exeicon;
54 | }
55 | }
56 | public event EventHandler ProgramIconChanged;
57 |
58 | public string ProgramName
59 | {
60 | get
61 | {
62 | string temp = "";
63 | if (!string.IsNullOrEmpty(filepath))
64 | {
65 | temp = Path.GetFileNameWithoutExtension(filepath);
66 | }
67 |
68 | return temp;
69 | }
70 | }
71 | public event EventHandler ProgramNameChanged;
72 |
73 | public LaunchProgramViewModel()
74 | {
75 | FilepathChanged += LaunchProgramViewModel_FilepathChanged;
76 | }
77 |
78 | private void LaunchProgramViewModel_FilepathChanged(object sender, EventArgs e)
79 | {
80 | ProgramIconChanged?.Invoke(this, EventArgs.Empty);
81 | ProgramNameChanged?.Invoke(this, EventArgs.Empty);
82 | }
83 |
84 | public void LoadAction(SpecialAction action)
85 | {
86 | filepath = action.details;
87 | delay = action.delayTime;
88 | arguments = action.extra;
89 | }
90 |
91 | public void SaveAction(SpecialAction action, bool edit = false)
92 | {
93 | Global.SaveAction(action.name, action.controls, 2, $"{filepath}?{delay.ToString("#.##", Global.configFileDecimalCulture)}", edit, arguments);
94 | }
95 |
96 | public override bool IsValid(SpecialAction action)
97 | {
98 | ClearOldErrors();
99 |
100 | bool valid = true;
101 | List filepathErrors = new List();
102 |
103 | if (filepath.Length == 0)
104 | {
105 | filepathErrors.Add("Filepath empty");
106 | }
107 | else if (!File.Exists(filepath))
108 | {
109 | filepathErrors.Add("File at path does not exist");
110 | }
111 |
112 | if (filepathErrors.Count > 0)
113 | {
114 | errors["Filepath"] = filepathErrors;
115 | RaiseErrorsChanged("Filepath");
116 | }
117 |
118 | return valid;
119 | }
120 |
121 | public override void ClearOldErrors()
122 | {
123 | if (errors.Count > 0)
124 | {
125 | errors.Clear();
126 | RaiseErrorsChanged("Filepath");
127 | }
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/SpecialActions/LoadProfileViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using DS4Windows;
8 | using DS4WinWPF.DS4Forms.ViewModels.Util;
9 |
10 | namespace DS4WinWPF.DS4Forms.ViewModels.SpecialActions
11 | {
12 | public class LoadProfileViewModel : NotifyDataErrorBase
13 | {
14 | private bool autoUntrigger;
15 | private ProfileList profileList;
16 | private int profileIndex;
17 | private bool normalTrigger = true;
18 |
19 | public bool AutoUntrigger { get => autoUntrigger; set => autoUntrigger = value; }
20 | public int ProfileIndex
21 | {
22 | get => profileIndex;
23 | set
24 | {
25 | if (profileIndex == value) return;
26 | profileIndex = value;
27 | ProfileIndexChanged?.Invoke(this, EventArgs.Empty);
28 | }
29 | }
30 | public event EventHandler ProfileIndexChanged;
31 |
32 | public bool UnloadEnabled { get => profileIndex > 0; }
33 | public event EventHandler UnloadEnabledChanged;
34 |
35 | public ProfileList ProfileList { get => profileList; }
36 | public bool NormalTrigger { get => normalTrigger; set => normalTrigger = value; }
37 |
38 | public LoadProfileViewModel(ProfileList profileList)
39 | {
40 | this.profileList = profileList;
41 |
42 | ProfileIndexChanged += LoadProfileViewModel_ProfileIndexChanged;
43 | }
44 |
45 | public void LoadAction(SpecialAction action)
46 | {
47 | autoUntrigger = action.automaticUntrigger;
48 | string profilename = action.details;
49 | ProfileEntity item = profileList.ProfileListCol.SingleOrDefault(x => x.Name == profilename);
50 | if (item != null)
51 | {
52 | profileIndex = profileList.ProfileListCol.IndexOf(item) + 1;
53 | }
54 | }
55 |
56 | private void LoadProfileViewModel_ProfileIndexChanged(object sender, EventArgs e)
57 | {
58 | UnloadEnabledChanged?.Invoke(this, EventArgs.Empty);
59 | }
60 |
61 | public void SaveAction(SpecialAction action, bool edit = false)
62 | {
63 | if (profileIndex > 0)
64 | {
65 | string profilename = profileList.ProfileListCol[profileIndex - 1].Name;
66 | if (action.ucontrols == null)
67 | {
68 | action.ucontrols = string.Empty;
69 | }
70 |
71 | Global.SaveAction(action.name, action.controls, 3, profilename, edit,
72 | action.ucontrols +
73 | (autoUntrigger ? (action.ucontrols.Length > 0 ? "/" : "") + "AutomaticUntrigger" : ""));
74 | }
75 | }
76 |
77 | public override bool IsValid(SpecialAction action)
78 | {
79 | ClearOldErrors();
80 |
81 | bool valid = true;
82 | List profileIndexErrors = new List();
83 |
84 | if (profileIndex == 0)
85 | {
86 | profileIndexErrors.Add("No profile given");
87 | errors["ProfileIndex"] = profileIndexErrors;
88 | RaiseErrorsChanged("ProfileIndex");
89 | }
90 |
91 | return valid;
92 | }
93 |
94 | public override void ClearOldErrors()
95 | {
96 | if (errors.Count > 0)
97 | {
98 | errors.Clear();
99 | RaiseErrorsChanged("ProfileIndex");
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/SpecialActions/MacroViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using DS4Windows;
9 | using DS4WinWPF.DS4Forms.ViewModels.Util;
10 |
11 | namespace DS4WinWPF.DS4Forms.ViewModels.SpecialActions
12 | {
13 | public class MacroViewModel : NotifyDataErrorBase
14 | {
15 | private bool useScanCode;
16 | private bool runTriggerRelease;
17 | private bool syncRun;
18 | private bool keepKeyState;
19 | private bool repeatHeld;
20 | private List macro = new List(1);
21 | private string macrostring;
22 |
23 | public bool UseScanCode { get => useScanCode; set => useScanCode = value; }
24 | public bool RunTriggerRelease { get => runTriggerRelease; set => runTriggerRelease = value; }
25 | public bool SyncRun { get => syncRun; set => syncRun = value; }
26 | public bool KeepKeyState { get => keepKeyState; set => keepKeyState = value; }
27 | public bool RepeatHeld { get => repeatHeld; set => repeatHeld = value; }
28 | public List Macro { get => macro; set => macro = value; }
29 | public string Macrostring { get => macrostring;
30 | set
31 | {
32 | macrostring = value;
33 | MacrostringChanged?.Invoke(this, EventArgs.Empty);
34 | }
35 | }
36 |
37 | public event EventHandler MacrostringChanged;
38 |
39 | public void LoadAction(SpecialAction action)
40 | {
41 | macro = action.macro;
42 | if (action.macro.Count > 0)
43 | {
44 | MacroParser macroParser = new MacroParser(action.macro.ToArray());
45 | macroParser.LoadMacro();
46 | macrostring = string.Join(", ", macroParser.GetMacroStrings());
47 | }
48 |
49 | useScanCode = action.keyType.HasFlag(DS4KeyType.ScanCode);
50 | runTriggerRelease = action.pressRelease;
51 | syncRun = action.synchronized;
52 | keepKeyState = action.keepKeyState;
53 | repeatHeld = action.keyType.HasFlag(DS4KeyType.RepeatMacro);
54 | }
55 |
56 | public DS4ControlSettings PrepareSettings()
57 | {
58 | DS4ControlSettings settings = new DS4ControlSettings(DS4Controls.None);
59 | settings.action.actionMacro = macro.ToArray();
60 | settings.actionType = DS4ControlSettings.ActionType.Macro;
61 | settings.keyType = DS4KeyType.Macro;
62 | if (repeatHeld)
63 | {
64 | settings.keyType |= DS4KeyType.RepeatMacro;
65 | }
66 |
67 | return settings;
68 | }
69 |
70 | public void SaveAction(SpecialAction action, bool edit = false)
71 | {
72 | List extrasList = new List();
73 | extrasList.Add(useScanCode ? "Scan Code" : null);
74 | extrasList.Add(runTriggerRelease ? "RunOnRelease" : null);
75 | extrasList.Add(syncRun ? "Sync" : null);
76 | extrasList.Add(keepKeyState ? "KeepKeyState" : null);
77 | extrasList.Add(repeatHeld ? "Repeat" : null);
78 | Global.SaveAction(action.name, action.controls, 1, string.Join("/", macro), edit,
79 | string.Join("/", extrasList.Where(s => !string.IsNullOrEmpty(s))));
80 | }
81 |
82 | public void UpdateMacroString()
83 | {
84 | string temp = "";
85 | if (macro.Count > 0)
86 | {
87 | MacroParser macroParser = new MacroParser(macro.ToArray());
88 | macroParser.LoadMacro();
89 | temp = string.Join(", ", macroParser.GetMacroStrings());
90 | }
91 |
92 | Macrostring = temp;
93 | }
94 |
95 | public override bool IsValid(SpecialAction action)
96 | {
97 | ClearOldErrors();
98 |
99 | bool valid = true;
100 | List macroErrors = new List();
101 |
102 | if (macro.Count == 0)
103 | {
104 | valid = false;
105 | macroErrors.Add("No macro defined");
106 | errors["Macro"] = macroErrors;
107 | RaiseErrorsChanged("Macro");
108 | }
109 |
110 | return valid;
111 | }
112 |
113 | public override void ClearOldErrors()
114 | {
115 | if (errors.Count > 0)
116 | {
117 | errors.Clear();
118 | RaiseErrorsChanged("Macro");
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/SpecialActions/SASteeringWheelViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using DS4Windows;
7 | using DS4WinWPF.DS4Forms.ViewModels.Util;
8 |
9 | namespace DS4WinWPF.DS4Forms.ViewModels.SpecialActions
10 | {
11 | public class SASteeringWheelViewModel : NotifyDataErrorBase
12 | {
13 | private double delay;
14 | public double Delay { get => delay; set => delay = value; }
15 |
16 | public void LoadAction(SpecialAction action)
17 | {
18 | delay = action.delayTime;
19 | }
20 |
21 | public void SaveAction(SpecialAction action, bool edit = false)
22 | {
23 | Global.SaveAction(action.name, action.controls, 8, delay.ToString("#.##", Global.configFileDecimalCulture), edit);
24 | }
25 |
26 | public override bool IsValid(SpecialAction action)
27 | {
28 | ClearOldErrors();
29 |
30 | bool valid = true;
31 | List delayErrors = new List();
32 |
33 | if (delay < 0 || delay > 60)
34 | {
35 | delayErrors.Add("Delay out of range");
36 | errors["Delay"] = delayErrors;
37 | RaiseErrorsChanged("Delay");
38 | }
39 |
40 | return valid;
41 | }
42 |
43 | public override void ClearOldErrors()
44 | {
45 | if (errors.Count > 0)
46 | {
47 | errors.Clear();
48 | RaiseErrorsChanged("Delay");
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/Util/EnumChoiceSelection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4WinWPF.DS4Forms.ViewModels.Util
4 | {
5 | public class EnumChoiceSelection
6 | {
7 | private string displayName;
8 | public string DisplayName { get => displayName; }
9 |
10 | private T choiceValue;
11 | public T ChoiceValue
12 | {
13 | get => choiceValue;
14 | set => choiceValue = value;
15 | }
16 |
17 | public EnumChoiceSelection(string name, T currentValue)
18 | {
19 | displayName = name;
20 | choiceValue = currentValue;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Forms/ViewModels/Util/NotifyDataErrorBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 |
6 | namespace DS4WinWPF.DS4Forms.ViewModels.Util
7 | {
8 | public abstract class NotifyDataErrorBase : INotifyDataErrorInfo
9 | {
10 | protected Dictionary> errors =
11 | new Dictionary>();
12 |
13 | public bool HasErrors => errors.Count > 0;
14 |
15 | public event EventHandler ErrorsChanged;
16 |
17 | public IEnumerable GetErrors(string propertyName)
18 | {
19 | errors.TryGetValue(propertyName, out List errorsForName);
20 | return errorsForName;
21 | }
22 |
23 | public void RaiseErrorsChanged(string propertyName)
24 | {
25 | ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
26 | }
27 |
28 | public abstract bool IsValid(DS4Windows.SpecialAction action);
29 | public abstract void ClearOldErrors();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Library/DS4StateExposed.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace DS4Windows
3 | {
4 | public class DS4StateExposed
5 | {
6 | private DS4State _state;
7 |
8 | public DS4StateExposed()
9 | {
10 | _state = new DS4State();
11 | }
12 |
13 | public DS4StateExposed(DS4State state)
14 | {
15 | _state = state;
16 | }
17 |
18 | bool Square { get { return _state.Square; } }
19 | bool Triangle { get { return _state.Triangle; } }
20 | bool Circle { get { return _state.Circle; } }
21 | bool Cross { get { return _state.Cross; } }
22 | bool DpadUp { get { return _state.DpadUp; } }
23 | bool DpadDown { get { return _state.DpadDown; } }
24 | bool DpadLeft { get { return _state.DpadLeft; } }
25 | bool DpadRight { get { return _state.DpadRight; } }
26 | bool L1 { get { return _state.L1; } }
27 | bool L3 { get { return _state.L3; } }
28 | bool R1 { get { return _state.R1; } }
29 | bool R3 { get { return _state.R3; } }
30 | bool Share { get { return _state.Share; } }
31 | bool Options { get { return _state.Options; } }
32 | bool PS { get { return _state.PS; } }
33 | bool Touch1 { get { return _state.Touch1; } }
34 | bool Touch2 { get { return _state.Touch2; } }
35 | bool TouchButton { get { return _state.TouchButton; } }
36 | bool Touch1Finger { get { return _state.Touch1Finger; } }
37 | bool Touch2Fingers { get { return _state.Touch2Fingers; } }
38 | byte LX { get { return _state.LX; } }
39 | byte RX { get { return _state.RX; } }
40 | byte LY { get { return _state.LY; } }
41 | byte RY { get { return _state.RY; } }
42 | byte L2 { get { return _state.L2; } }
43 | byte R2 { get { return _state.R2; } }
44 | int Battery { get { return _state.Battery; } }
45 |
46 | public SixAxis Motion
47 | {
48 | get => _state.Motion;
49 | }
50 |
51 | public int GyroYaw { get { return _state.Motion.gyroYaw; } }
52 | public int getGyroYaw()
53 | {
54 | return _state.Motion.gyroYaw;
55 | }
56 |
57 | public int GyroPitch { get { return _state.Motion.gyroPitch; } }
58 | public int getGyroPitch()
59 | {
60 | return _state.Motion.gyroPitch;
61 | }
62 |
63 | public int GyroRoll { get { return _state.Motion.gyroRoll; } }
64 | public int getGyroRoll()
65 | {
66 | return _state.Motion.gyroRoll;
67 | }
68 |
69 | public int AccelX { get { return _state.Motion.accelX; } }
70 | public int getAccelX()
71 | {
72 | return _state.Motion.accelX;
73 | }
74 |
75 | public int AccelY { get { return _state.Motion.accelY; } }
76 | public int getAccelY()
77 | {
78 | return _state.Motion.accelY;
79 | }
80 |
81 | public int AccelZ { get { return _state.Motion.accelZ; } }
82 | public int getAccelZ()
83 | {
84 | return _state.Motion.accelZ;
85 | }
86 |
87 | public int OutputAccelX { get { return _state.Motion.outputAccelX; } }
88 | public int getOutputAccelX()
89 | {
90 | return _state.Motion.outputAccelX;
91 | }
92 |
93 | public int OutputAccelY { get { return _state.Motion.outputAccelY; } }
94 | public int getOutputAccelY()
95 | {
96 | return _state.Motion.outputAccelY;
97 | }
98 |
99 | public int OutputAccelZ { get { return _state.Motion.outputAccelZ; } }
100 | public int getOutputAccelZ()
101 | {
102 | return _state.Motion.outputAccelZ;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Library/InputDevices/InputDeviceFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DS4Windows.InputDevices
8 | {
9 | public enum InputDeviceType : uint
10 | {
11 | DS4,
12 | SwitchPro,
13 | JoyConL,
14 | JoyConR,
15 | DualSense,
16 | }
17 |
18 | public abstract class InputDeviceFactory
19 | {
20 | public static DS4Device CreateDevice(InputDeviceType tempType,
21 | HidDevice hidDevice, string disName, VidPidFeatureSet featureSet = VidPidFeatureSet.DefaultDS4)
22 | {
23 | DS4Device temp = null;
24 |
25 | switch(tempType)
26 | {
27 | case InputDeviceType.DS4:
28 | temp = new DS4Device(hidDevice, disName, featureSet);
29 | break;
30 | case InputDeviceType.SwitchPro:
31 | temp = new SwitchProDevice(hidDevice, disName, featureSet);
32 | break;
33 | case InputDeviceType.JoyConL:
34 | case InputDeviceType.JoyConR:
35 | temp = new JoyConDevice(hidDevice, disName, featureSet);
36 | break;
37 | case InputDeviceType.DualSense:
38 | temp = new DualSenseDevice(hidDevice, disName, featureSet);
39 | break;
40 | }
41 |
42 | return temp;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/DS4Windows/DS4Library/InputDevices/TriggerEffects.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DS4Windows.InputDevices
8 | {
9 | public enum TriggerEffects : ushort
10 | {
11 | None,
12 | Rigid,
13 | Pulse,
14 | FullClick,
15 | }
16 |
17 | public enum TriggerId : ushort
18 | {
19 | Trigger0,
20 | LeftTrigger = Trigger0,
21 | Trigger1,
22 | RightTrigger = Trigger1,
23 | }
24 |
25 | public struct TriggerEffectSettings
26 | {
27 | public byte maxValue;
28 | public byte startValue;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/DS4Windows/DS4W.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/DS4W.ico
--------------------------------------------------------------------------------
/DS4Windows/DateTimeJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text.Json;
4 | using System.Text.Json.Serialization;
5 |
6 | namespace DS4WinWPF
7 | {
8 | public class DateTimeJsonConverter
9 | {
10 | public class DateTimeConverterUsingDateTimeParse : JsonConverter
11 | {
12 | public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
13 | {
14 | Debug.Assert(typeToConvert == typeof(DateTime));
15 | return DateTime.Parse(reader.GetString());
16 | }
17 |
18 | public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
19 | {
20 | writer.WriteStringValue(value.ToString());
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/DS4Windows/HidLibrary/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace DS4Windows
4 | {
5 | public static class Extensions
6 | {
7 | public static string ToUTF8String(this byte[] buffer)
8 | {
9 | var value = Encoding.UTF8.GetString(buffer);
10 | return value.Remove(value.IndexOf((char)0));
11 | }
12 |
13 | public static string ToUTF16String(this byte[] buffer)
14 | {
15 | var value = Encoding.Unicode.GetString(buffer);
16 | return value.Remove(value.IndexOf((char)0));
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/DS4Windows/HidLibrary/HidDeviceAttributes.cs:
--------------------------------------------------------------------------------
1 | namespace DS4Windows
2 | {
3 | public class HidDeviceAttributes
4 | {
5 | internal HidDeviceAttributes(NativeMethods.HIDD_ATTRIBUTES attributes)
6 | {
7 | VendorId = attributes.VendorID;
8 | ProductId = attributes.ProductID;
9 | Version = attributes.VersionNumber;
10 |
11 | VendorHexId = "0x" + attributes.VendorID.ToString("X4");
12 | ProductHexId = "0x" + attributes.ProductID.ToString("X4");
13 | }
14 |
15 | public int VendorId { get; private set; }
16 | public int ProductId { get; private set; }
17 | public int Version { get; private set; }
18 | public string VendorHexId { get; set; }
19 | public string ProductHexId { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/DS4Windows/HidLibrary/HidDeviceCapabilities.cs:
--------------------------------------------------------------------------------
1 | namespace DS4Windows
2 | {
3 | public class HidDeviceCapabilities
4 | {
5 | internal HidDeviceCapabilities(NativeMethods.HIDP_CAPS capabilities)
6 | {
7 | Usage = capabilities.Usage;
8 | UsagePage = capabilities.UsagePage;
9 | InputReportByteLength = capabilities.InputReportByteLength;
10 | OutputReportByteLength = capabilities.OutputReportByteLength;
11 | FeatureReportByteLength = capabilities.FeatureReportByteLength;
12 | Reserved = capabilities.Reserved;
13 | NumberLinkCollectionNodes = capabilities.NumberLinkCollectionNodes;
14 | NumberInputButtonCaps = capabilities.NumberInputButtonCaps;
15 | NumberInputValueCaps = capabilities.NumberInputValueCaps;
16 | NumberInputDataIndices = capabilities.NumberInputDataIndices;
17 | NumberOutputButtonCaps = capabilities.NumberOutputButtonCaps;
18 | NumberOutputValueCaps = capabilities.NumberOutputValueCaps;
19 | NumberOutputDataIndices = capabilities.NumberOutputDataIndices;
20 | NumberFeatureButtonCaps = capabilities.NumberFeatureButtonCaps;
21 | NumberFeatureValueCaps = capabilities.NumberFeatureValueCaps;
22 | NumberFeatureDataIndices = capabilities.NumberFeatureDataIndices;
23 |
24 | }
25 |
26 | public ushort Usage { get; private set; }
27 | public ushort UsagePage { get; private set; }
28 | public short InputReportByteLength { get; private set; }
29 | public short OutputReportByteLength { get; private set; }
30 | public short FeatureReportByteLength { get; private set; }
31 | public short[] Reserved { get; private set; }
32 | public short NumberLinkCollectionNodes { get; private set; }
33 | public short NumberInputButtonCaps { get; private set; }
34 | public short NumberInputValueCaps { get; private set; }
35 | public short NumberInputDataIndices { get; private set; }
36 | public short NumberOutputButtonCaps { get; private set; }
37 | public short NumberOutputValueCaps { get; private set; }
38 | public short NumberOutputDataIndices { get; private set; }
39 | public short NumberFeatureButtonCaps { get; private set; }
40 | public short NumberFeatureValueCaps { get; private set; }
41 | public short NumberFeatureDataIndices { get; private set; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/DS4Windows/HidLibrary/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Ultraviolet Catastrophe
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/DS4Windows/LogItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DS4WinWPF
8 | {
9 | public class LogItem
10 | {
11 | private DateTime datetime;
12 | private string message;
13 | private bool warning;
14 |
15 | public DateTime Datetime { get => datetime; set => datetime = value; }
16 | public string Message { get => message; set => message = value; }
17 | public bool Warning { get => warning; set => warning = value; }
18 | public string Color
19 | {
20 | get
21 | {
22 | return warning ? "Red" : "Black";
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/DS4Windows/LogWriter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 |
4 | namespace DS4WinWPF
5 | {
6 | public class LogWriter
7 | {
8 | private string filename;
9 | private List logCol;
10 |
11 | public LogWriter(string filename, List col)
12 | {
13 | this.filename = filename;
14 | logCol = col;
15 | }
16 |
17 | public void Process()
18 | {
19 | List outputLines = new List();
20 | foreach(LogItem item in logCol)
21 | {
22 | outputLines.Add($"{item.Datetime}: {item.Message}");
23 | }
24 |
25 | try
26 | {
27 | StreamWriter stream = new StreamWriter(filename);
28 | foreach(string line in outputLines)
29 | {
30 | stream.WriteLine(line);
31 | }
32 | stream.Close();
33 | }
34 | catch { }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/DS4Windows/LoggerHolder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NLog;
7 | using NLog.Targets.Wrappers;
8 |
9 | namespace DS4WinWPF
10 | {
11 | public class LoggerHolder
12 | {
13 | private Logger logger;// = LogManager.GetCurrentClassLogger();
14 | public Logger Logger { get => logger; }
15 |
16 | public LoggerHolder(DS4Windows.ControlService service)
17 | {
18 | var configuration = LogManager.Configuration;
19 | var wrapTarget = configuration.FindTargetByName("logfile") as WrapperTargetBase;
20 | var fileTarget = wrapTarget.WrappedTarget as NLog.Targets.FileTarget;
21 | fileTarget.FileName = $@"{DS4Windows.Global.appdatapath}\Logs\ds4windows_log.txt";
22 | fileTarget.ArchiveFileName = $@"{DS4Windows.Global.appdatapath}\Logs\ds4windows_log_{{#}}.txt";
23 | LogManager.Configuration = configuration;
24 | LogManager.ReconfigExistingLoggers();
25 |
26 | logger = LogManager.GetCurrentClassLogger();
27 |
28 | service.Debug += WriteToLog;
29 | DS4Windows.AppLogger.GuiLog += WriteToLog;
30 | }
31 |
32 | private void WriteToLog(object sender, DS4Windows.DebugEventArgs e)
33 | {
34 | if (e.Temporary)
35 | {
36 | return;
37 | }
38 |
39 | if (!e.Warning)
40 | {
41 | logger.Info(e.Data);
42 | }
43 | else
44 | {
45 | logger.Warn(e.Data);
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/DS4Windows/NLog.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DS4Windows/OneEuroFilter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Diagnostics;
5 |
6 | namespace Sensorit.Base
7 | {
8 | public class OneEuroFilter
9 | {
10 | public OneEuroFilter(double minCutoff, double beta)
11 | {
12 | firstTime = true;
13 | this.minCutoff = minCutoff;
14 | this.beta = beta;
15 |
16 | xFilt = new LowpassFilter();
17 | dxFilt = new LowpassFilter();
18 | dcutoff = 1;
19 | }
20 |
21 | protected bool firstTime;
22 | protected double minCutoff;
23 | protected double beta;
24 | protected LowpassFilter xFilt;
25 | protected LowpassFilter dxFilt;
26 | protected double dcutoff;
27 |
28 | public double MinCutoff
29 | {
30 | get { return minCutoff; }
31 | set { minCutoff = value; }
32 | }
33 |
34 | public double Beta
35 | {
36 | get { return beta; }
37 | set { beta = value; }
38 | }
39 |
40 | public double Filter(double x, double rate)
41 | {
42 | double dx = firstTime ? 0 : (x - xFilt.Last()) * rate;
43 | if (firstTime)
44 | {
45 | firstTime = false;
46 | }
47 |
48 | var edx = dxFilt.Filter(dx, Alpha(rate, dcutoff));
49 | var cutoff = minCutoff + beta * Math.Abs(edx);
50 |
51 | return xFilt.Filter(x, Alpha(rate, cutoff));
52 | }
53 |
54 | protected double Alpha(double rate, double cutoff)
55 | {
56 | var tau = 1.0 / (2 * Math.PI * cutoff);
57 | var te = 1.0 / rate;
58 | return 1.0 / (1.0 + tau / te);
59 | }
60 |
61 | public void Reset()
62 | {
63 | xFilt.Reset();
64 | dxFilt.Reset();
65 | }
66 | }
67 |
68 | public class LowpassFilter
69 | {
70 | public LowpassFilter()
71 | {
72 | firstTime = true;
73 | }
74 |
75 | protected bool firstTime;
76 | protected double hatXPrev;
77 |
78 | public double Last()
79 | {
80 | return hatXPrev;
81 | }
82 |
83 | public double Filter(double x, double alpha)
84 | {
85 | double hatX = 0;
86 | if (firstTime)
87 | {
88 | firstTime = false;
89 | hatX = x;
90 | }
91 | else
92 | hatX = alpha * x + (1 - alpha) * hatXPrev;
93 |
94 | hatXPrev = hatX;
95 |
96 | return hatX;
97 | }
98 |
99 | public void Reset()
100 | {
101 | firstTime = true;
102 | hatXPrev = 0.0;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/DS4Windows/ProfileEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace DS4WinWPF
9 | {
10 | public class ProfileEntity
11 | {
12 | private string name;
13 | public string Name
14 | {
15 | get => name;
16 | set
17 | {
18 | if (name == value) return;
19 | name = value;
20 | NameChanged?.Invoke(this, EventArgs.Empty);
21 | }
22 | }
23 |
24 | public event EventHandler NameChanged;
25 | public event EventHandler ProfileSaved;
26 | public event EventHandler ProfileDeleted;
27 |
28 | public void DeleteFile()
29 | {
30 | if (!string.IsNullOrWhiteSpace(name))
31 | {
32 | string filepath = DS4Windows.Global.appdatapath + @"\Profiles\" + name + ".xml";
33 | if (File.Exists(filepath))
34 | {
35 | File.Delete(filepath);
36 | ProfileDeleted?.Invoke(this, EventArgs.Empty);
37 | }
38 | }
39 | }
40 |
41 | public void SaveProfile(int deviceNum)
42 | {
43 | if (!string.IsNullOrWhiteSpace(name))
44 | {
45 | DS4Windows.Global.SaveProfile(deviceNum, name);
46 | DS4Windows.Global.CacheExtraProfileInfo(deviceNum);
47 | }
48 | }
49 |
50 | public void FireSaved()
51 | {
52 | ProfileSaved?.Invoke(this, EventArgs.Empty);
53 | }
54 |
55 | public void RenameProfile(string newProfileName)
56 | {
57 | string oldFilePath = Path.Combine(DS4Windows.Global.appdatapath,
58 | "Profiles", $"{name}.xml");
59 |
60 | string newFilePath = Path.Combine(DS4Windows.Global.appdatapath,
61 | "Profiles", $"{newProfileName}.xml");
62 |
63 | if (File.Exists(oldFilePath) && !File.Exists(newFilePath))
64 | {
65 | File.Move(oldFilePath, newFilePath);
66 | // Send NameChanged event so controls get updated with new name
67 | Name = newProfileName;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/DS4Windows/ProfileList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows.Data;
9 |
10 | namespace DS4WinWPF
11 | {
12 | public class ProfileList
13 | {
14 | private object _proLockobj = new object();
15 | private ObservableCollection profileListCol =
16 | new ObservableCollection();
17 |
18 | public ObservableCollection ProfileListCol { get => profileListCol; set => profileListCol = value; }
19 |
20 | public ProfileList()
21 | {
22 | BindingOperations.EnableCollectionSynchronization(profileListCol, _proLockobj);
23 | }
24 |
25 | public void Refresh()
26 | {
27 | profileListCol.Clear();
28 | string[] profiles = Directory.GetFiles(DS4Windows.Global.appdatapath + @"\Profiles\");
29 | foreach (string s in profiles)
30 | {
31 | if (s.EndsWith(".xml"))
32 | {
33 | ProfileEntity item = new ProfileEntity()
34 | {
35 | Name = Path.GetFileNameWithoutExtension(s)
36 | };
37 |
38 | profileListCol.Add(item);
39 | }
40 | }
41 | }
42 |
43 | public void AddProfileSort(string profilename)
44 | {
45 | int idx = 0;
46 | bool inserted = false;
47 | foreach (ProfileEntity entry in profileListCol)
48 | {
49 | if (entry.Name.CompareTo(profilename) > 0)
50 | {
51 | profileListCol.Insert(idx, new ProfileEntity() { Name = profilename });
52 | inserted = true;
53 | break;
54 | }
55 | idx++;
56 | }
57 |
58 | if (!inserted)
59 | {
60 | profileListCol.Add(new ProfileEntity() { Name = profilename });
61 | }
62 | }
63 |
64 | public void RemoveProfile(string profile)
65 | {
66 | var selectedEntity = profileListCol.SingleOrDefault(x => x.Name == profile);
67 | if (selectedEntity != null)
68 | {
69 | int selectedIndex = profileListCol.IndexOf(selectedEntity);
70 | profileListCol.RemoveAt(selectedIndex);
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/DS4Windows/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 |
4 | [assembly: ThemeInfo(
5 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
6 | //(used if a resource is not found in the page,
7 | // or application resource dictionaries)
8 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
9 | //(used if a resource is not found in the page,
10 | // app, or any theme specific resource dictionaries)
11 | )]
12 |
--------------------------------------------------------------------------------
/DS4Windows/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DS4WinWPF.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/DS4Windows/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DS4Windows/ReaderWriteLockSlimWrappers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace DS4Windows
5 | {
6 | public class ReadLocker : IDisposable
7 | {
8 | private ReaderWriterLockSlim _lockerInstance;
9 |
10 | public ReadLocker(ReaderWriterLockSlim lockerInstance)
11 | {
12 | _lockerInstance = lockerInstance;
13 | _lockerInstance.EnterReadLock();
14 | }
15 |
16 | public void Dispose()
17 | {
18 | _lockerInstance.ExitReadLock();
19 | _lockerInstance = null;
20 | }
21 | }
22 |
23 | public class WriteLocker : IDisposable
24 | {
25 | private ReaderWriterLockSlim _lockerInstance;
26 | private bool IsDisposed => _lockerInstance == null;
27 |
28 | public WriteLocker(ReaderWriterLockSlim lockerInstance)
29 | {
30 | _lockerInstance = lockerInstance;
31 | _lockerInstance.EnterWriteLock();
32 | }
33 |
34 | public void Dispose()
35 | {
36 | if (IsDisposed)
37 | {
38 | throw new ObjectDisposedException(this.ToString());
39 | }
40 |
41 | _lockerInstance.ExitWriteLock();
42 | _lockerInstance = null;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/DS4Windows/Resources/360 fades.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/360 fades.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/360 highlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/360 highlight.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/360 map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/360 map.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/A.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/A.PNG
--------------------------------------------------------------------------------
/DS4Windows/Resources/B.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/B.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/BACK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/BACK.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/BT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/BT.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/BT_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/BT_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DOWN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DOWN.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4 Config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4 Config.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4 Config_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4 Config_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4 Controller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4 Controller.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4 lightbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4 lightbar.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Circle.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Cross.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Cross.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Down.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_L1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_L1.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_L2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_L2.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_LS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_LS.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Left.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_PS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_PS.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_R1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_R1.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_R2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_R2.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_RS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_RS.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Right.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Share.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Square.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_TouchLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_TouchLeft.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_TouchMulti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_TouchMulti.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_TouchRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_TouchRight.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_TouchUpper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_TouchUpper.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Triangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Triangle.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_Up.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4-Config_options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4-Config_options.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4.ico
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4W - Black.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4W - Black.ico
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4W - White.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4W - White.ico
--------------------------------------------------------------------------------
/DS4Windows/Resources/DS4W.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/DS4W.ico
--------------------------------------------------------------------------------
/DS4Windows/Resources/LB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LB.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LEFT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LEFT.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LS.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LSD.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LSL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LSL.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LSR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LSR.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LSU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LSU.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/LT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/LT.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/Pairmode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/Pairmode.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RB.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RIGHT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RIGHT.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RS.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RSD.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RSL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RSL.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RSR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RSR.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RSU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RSU.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/RT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/RT.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/Red Circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/Red Circle.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/START.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/START.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/UP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/UP.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/USB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/USB.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/USB_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/USB_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/UpperTouch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/UpperTouch.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/X.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/X.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/Y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/Y.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/cancel.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/cancel_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/cancel_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/checked.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/checked_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/checked_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/clock.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/clock_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/clock_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/copy.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/copy_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/copy_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/delete.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/delete_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/delete_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/edit.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/edit_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/edit_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/export.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/export_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/export_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/import.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/import.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/import_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/import_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/key-solid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/key-solid.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/key-solid_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/key-solid_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/keydown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/keydown.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/keydown_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/keydown_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/keyup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/keyup.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/keyup_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/keyup_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/left touch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/left touch.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/mouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/mouse.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/newprofile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/newprofile.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/newprofile_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/newprofile_white.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/none.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/rainbow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/rainbow.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/rainbowC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/rainbowC.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/rainbowCCrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/rainbowCCrop.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/right touch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/right touch.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/saveprofile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/saveprofile.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/size.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/social/GitHub-Mark-64px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/social/GitHub-Mark-64px.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/social/GitHub-Mark-Light-64px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/social/GitHub-Mark-Light-64px.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/social/bittube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/social/bittube.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/social/twitter_logo_initial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/social/twitter_logo_initial.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/social/youtube_social_icon_red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/social/youtube_social_icon_red.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/x360test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/x360test.png
--------------------------------------------------------------------------------
/DS4Windows/Resources/xbox_360_controller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/Resources/xbox_360_controller.png
--------------------------------------------------------------------------------
/DS4Windows/StatusLogMsg.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DS4WinWPF
4 | {
5 | public class StatusLogMsg
6 | {
7 | private string message;
8 | private bool warning;
9 | public string Message
10 | {
11 | get => message;
12 | set
13 | {
14 | if (message == value) return;
15 | message = value;
16 | MessageChanged?.Invoke(this, EventArgs.Empty);
17 | }
18 | }
19 |
20 | public event EventHandler MessageChanged;
21 |
22 | public bool Warning { get => warning;
23 | set
24 | {
25 | if (warning == value) return;
26 | warning = value;
27 | WarningChanged?.Invoke(this, EventArgs.Empty);
28 | ColorChanged?.Invoke(this, EventArgs.Empty);
29 | }
30 | }
31 |
32 | public event EventHandler WarningChanged;
33 |
34 | public string Color
35 | {
36 | get
37 | {
38 | return warning ? "Red" : "#FF696969";
39 | }
40 | }
41 |
42 | public event EventHandler ColorChanged;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/DS4Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/DS4Windows/libs/x64/FakerInputWrapper/FakerInputDll.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x64/FakerInputWrapper/FakerInputDll.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x64/FakerInputWrapper/FakerInputWrapper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x64/FakerInputWrapper/FakerInputWrapper.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x64/Nefarius.ViGEm.Client/Nefarius.ViGEm.Client.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x64/Nefarius.ViGEm.Client/Nefarius.ViGEm.Client.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x64/SharpOSC/SharpOSC.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x64/SharpOSC/SharpOSC.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x86/FakerInputWrapper/FakerInputDll.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x86/FakerInputWrapper/FakerInputDll.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x86/FakerInputWrapper/FakerInputWrapper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x86/FakerInputWrapper/FakerInputWrapper.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x86/Nefarius.ViGEm.Client/Nefarius.ViGEm.Client.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x86/Nefarius.ViGEm.Client/Nefarius.ViGEm.Client.dll
--------------------------------------------------------------------------------
/DS4Windows/libs/x86/SharpOSC/SharpOSC.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/DS4Windows/libs/x86/SharpOSC/SharpOSC.dll
--------------------------------------------------------------------------------
/DS4Windows/newest.txt:
--------------------------------------------------------------------------------
1 | 3.1.2
2 |
--------------------------------------------------------------------------------
/DS4Windows/runtimeconfig.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "additionalProbingPaths": [
3 | "./Lang/"
4 | ]
5 | }
--------------------------------------------------------------------------------
/DS4WindowsWPF.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29306.81
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DS4WinWPF", "DS4Windows\DS4WinWPF.csproj", "{0135A24D-5DBB-483C-9FC5-9A869E23DA9A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Debug|x64.ActiveCfg = Debug|x64
17 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Debug|x64.Build.0 = Debug|x64
18 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Debug|x86.ActiveCfg = Debug|x86
19 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Debug|x86.Build.0 = Debug|x86
20 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Release|x64.ActiveCfg = Release|x64
21 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Release|x64.Build.0 = Release|x64
22 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Release|x86.ActiveCfg = Release|x86
23 | {0135A24D-5DBB-483C-9FC5-9A869E23DA9A}.Release|x86.Build.0 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {2BE30981-376A-4DEA-B2B1-247BADB864FC}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Travis Nickles
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | This project includes the source code of some third party projects. This file
2 | will attempt to document some third party source code that is used in the
3 | DS4Windows source code and state the original source.
4 |
5 | Crc32:
6 | https://github.com/dariogriffo/Crc32
7 |
8 | Font Awesome:
9 | https://fontawesome.com/license
10 |
11 | 1€ Filter (C# version):
12 | http://cristal.univ-lille.fr/~casiez/1euro/OneEuroFilter.cs
13 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # TODO
2 |
3 | * Add hooks to keep track of active display monitors for Absolute Mouse
4 | * Figure out desired options for Absolute Mouse support
5 | * ~~Change Full Click trigger effect for DualSense. Interpolate and take profile max zone into account (Have a draft that needs more work. Delay implementing for now)~~
6 | * Add more localization ready strings
7 | * ~~Make task related helper GUI app for launching DS4Windows. Might use for other use cases as well. (Poor startup time by comparison)~~
8 | * Add absolute mouse options for various output types (Sticks and Touchpad)
9 | * ~~Include PurgeOldXInput helper app~~
10 | * ~~Look into final DS4Updater check in DS4Updater app. Batch script seems to get launched even when the updater is already up to date~~
11 | * ~~Bundle trimmed ManagedDevcon assembly with PurgeOldXInput. DIFxAPI causing false positivies in VirusTotal.~~
12 | * ~~Determine output behavior for Outer Bind Button. Currently treated as a virtual trigger. Steam treats its version like a normal button (no analog). Might change later.~~
13 | * ~~Test Steam Input Gyro vs Touchpad mouse action priority. (Tested. Output actions are added together. Do not want)~~
14 | * ~~Add Button Wheel sensitivity setting of some kind. (Forget it. Just increase the current time delta used)~~
15 | * ~~Add Max Output Force option for Gyro Mouse-like Joystick~~
16 | * Try to add some form of Action Set support. Really missing playing Mass Effect 1 and 2
17 |
--------------------------------------------------------------------------------
/contributors.txt:
--------------------------------------------------------------------------------
1 | Travis Nickles (Ryochan7)
2 | AnessZurba
3 | avsha114
4 | bernspedras
5 | carloshbcabral
6 | DandelionSprout
7 | dante38
8 | dondrakon
9 | Flo082002
10 | firodj
11 | Geroyuni
12 | GreySole
13 | Haamar
14 | hpesoj
15 | jdanders
16 | jdfeng
17 | jmg2k
18 | joaopedrogomes
19 | justalemon
20 | Kamilczak020
21 | Кладовая
22 | Korney Czukowski (czukowski)
23 | Leonardo Melati (Leomelati)
24 | MakiseKurisu
25 | mayawei
26 | mika-n
27 | MikeCZ23
28 | nefarius
29 | nelitow
30 | olokos
31 | peter9811
32 | Rajko Stojadinovic (rajkosto)
33 | RedDevilus
34 | RokasKil
35 | sabihoshi
36 | Sander0542
37 | shikulja
38 | sitiom
39 | SyaoranChang
40 | sergejkiller
41 | SteelShot
42 | stryblt
43 | toshixm
44 | tpneill
45 | wingfixer
46 | xLive
47 | xrossb
48 | Yuki-nyan
49 |
--------------------------------------------------------------------------------
/disabled_device_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/disabled_device_example.png
--------------------------------------------------------------------------------
/disabled_device_example_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/disabled_device_example_small.png
--------------------------------------------------------------------------------
/doc/dev/profile_version_info.md:
--------------------------------------------------------------------------------
1 | ## Profile Version Info
2 |
3 | This document will present some of the distinctive (mostly backwards incompatible)
4 | changes that justify incrementing the version number for the profile schema.
5 | The **config_version** attribute in a profile will describe the last known schema
6 | used to write out a profile. Some older profiles did not contain the
7 | **config_version** attribute so tags used in the profile might have to be examined
8 | to determine an approximate version number corresponding to the schema version.
9 |
10 | ### 5 (DS4Windows 2.1.15)
11 |
12 | Replace old **UseTPforControls** option with a new **TouchpadOutputMode**
13 | option. Will likely be used in the future to allow for more than two
14 | modes for the Touchpad. Adding absolute mouse pointer support is one
15 | idea
16 |
17 | ### 4 (DS4Windows 2.1.6)
18 |
19 | Replace **GyroSmoothing** and **GyroSmoothingWeight** and bundle new tags
20 | in the **GyroMouseSmoothingSettings** group. Allow 1 Euro Filter options
21 |
22 | ### 3 (DS4Windows 2.1.3)
23 |
24 | Version 3 was the first profile schema to have a **config_version**
25 | specified. It was used primarily as a placeholder. I don't know
26 | if the schema really changed from what would be considered
27 | version 2
28 |
29 | ### 2
30 |
31 | Changed default values for **LSDeadZone** and **RSDeadZone**.
32 | Added anti-dead zone info
33 |
34 | ### 1 (DS4Windows 1.4.52)
35 |
36 | Initial schema as used in the last Jays2Kings build (1.4.52)
37 |
--------------------------------------------------------------------------------
/ds4winwpf_screen_20200412.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/ds4winwpf_screen_20200412.png
--------------------------------------------------------------------------------
/extras/ViGEmBusInstaller_DS4Win.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/extras/ViGEmBusInstaller_DS4Win.zip
--------------------------------------------------------------------------------
/extras/Virtual Bus Driver.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ds4windowsapp/DS4Windows/65609b470f53a4f832fb07ac24085d3e28ec15bd/extras/Virtual Bus Driver.zip
--------------------------------------------------------------------------------
/utils/inject_deps_path.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import json, re
4 |
5 | # Check for possible file path arg
6 | if len(sys.argv) != 2:
7 | sys.exit(1)
8 |
9 | # Check if path exists on file system
10 | tempfile = sys.argv[1]
11 | if not os.path.exists(tempfile):
12 | sys.exit(1)
13 |
14 | # Open file
15 | temp_json = None
16 | pattern = re.compile("^DS4Windows/[0-9]+\.[0-9]+\.[0-9]+$")
17 | with open(tempfile) as input_file:
18 | temp_json = json.load(input_file)
19 | for k, v in temp_json["libraries"].items():
20 | test_match = re.match(pattern, k)
21 | if test_match:
22 | temp_json["libraries"][k]["path"] = "./"
23 | break
24 |
25 | #print(temp_json["libraries"])
26 |
27 | # Check for json dict
28 | if not temp_json:
29 | sys.exit(1)
30 |
31 | output_string = json.dumps(temp_json, indent=2)
32 | with open(tempfile, "w") as output_file:
33 | output_file.write(output_string)
34 |
--------------------------------------------------------------------------------