├── .gitignore
├── EDForceFeedback.sln
├── EDForceFeedback
├── App.config
├── EDForceFeedback.csproj
├── FFUtils
│ ├── FFConst.exe
│ ├── csFeedback.exe
│ ├── fedit.exe
│ └── pid1_01.pdf
├── Forces
│ ├── Cargo.ffe
│ ├── CenterSpringXY.ffe
│ ├── Damper.ffe
│ ├── Dock.ffe
│ ├── Gear.ffe
│ ├── Hardpoints.ffe
│ ├── Landed.ffe
│ ├── SuperCruise.ffe
│ ├── Vibrate.ffe
│ └── VibrateSide.ffe
├── Form1.Designer.cs
├── Form1.cs
├── Form1.resx
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── settings.Xbox.json
├── settings.json
├── settingsMSFFB2.json
├── settingsXboxAndCyborg.json
└── settingsXboxAndMSFFB2.json
├── EDForceFeedbackConsole
├── App.config
├── EDForceFeedbackConsole.csproj
├── FFUtils
│ ├── FFConst.exe
│ ├── csFeedback.exe
│ ├── fedit.exe
│ └── pid1_01.pdf
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── Forces
│ ├── Cargo.ffe
│ ├── CenterSpringXY.ffe
│ ├── Damper.ffe
│ ├── Dock.ffe
│ ├── Gear.ffe
│ ├── Hardpoints.ffe
│ ├── Landed.ffe
│ ├── SuperCruise.ffe
│ ├── Vibrate.ffe
│ └── VibrateSide.ffe
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── appsettings.json
├── settings.Xbox.json
├── settings.bak.json
├── settings.json
├── settingsMSFFB2.json
├── settingsXboxAndCyborg.json
└── settingsXboxAndMSFFB2.json
├── ForceFeedback.PNG
├── ForceFeedbackSharpDx
├── ForceFeedbackController.cs
└── ForceFeedbackSharpDx.csproj
├── Journals
├── Client.cs
├── Device.cs
├── DeviceEvents.cs
├── EventConfiguration.cs
├── Journals.csproj
└── Settings.cs
├── LICENSE
├── README.md
├── TestForceFeedback
├── App.config
├── EliteAPIMock.cs
├── EliteShipMock.cs
├── EliteStatusMock.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── Forces
│ ├── Cargo.ffe
│ ├── CenterSpringXY.ffe
│ ├── Damper.ffe
│ ├── Dock.ffe
│ ├── Gear.ffe
│ ├── Hardpoints.ffe
│ ├── Landed.ffe
│ ├── Vibrate.ffe
│ └── VibrateSide.ffe
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── TestForceFeedback.csproj
└── packages.config
└── events.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
--------------------------------------------------------------------------------
/EDForceFeedback.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.13.35828.75 d17.13
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ForceFeedbackSharpDx", "ForceFeedbackSharpDx\ForceFeedbackSharpDx.csproj", "{D3C53E08-943F-4DD8-9939-6CD5858E28AC}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Journals", "Journals\Journals.csproj", "{CF2E9959-F6FE-4E26-89E9-AF7DFAB9099E}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDForceFeedback", "EDForceFeedback\EDForceFeedback.csproj", "{072E80F0-C235-44F2-B93B-747C488B490A}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestForceFeedback", "TestForceFeedback\TestForceFeedback.csproj", "{574005ED-6B12-4092-AC48-71B5B302F8AD}"
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EFF6C1F9-7DEC-431E-8F1B-823AC8CAE114}"
15 | ProjectSection(SolutionItems) = preProject
16 | README.md = README.md
17 | EndProjectSection
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {D3C53E08-943F-4DD8-9939-6CD5858E28AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {D3C53E08-943F-4DD8-9939-6CD5858E28AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {D3C53E08-943F-4DD8-9939-6CD5858E28AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {D3C53E08-943F-4DD8-9939-6CD5858E28AC}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {CF2E9959-F6FE-4E26-89E9-AF7DFAB9099E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {CF2E9959-F6FE-4E26-89E9-AF7DFAB9099E}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {CF2E9959-F6FE-4E26-89E9-AF7DFAB9099E}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {CF2E9959-F6FE-4E26-89E9-AF7DFAB9099E}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {072E80F0-C235-44F2-B93B-747C488B490A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {072E80F0-C235-44F2-B93B-747C488B490A}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {072E80F0-C235-44F2-B93B-747C488B490A}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {072E80F0-C235-44F2-B93B-747C488B490A}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {574005ED-6B12-4092-AC48-71B5B302F8AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {574005ED-6B12-4092-AC48-71B5B302F8AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {574005ED-6B12-4092-AC48-71B5B302F8AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {574005ED-6B12-4092-AC48-71B5B302F8AD}.Release|Any CPU.Build.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {F09A2414-F647-4782-8D23-17387CCD776D}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/EDForceFeedback/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
--------------------------------------------------------------------------------
/EDForceFeedback/EDForceFeedback.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {072E80F0-C235-44F2-B93B-747C488B490A}
8 | Exe
9 | EDForceFeedback
10 | EDForceFeedback
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 | false
18 | publish\
19 | true
20 | Disk
21 | false
22 | Foreground
23 | 7
24 | Days
25 | false
26 | false
27 | true
28 | 0
29 | 2.5.0.%2a
30 | false
31 | true
32 |
33 |
34 |
35 | AnyCPU
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | true
53 |
54 |
55 |
56 | ..\packages\Microsoft.Extensions.Configuration.9.0.3\lib\net462\Microsoft.Extensions.Configuration.dll
57 | True
58 |
59 |
60 | ..\packages\Microsoft.Extensions.Configuration.Abstractions.9.0.3\lib\net462\Microsoft.Extensions.Configuration.Abstractions.dll
61 | True
62 |
63 |
64 | ..\packages\Microsoft.Extensions.Configuration.Binder.9.0.3\lib\net462\Microsoft.Extensions.Configuration.Binder.dll
65 | True
66 |
67 |
68 | ..\packages\Microsoft.Extensions.Configuration.CommandLine.9.0.3\lib\net462\Microsoft.Extensions.Configuration.CommandLine.dll
69 | True
70 |
71 |
72 | ..\packages\Microsoft.Extensions.Configuration.Json.9.0.3\lib\net462\Microsoft.Extensions.Configuration.Json.dll
73 | True
74 |
75 |
76 | ..\packages\Microsoft.Extensions.Configuration.UserSecrets.9.0.3\lib\net462\Microsoft.Extensions.Configuration.UserSecrets.dll
77 | True
78 |
79 |
80 | ..\packages\Microsoft.Extensions.DependencyInjection.9.0.3\lib\net462\Microsoft.Extensions.DependencyInjection.dll
81 | True
82 |
83 |
84 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.9.0.3\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll
85 | True
86 |
87 |
88 | ..\packages\Microsoft.Extensions.FileProviders.Abstractions.9.0.3\lib\net462\Microsoft.Extensions.FileProviders.Abstractions.dll
89 | True
90 |
91 |
92 | ..\packages\Microsoft.Extensions.FileProviders.Physical.9.0.3\lib\net462\Microsoft.Extensions.FileProviders.Physical.dll
93 | True
94 |
95 |
96 | ..\packages\Microsoft.Extensions.FileSystemGlobbing.9.0.3\lib\net462\Microsoft.Extensions.FileSystemGlobbing.dll
97 | True
98 |
99 |
100 | ..\packages\Microsoft.Extensions.Hosting.9.0.3\lib\net462\Microsoft.Extensions.Hosting.dll
101 | True
102 |
103 |
104 | ..\packages\Microsoft.Extensions.Hosting.Abstractions.9.0.3\lib\net462\Microsoft.Extensions.Hosting.Abstractions.dll
105 | True
106 |
107 |
108 | ..\packages\Microsoft.Extensions.Logging.9.0.3\lib\net462\Microsoft.Extensions.Logging.dll
109 | True
110 |
111 |
112 | ..\packages\Microsoft.Extensions.Logging.Abstractions.9.0.3\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll
113 | True
114 |
115 |
116 | ..\packages\Microsoft.Extensions.Logging.Configuration.9.0.3\lib\net462\Microsoft.Extensions.Logging.Configuration.dll
117 | True
118 |
119 |
120 | ..\packages\Microsoft.Extensions.Logging.Console.9.0.3\lib\net462\Microsoft.Extensions.Logging.Console.dll
121 | True
122 |
123 |
124 | ..\packages\Microsoft.Extensions.Logging.EventLog.9.0.3\lib\net462\Microsoft.Extensions.Logging.EventLog.dll
125 | True
126 |
127 |
128 | ..\packages\Microsoft.Extensions.Logging.EventSource.9.0.3\lib\net462\Microsoft.Extensions.Logging.EventSource.dll
129 | True
130 |
131 |
132 | ..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.9.0.3\lib\net462\Microsoft.Extensions.Options.ConfigurationExtensions.dll
133 | True
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 | Always
154 |
155 |
156 | Always
157 |
158 |
159 | Always
160 |
161 |
162 | Always
163 |
164 |
165 | Always
166 |
167 |
168 | Always
169 |
170 |
171 | Always
172 |
173 |
174 | Always
175 |
176 |
177 | Always
178 |
179 |
180 | Always
181 |
182 |
183 |
184 | Always
185 |
186 |
187 | Always
188 |
189 |
190 | Always
191 |
192 |
193 | Always
194 |
195 |
196 | Always
197 |
198 |
199 | Always
200 |
201 |
202 | Always
203 |
204 |
205 | Always
206 |
207 |
208 |
209 |
210 | {cf2e9959-f6fe-4e26-89e9-af7dfab9099e}
211 | Journals
212 |
213 |
214 |
215 |
216 | False
217 | Microsoft .NET Framework 4.8 %28x86 and x64%29
218 | true
219 |
220 |
221 | False
222 | .NET Framework 3.5 SP1
223 | false
224 |
225 |
226 |
227 |
228 | 4.7.0
229 |
230 |
231 | 9.0.3
232 |
233 |
234 | 13.0.3
235 |
236 |
237 | 3.2.46
238 |
239 |
240 | 9.0.0
241 |
242 |
243 | 3.0.0
244 |
245 |
246 | 2.1.0
247 |
248 |
249 | 6.0.0
250 |
251 |
252 | 4.2.0
253 |
254 |
255 | 9.0.3
256 |
257 |
258 | 4.6.0
259 |
260 |
261 | 4.3.1
262 |
263 |
264 | 4.3.0
265 |
266 |
267 | 4.3.1
268 |
269 |
270 | 9.0.3
271 |
272 |
273 | 4.6.0
274 |
275 |
276 |
277 |
--------------------------------------------------------------------------------
/EDForceFeedback/FFUtils/FFConst.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/FFUtils/FFConst.exe
--------------------------------------------------------------------------------
/EDForceFeedback/FFUtils/csFeedback.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/FFUtils/csFeedback.exe
--------------------------------------------------------------------------------
/EDForceFeedback/FFUtils/fedit.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/FFUtils/fedit.exe
--------------------------------------------------------------------------------
/EDForceFeedback/FFUtils/pid1_01.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/FFUtils/pid1_01.pdf
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Cargo.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Cargo.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/CenterSpringXY.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/CenterSpringXY.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Damper.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Damper.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Dock.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Dock.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Gear.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Gear.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Hardpoints.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Hardpoints.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Landed.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Landed.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/SuperCruise.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/SuperCruise.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/Vibrate.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/Vibrate.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Forces/VibrateSide.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedback/Forces/VibrateSide.ffe
--------------------------------------------------------------------------------
/EDForceFeedback/Form1.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace EDForceFeedback
2 | {
3 | partial class Form1
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.statusLabel = new System.Windows.Forms.Label();
32 | this.testButton = new System.Windows.Forms.Button();
33 | this.SuspendLayout();
34 | //
35 | // statusLabel
36 | //
37 | this.statusLabel.AutoSize = true;
38 | this.statusLabel.Location = new System.Drawing.Point(20, 12);
39 | this.statusLabel.Name = "statusLabel";
40 | this.statusLabel.Size = new System.Drawing.Size(147, 15);
41 | this.statusLabel.TabIndex = 0;
42 | this.statusLabel.Text = "EDForceFeedback Window";
43 | //
44 | // testButton
45 | //
46 | this.testButton.Location = new System.Drawing.Point(400, 8);
47 | this.testButton.Name = "testButton";
48 | this.testButton.Size = new System.Drawing.Size(75, 23);
49 | this.testButton.TabIndex = 1;
50 | this.testButton.Text = "Test";
51 | this.testButton.UseVisualStyleBackColor = true;
52 | this.testButton.Click += new System.EventHandler(this.button1_Click);
53 | //
54 | // Form1
55 | //
56 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
57 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
58 | this.ClientSize = new System.Drawing.Size(487, 49);
59 | this.Controls.Add(this.testButton);
60 | this.Controls.Add(this.statusLabel);
61 | this.Name = "Form1";
62 | this.Text = "EDForceFeedback";
63 | this.Load += new System.EventHandler(this.Form1_Load);
64 | this.ResumeLayout(false);
65 | this.PerformLayout();
66 |
67 | }
68 |
69 | #endregion
70 |
71 | private Label statusLabel;
72 | private Button testButton;
73 | }
74 | }
--------------------------------------------------------------------------------
/EDForceFeedback/Form1.cs:
--------------------------------------------------------------------------------
1 | using Journals;
2 | using Microsoft.Extensions.Logging;
3 | using System.Runtime.CompilerServices;
4 | using System.Windows.Forms;
5 | using System.Xml.Linq;
6 |
7 | namespace EDForceFeedback
8 | {
9 | public partial class Form1 : Form
10 | {
11 | private Client _client;
12 | private Settings _settings;
13 | public Form1(Client client, Settings settings)
14 | {
15 | InitializeComponent();
16 |
17 | _client = client;
18 | _settings = settings;
19 | }
20 |
21 | private void Form1_Load(object sender, EventArgs e)
22 | {
23 | Task.Run(async () => await _client.Initialize(_settings).ConfigureAwait(false)).ContinueWith(t =>
24 | {
25 | var result = "Uknown state";
26 | if (t.IsCanceled) result = "Task cancelled";
27 | else if (t.IsFaulted) result = $"Exception {t.Exception.InnerException?.Message}";
28 | else result = _client.StatusText;
29 |
30 | statusLabel.Invoke((MethodInvoker)delegate {
31 | statusLabel.Text = result;
32 | });
33 | });
34 |
35 | }
36 |
37 | private void button1_Click(object sender, EventArgs e)
38 | {
39 | _client.TestEffect();
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/EDForceFeedback/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
--------------------------------------------------------------------------------
/EDForceFeedback/Program.cs:
--------------------------------------------------------------------------------
1 | using Journals;
2 | using Newtonsoft.Json;
3 | using System;
4 | using System.IO;
5 | using System.Threading.Tasks;
6 |
7 | namespace EDForceFeedback
8 | {
9 | static public class Program
10 | {
11 | static private async Task Main(string[] args)
12 | {
13 | var fileName = $"{Directory.GetCurrentDirectory()}\\settings.json";
14 |
15 | // Check if a settings file was specified
16 | if (args?.Length == 1)
17 | {
18 | if (args[0].CompareTo("-h") == 0 || args[0].CompareTo("help") == 0)
19 | {
20 | Console.WriteLine("EDForceFeedBack: EDForceFeedback.exe is a console program that runs during a Elite Dangerous session.");
21 | Console.WriteLine("It watches the ED log files and responds to game events by playing a force feedback editor (.ffe) file.");
22 | Console.WriteLine();
23 | Console.WriteLine("Usage:");
24 | Console.WriteLine("EDForceFeedback.exe -h Output this help.");
25 | Console.WriteLine(@"EDForceFeedback.exe c:\settings.json Override the default settings file and use this instead.");
26 | Console.WriteLine($"EDForceFeedback.exe Will default to the settings file {Directory.GetCurrentDirectory()}\\settings.json");
27 | return;
28 | }
29 | else
30 | {
31 | fileName = args[0];
32 | }
33 | }
34 |
35 | Console.WriteLine($"Using setting file: {fileName}");
36 |
37 | var settings = JsonConvert.DeserializeObject(File.ReadAllText(fileName));
38 |
39 | var client = new Client();
40 |
41 | await client.Initialize(settings).ConfigureAwait(false);
42 |
43 | while (true)
44 | await Task.Delay(5000).ConfigureAwait(false);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/EDForceFeedback/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EDForceFeedback")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EDForceFeedback")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("072e80f0-c235-44f2-b93b-747c488b490a")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/EDForceFeedback/settings.Xbox.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | }
101 | ]
102 | }
103 |
--------------------------------------------------------------------------------
/EDForceFeedback/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
16 | "ProductName": "SideWinder Force Feedback 2 Joystick",
17 | "AutoCenter": true,
18 | "ForceFeedbackGain": 10000,
19 |
20 | "StatusEvents": [
21 | {
22 | "Event": "Status.Docked:True",
23 | "ForceFile": "Dock.ffe",
24 | "Duration": 2000
25 | },
26 | {
27 | "Event": "Status.Docked:False",
28 | "ForceFile": "Dock.ffe",
29 | "Duration": 2000
30 | },
31 | {
32 | "Event": "Status.Gear:True",
33 | "ForceFile": "Gear.ffe",
34 | "Duration": 3000
35 | },
36 | {
37 | "Event": "Status.Gear:False",
38 | "ForceFile": "Gear.ffe",
39 | "Duration": 3000
40 | },
41 | {
42 | "Event": "Status.Lights:True",
43 | "ForceFile": "Vibrate.ffe",
44 | "Duration": 250
45 | },
46 | {
47 | "Event": "Status.Lights:False",
48 | "ForceFile": "Vibrate.ffe",
49 | "Duration": 250
50 | },
51 | {
52 | "Event": "Status.Hardpoints:True",
53 | "ForceFile": "Hardpoints.ffe",
54 | "Duration": 2000
55 | },
56 | {
57 | "Event": "Status.Hardpoints:False",
58 | "ForceFile": "Hardpoints.ffe",
59 | "Duration": 2000
60 | },
61 | {
62 | "Event": "Status.Landed:True",
63 | "ForceFile": "Hardpoints.ffe",
64 | "Duration": 1500
65 | },
66 | {
67 | "Event": "Status.Landed:False",
68 | "ForceFile": "Hardpoints.ffe",
69 | "Duration": 1500
70 | },
71 | {
72 | "Event": "Status.LowFuel:True",
73 | "ForceFile": "VibrateSide.ffe",
74 | "Duration": 500
75 | },
76 | {
77 | "Event": "Status.LowFuel:False",
78 | "ForceFile": "VibrateSide.ffe",
79 | "Duration": 500
80 | },
81 | {
82 | "Event": "Status.CargoScoop:True",
83 | "ForceFile": "Cargo.ffe",
84 | "Duration": 2000
85 | },
86 | {
87 | "Event": "Status.CargoScoop:False",
88 | "ForceFile": "Cargo.ffe",
89 | "Duration": 2000
90 | },
91 | {
92 | "Event": "Status.Overheating:True",
93 | "ForceFile": "VibrateSide.ffe",
94 | "Duration": 250
95 | },
96 | {
97 | "Event": "Status.Overheating:False",
98 | "ForceFile": "VibrateSide.ffe",
99 | "Duration": 250
100 | }
101 | ]
102 | }
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/EDForceFeedback/settingsMSFFB2.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
16 | "ProductName": "SideWinder Force Feedback 2 Joystick",
17 | "AutoCenter": true,
18 | "ForceFeedbackGain": 10000,
19 |
20 | "StatusEvents": [
21 | {
22 | "Event": "Status.Docked:True",
23 | "ForceFile": "Dock.ffe",
24 | "Duration": 2000
25 | },
26 | {
27 | "Event": "Status.Docked:False",
28 | "ForceFile": "Dock.ffe",
29 | "Duration": 2000
30 | },
31 | {
32 | "Event": "Status.Gear:True",
33 | "ForceFile": "Gear.ffe",
34 | "Duration": 3000
35 | },
36 | {
37 | "Event": "Status.Gear:False",
38 | "ForceFile": "Gear.ffe",
39 | "Duration": 3000
40 | },
41 | {
42 | "Event": "Status.Lights:True",
43 | "ForceFile": "Vibrate.ffe",
44 | "Duration": 250
45 | },
46 | {
47 | "Event": "Status.Lights:False",
48 | "ForceFile": "Vibrate.ffe",
49 | "Duration": 250
50 | },
51 | {
52 | "Event": "Status.Hardpoints:True",
53 | "ForceFile": "Hardpoints.ffe",
54 | "Duration": 2000
55 | },
56 | {
57 | "Event": "Status.Hardpoints:False",
58 | "ForceFile": "Hardpoints.ffe",
59 | "Duration": 2000
60 | },
61 | {
62 | "Event": "Status.Landed:True",
63 | "ForceFile": "Hardpoints.ffe",
64 | "Duration": 1500
65 | },
66 | {
67 | "Event": "Status.Landed:False",
68 | "ForceFile": "Hardpoints.ffe",
69 | "Duration": 1500
70 | },
71 | {
72 | "Event": "Status.LowFuel:True",
73 | "ForceFile": "VibrateSide.ffe",
74 | "Duration": 500
75 | },
76 | {
77 | "Event": "Status.LowFuel:False",
78 | "ForceFile": "VibrateSide.ffe",
79 | "Duration": 500
80 | },
81 | {
82 | "Event": "Status.CargoScoop:True",
83 | "ForceFile": "Cargo.ffe",
84 | "Duration": 2000
85 | },
86 | {
87 | "Event": "Status.CargoScoop:False",
88 | "ForceFile": "Cargo.ffe",
89 | "Duration": 2000
90 | },
91 | {
92 | "Event": "Status.Overheating:True",
93 | "ForceFile": "VibrateSide.ffe",
94 | "Duration": 250
95 | },
96 | {
97 | "Event": "Status.Overheating:False",
98 | "ForceFile": "VibrateSide.ffe",
99 | "Duration": 250
100 | }
101 | ]
102 | }
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/EDForceFeedback/settingsXboxAndCyborg.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | },
101 | {
102 | "ProductGuid": "ff1206a3-0000-0000-0000-504944564944",
103 | "ProductName": "",
104 | "AutoCenter": true,
105 | "ForceFeedbackGain": 10000,
106 |
107 | "StatusEvents": [
108 | {
109 | "Event": "Status.Docked:True",
110 | "ForceFile": "Dock.ffe",
111 | "Duration": 2000
112 | },
113 | {
114 | "Event": "Status.Docked:False",
115 | "ForceFile": "Dock.ffe",
116 | "Duration": 2000
117 | },
118 | {
119 | "Event": "Status.Gear:True",
120 | "ForceFile": "Gear.ffe",
121 | "Duration": 3000
122 | },
123 | {
124 | "Event": "Status.Gear:False",
125 | "ForceFile": "Gear.ffe",
126 | "Duration": 3000
127 | },
128 | {
129 | "Event": "Status.Lights:True",
130 | "ForceFile": "Vibrate.ffe",
131 | "Duration": 250
132 | },
133 | {
134 | "Event": "Status.Lights:False",
135 | "ForceFile": "Vibrate.ffe",
136 | "Duration": 250
137 | },
138 | {
139 | "Event": "Status.Hardpoints:True",
140 | "ForceFile": "Hardpoints.ffe",
141 | "Duration": 2000
142 | },
143 | {
144 | "Event": "Status.Hardpoints:False",
145 | "ForceFile": "Hardpoints.ffe",
146 | "Duration": 2000
147 | },
148 | {
149 | "Event": "Status.Landed:True",
150 | "ForceFile": "Hardpoints.ffe",
151 | "Duration": 1500
152 | },
153 | {
154 | "Event": "Status.Landed:False",
155 | "ForceFile": "Hardpoints.ffe",
156 | "Duration": 1500
157 | },
158 | {
159 | "Event": "Status.LowFuel:True",
160 | "ForceFile": "VibrateSide.ffe",
161 | "Duration": 500
162 | },
163 | {
164 | "Event": "Status.LowFuel:False",
165 | "ForceFile": "VibrateSide.ffe",
166 | "Duration": 500
167 | },
168 | {
169 | "Event": "Status.CargoScoop:True",
170 | "ForceFile": "Cargo.ffe",
171 | "Duration": 2000
172 | },
173 | {
174 | "Event": "Status.CargoScoop:False",
175 | "ForceFile": "Cargo.ffe",
176 | "Duration": 2000
177 | },
178 | {
179 | "Event": "Status.Overheating:True",
180 | "ForceFile": "VibrateSide.ffe",
181 | "Duration": 250
182 | },
183 | {
184 | "Event": "Status.Overheating:False",
185 | "ForceFile": "VibrateSide.ffe",
186 | "Duration": 250
187 | }
188 | ]
189 | }
190 | ]
191 | }
192 |
--------------------------------------------------------------------------------
/EDForceFeedback/settingsXboxAndMSFFB2.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | },
101 | {
102 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
103 | "ProductName": "SideWinder Force Feedback 2 Joystick",
104 | "AutoCenter": true,
105 | "ForceFeedbackGain": 10000,
106 |
107 | "StatusEvents": [
108 | {
109 | "Event": "Status.Docked:True",
110 | "ForceFile": "Dock.ffe",
111 | "Duration": 2000
112 | },
113 | {
114 | "Event": "Status.Docked:False",
115 | "ForceFile": "Dock.ffe",
116 | "Duration": 2000
117 | },
118 | {
119 | "Event": "Status.Gear:True",
120 | "ForceFile": "Gear.ffe",
121 | "Duration": 3000
122 | },
123 | {
124 | "Event": "Status.Gear:False",
125 | "ForceFile": "Gear.ffe",
126 | "Duration": 3000
127 | },
128 | {
129 | "Event": "Status.Lights:True",
130 | "ForceFile": "Vibrate.ffe",
131 | "Duration": 250
132 | },
133 | {
134 | "Event": "Status.Lights:False",
135 | "ForceFile": "Vibrate.ffe",
136 | "Duration": 250
137 | },
138 | {
139 | "Event": "Status.Hardpoints:True",
140 | "ForceFile": "Hardpoints.ffe",
141 | "Duration": 2000
142 | },
143 | {
144 | "Event": "Status.Hardpoints:False",
145 | "ForceFile": "Hardpoints.ffe",
146 | "Duration": 2000
147 | },
148 | {
149 | "Event": "Status.Landed:True",
150 | "ForceFile": "Hardpoints.ffe",
151 | "Duration": 1500
152 | },
153 | {
154 | "Event": "Status.Landed:False",
155 | "ForceFile": "Hardpoints.ffe",
156 | "Duration": 1500
157 | },
158 | {
159 | "Event": "Status.LowFuel:True",
160 | "ForceFile": "VibrateSide.ffe",
161 | "Duration": 500
162 | },
163 | {
164 | "Event": "Status.LowFuel:False",
165 | "ForceFile": "VibrateSide.ffe",
166 | "Duration": 500
167 | },
168 | {
169 | "Event": "Status.CargoScoop:True",
170 | "ForceFile": "Cargo.ffe",
171 | "Duration": 2000
172 | },
173 | {
174 | "Event": "Status.CargoScoop:False",
175 | "ForceFile": "Cargo.ffe",
176 | "Duration": 2000
177 | },
178 | {
179 | "Event": "Status.Overheating:True",
180 | "ForceFile": "VibrateSide.ffe",
181 | "Duration": 250
182 | },
183 | {
184 | "Event": "Status.Overheating:False",
185 | "ForceFile": "VibrateSide.ffe",
186 | "Duration": 250
187 | }
188 | ]
189 | }
190 | ]
191 | }
192 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/EDForceFeedbackConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Debug
7 | AnyCPU
8 | {072E80F0-C235-44F2-B93B-747C488B490A}
9 | Exe
10 | EDForceFeedback
11 | EDForceFeedback
12 | v4.8
13 | 512
14 | true
15 | true
16 |
17 |
18 | false
19 | publish\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 3.1.0.%2a
31 | false
32 | true
33 |
34 |
35 | AnyCPU
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | true
53 |
54 |
55 |
56 | ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
57 |
58 |
59 | ..\packages\Microsoft.Extensions.Configuration.5.0.0\lib\net461\Microsoft.Extensions.Configuration.dll
60 |
61 |
62 | ..\packages\Microsoft.Extensions.Configuration.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Abstractions.dll
63 |
64 |
65 | ..\packages\Microsoft.Extensions.Configuration.Binder.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Binder.dll
66 |
67 |
68 | ..\packages\Microsoft.Extensions.Configuration.CommandLine.5.0.0\lib\net461\Microsoft.Extensions.Configuration.CommandLine.dll
69 |
70 |
71 | ..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.5.0.0\lib\net461\Microsoft.Extensions.Configuration.EnvironmentVariables.dll
72 |
73 |
74 | ..\packages\Microsoft.Extensions.Configuration.FileExtensions.5.0.0\lib\net461\Microsoft.Extensions.Configuration.FileExtensions.dll
75 |
76 |
77 | ..\packages\Microsoft.Extensions.Configuration.Json.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Json.dll
78 |
79 |
80 | ..\packages\Microsoft.Extensions.Configuration.UserSecrets.5.0.0\lib\net461\Microsoft.Extensions.Configuration.UserSecrets.dll
81 |
82 |
83 | ..\packages\Microsoft.Extensions.DependencyInjection.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.dll
84 |
85 |
86 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll
87 |
88 |
89 | ..\packages\Microsoft.Extensions.FileProviders.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.FileProviders.Abstractions.dll
90 |
91 |
92 | ..\packages\Microsoft.Extensions.FileProviders.Physical.5.0.0\lib\net461\Microsoft.Extensions.FileProviders.Physical.dll
93 |
94 |
95 | ..\packages\Microsoft.Extensions.FileSystemGlobbing.5.0.0\lib\net461\Microsoft.Extensions.FileSystemGlobbing.dll
96 |
97 |
98 | ..\packages\Microsoft.Extensions.Hosting.5.0.0\lib\net461\Microsoft.Extensions.Hosting.dll
99 |
100 |
101 | ..\packages\Microsoft.Extensions.Hosting.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Hosting.Abstractions.dll
102 |
103 |
104 | ..\packages\Microsoft.Extensions.Logging.5.0.0\lib\net461\Microsoft.Extensions.Logging.dll
105 |
106 |
107 | ..\packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll
108 |
109 |
110 | ..\packages\Microsoft.Extensions.Logging.Configuration.5.0.0\lib\net461\Microsoft.Extensions.Logging.Configuration.dll
111 |
112 |
113 | ..\packages\Microsoft.Extensions.Logging.Console.5.0.0\lib\net461\Microsoft.Extensions.Logging.Console.dll
114 |
115 |
116 | ..\packages\Microsoft.Extensions.Logging.Debug.5.0.0\lib\net461\Microsoft.Extensions.Logging.Debug.dll
117 |
118 |
119 | ..\packages\Microsoft.Extensions.Logging.EventLog.5.0.0\lib\net461\Microsoft.Extensions.Logging.EventLog.dll
120 |
121 |
122 | ..\packages\Microsoft.Extensions.Logging.EventSource.5.0.0\lib\net461\Microsoft.Extensions.Logging.EventSource.dll
123 |
124 |
125 | ..\packages\Microsoft.Extensions.Options.5.0.0\lib\net461\Microsoft.Extensions.Options.dll
126 |
127 |
128 | ..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.5.0.0\lib\net461\Microsoft.Extensions.Options.ConfigurationExtensions.dll
129 |
130 |
131 | ..\packages\Microsoft.Extensions.Primitives.5.0.1\lib\net461\Microsoft.Extensions.Primitives.dll
132 |
133 |
134 | ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
135 |
136 |
137 | ..\packages\protobuf-net.3.0.101\lib\net461\protobuf-net.dll
138 |
139 |
140 | ..\packages\protobuf-net.Core.3.0.101\lib\net461\protobuf-net.Core.dll
141 |
142 |
143 | ..\packages\Serilog.2.5.0\lib\net46\Serilog.dll
144 |
145 |
146 | ..\packages\Serilog.Extensions.Logging.2.0.2\lib\net461\Serilog.Extensions.Logging.dll
147 |
148 |
149 | ..\packages\Serilog.Extensions.Logging.File.2.0.0\lib\net461\Serilog.Extensions.Logging.File.dll
150 |
151 |
152 | ..\packages\Serilog.Formatting.Compact.1.0.0\lib\net45\Serilog.Formatting.Compact.dll
153 |
154 |
155 | ..\packages\Serilog.Sinks.Async.1.1.0\lib\net45\Serilog.Sinks.Async.dll
156 |
157 |
158 | ..\packages\Serilog.Sinks.File.3.2.0\lib\net45\Serilog.Sinks.File.dll
159 |
160 |
161 | ..\packages\Serilog.Sinks.RollingFile.3.3.0\lib\net45\Serilog.Sinks.RollingFile.dll
162 |
163 |
164 | ..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll
165 |
166 |
167 | ..\packages\SharpDX.DirectInput.4.2.0\lib\net45\SharpDX.DirectInput.dll
168 |
169 |
170 |
171 | ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
172 |
173 |
174 | ..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll
175 |
176 |
177 |
178 |
179 |
180 | ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll
181 |
182 |
183 | ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll
184 | True
185 | True
186 |
187 |
188 | ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
189 |
190 |
191 |
192 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
193 |
194 |
195 | ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
196 | True
197 | True
198 |
199 |
200 | ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
201 |
202 |
203 | ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
204 | True
205 | True
206 |
207 |
208 | ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll
209 | True
210 | True
211 |
212 |
213 | ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
214 | True
215 | True
216 |
217 |
218 | ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
219 | True
220 | True
221 |
222 |
223 | ..\packages\System.Text.Encodings.Web.5.0.0\lib\net461\System.Text.Encodings.Web.dll
224 |
225 |
226 | ..\packages\System.Text.Json.5.0.0\lib\net461\System.Text.Json.dll
227 |
228 |
229 | ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
230 |
231 |
232 | ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 | Always
249 |
250 |
251 | Always
252 |
253 |
254 | Always
255 |
256 |
257 | Always
258 |
259 |
260 | Always
261 |
262 |
263 | Always
264 |
265 |
266 | Always
267 |
268 |
269 | Always
270 |
271 |
272 | Always
273 |
274 |
275 | Always
276 |
277 |
278 | Always
279 |
280 |
281 | Always
282 |
283 |
284 | Always
285 |
286 |
287 |
288 | Always
289 |
290 |
291 | Always
292 |
293 |
294 | Always
295 |
296 |
297 | Always
298 |
299 |
300 | Always
301 |
302 |
303 |
304 |
305 | {cf2e9959-f6fe-4e26-89e9-af7dfab9099e}
306 | Journals
307 |
308 |
309 |
310 |
311 | False
312 | Microsoft .NET Framework 4.8 %28x86 and x64%29
313 | true
314 |
315 |
316 | False
317 | .NET Framework 3.5 SP1
318 | false
319 |
320 |
321 |
322 |
323 |
324 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
325 |
326 |
327 |
328 |
329 |
330 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FFUtils/FFConst.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/FFUtils/FFConst.exe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FFUtils/csFeedback.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/FFUtils/csFeedback.exe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FFUtils/fedit.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/FFUtils/fedit.exe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FFUtils/pid1_01.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/FFUtils/pid1_01.pdf
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
23 |
24 |
25 |
26 |
27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
28 |
29 |
30 |
31 |
32 | The order of preloaded assemblies, delimited with line breaks.
33 |
34 |
35 |
36 |
37 |
38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
39 |
40 |
41 |
42 |
43 | Controls if .pdbs for reference assemblies are also embedded.
44 |
45 |
46 |
47 |
48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
49 |
50 |
51 |
52 |
53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
54 |
55 |
56 |
57 |
58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
59 |
60 |
61 |
62 |
63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
64 |
65 |
66 |
67 |
68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
69 |
70 |
71 |
72 |
73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
74 |
75 |
76 |
77 |
78 | A list of unmanaged 32 bit assembly names to include, delimited with |.
79 |
80 |
81 |
82 |
83 | A list of unmanaged 64 bit assembly names to include, delimited with |.
84 |
85 |
86 |
87 |
88 | The order of preloaded assemblies, delimited with |.
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
97 |
98 |
99 |
100 |
101 | A comma-separated list of error codes that can be safely ignored in assembly verification.
102 |
103 |
104 |
105 |
106 | 'false' to turn off automatic generation of the XML Schema file.
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Cargo.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Cargo.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/CenterSpringXY.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/CenterSpringXY.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Damper.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Damper.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Dock.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Dock.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Gear.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Gear.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Hardpoints.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Hardpoints.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Landed.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Landed.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/SuperCruise.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/SuperCruise.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/Vibrate.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/Vibrate.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Forces/VibrateSide.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/EDForceFeedbackConsole/Forces/VibrateSide.ffe
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using Journals;
2 | using Microsoft.Extensions.Logging;
3 | using Newtonsoft.Json;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace EDForceFeedback
12 | {
13 | static public class Program
14 | {
15 | static private async Task Main(string[] args)
16 | {
17 | var fileName = $"{Directory.GetCurrentDirectory()}\\settings.json";
18 |
19 | // Check if a settings file was specified
20 | if (args?.Length == 1)
21 | {
22 | if (args[0].CompareTo("-h") == 0 || args[0].CompareTo("help") == 0)
23 | {
24 | Console.WriteLine("EDForceFeedBack: EDForceFeedback.exe is a console program that runs during a Elite Dangerous session.");
25 | Console.WriteLine("It watches the ED log files and responds to game events by playing a force feedback editor (.ffe) file.");
26 | Console.WriteLine();
27 | Console.WriteLine("Usage:");
28 | Console.WriteLine("EDForceFeedback.exe -h Output this help.");
29 | Console.WriteLine(@"EDForceFeedback.exe c:\settings.json Override the default settings file and use this instead.");
30 | Console.WriteLine($"EDForceFeedback.exe Will default to the settings file {Directory.GetCurrentDirectory()}\\settings.json");
31 | return;
32 | }
33 | else
34 | {
35 | fileName = args[0];
36 | }
37 | }
38 |
39 | Console.WriteLine($"Using setting file: {fileName}");
40 |
41 | var settings = JsonConvert.DeserializeObject(File.ReadAllText(fileName));
42 |
43 | var client = new Client();
44 |
45 | await client.Initialize(settings).ConfigureAwait(false);
46 |
47 | while (true)
48 | await Task.Delay(5000).ConfigureAwait(false);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EDForceFeedback")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EDForceFeedback")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("072e80f0-c235-44f2-b93b-747c488b490a")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Events": [
3 | {
4 | "Event": "Gear",
5 | "ForceFile": "Gear.ffe",
6 | "Duration": 2000
7 | },
8 | {
9 | "Event": "Dock",
10 | "ForceFile": "Gear.ffe",
11 | "Duration": 2000
12 | }
13 |
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settings.Xbox.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | }
101 | ]
102 | }
103 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settings.bak.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
16 | "ProductName": "SideWinder Force Feedback 2 Joystick",
17 | "AutoCenter": true,
18 | "ForceFeedbackGain": 10000,
19 |
20 | "StatusEvents": [
21 | {
22 | "Event": "Status.Docked:True",
23 | "ForceFile": "Dock.ffe",
24 | "Duration": 2000
25 | },
26 | {
27 | "Event": "Status.Docked:False",
28 | "ForceFile": "Dock.ffe",
29 | "Duration": 2000
30 | },
31 | {
32 | "Event": "Status.Gear:True",
33 | "ForceFile": "Gear.ffe",
34 | "Duration": 3000
35 | },
36 | {
37 | "Event": "Status.Gear:False",
38 | "ForceFile": "Gear.ffe",
39 | "Duration": 3000
40 | },
41 | {
42 | "Event": "Status.Lights:True",
43 | "ForceFile": "Vibrate.ffe",
44 | "Duration": 250
45 | },
46 | {
47 | "Event": "Status.Lights:False",
48 | "ForceFile": "Vibrate.ffe",
49 | "Duration": 250
50 | },
51 | {
52 | "Event": "Status.Hardpoints:True",
53 | "ForceFile": "Hardpoints.ffe",
54 | "Duration": 2000
55 | },
56 | {
57 | "Event": "Status.Hardpoints:False",
58 | "ForceFile": "Hardpoints.ffe",
59 | "Duration": 2000
60 | },
61 | {
62 | "Event": "Status.Landed:True",
63 | "ForceFile": "Hardpoints.ffe",
64 | "Duration": 1500
65 | },
66 | {
67 | "Event": "Status.Landed:False",
68 | "ForceFile": "Hardpoints.ffe",
69 | "Duration": 1500
70 | },
71 | {
72 | "Event": "Status.LowFuel:True",
73 | "ForceFile": "VibrateSide.ffe",
74 | "Duration": 500
75 | },
76 | {
77 | "Event": "Status.LowFuel:False",
78 | "ForceFile": "VibrateSide.ffe",
79 | "Duration": 500
80 | },
81 | {
82 | "Event": "Status.CargoScoop:True",
83 | "ForceFile": "Cargo.ffe",
84 | "Duration": 2000
85 | },
86 | {
87 | "Event": "Status.CargoScoop:False",
88 | "ForceFile": "Cargo.ffe",
89 | "Duration": 2000
90 | },
91 | {
92 | "Event": "Status.Overheating:True",
93 | "ForceFile": "VibrateSide.ffe",
94 | "Duration": 250
95 | },
96 | {
97 | "Event": "Status.Overheating:False",
98 | "ForceFile": "VibrateSide.ffe",
99 | "Duration": 250
100 | },
101 | {
102 | "Event": "EliteAPI.Event.Models.SupercruiseEntryEvent",
103 | "ForceFile": "VibrateSide.ffe",
104 | "Duration": 250
105 | }
106 | ]
107 | }
108 | ]
109 | }
110 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | }
101 | ]
102 | }
103 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settingsMSFFB2.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
16 | "ProductName": "SideWinder Force Feedback 2 Joystick",
17 | "AutoCenter": true,
18 | "ForceFeedbackGain": 10000,
19 |
20 | "StatusEvents": [
21 | {
22 | "Event": "Status.Docked:True",
23 | "ForceFile": "Dock.ffe",
24 | "Duration": 2000
25 | },
26 | {
27 | "Event": "Status.Docked:False",
28 | "ForceFile": "Dock.ffe",
29 | "Duration": 2000
30 | },
31 | {
32 | "Event": "Status.Gear:True",
33 | "ForceFile": "Gear.ffe",
34 | "Duration": 3000
35 | },
36 | {
37 | "Event": "Status.Gear:False",
38 | "ForceFile": "Gear.ffe",
39 | "Duration": 3000
40 | },
41 | {
42 | "Event": "Status.Lights:True",
43 | "ForceFile": "Vibrate.ffe",
44 | "Duration": 250
45 | },
46 | {
47 | "Event": "Status.Lights:False",
48 | "ForceFile": "Vibrate.ffe",
49 | "Duration": 250
50 | },
51 | {
52 | "Event": "Status.Hardpoints:True",
53 | "ForceFile": "Hardpoints.ffe",
54 | "Duration": 2000
55 | },
56 | {
57 | "Event": "Status.Hardpoints:False",
58 | "ForceFile": "Hardpoints.ffe",
59 | "Duration": 2000
60 | },
61 | {
62 | "Event": "Status.Landed:True",
63 | "ForceFile": "Hardpoints.ffe",
64 | "Duration": 1500
65 | },
66 | {
67 | "Event": "Status.Landed:False",
68 | "ForceFile": "Hardpoints.ffe",
69 | "Duration": 1500
70 | },
71 | {
72 | "Event": "Status.LowFuel:True",
73 | "ForceFile": "VibrateSide.ffe",
74 | "Duration": 500
75 | },
76 | {
77 | "Event": "Status.LowFuel:False",
78 | "ForceFile": "VibrateSide.ffe",
79 | "Duration": 500
80 | },
81 | {
82 | "Event": "Status.CargoScoop:True",
83 | "ForceFile": "Cargo.ffe",
84 | "Duration": 2000
85 | },
86 | {
87 | "Event": "Status.CargoScoop:False",
88 | "ForceFile": "Cargo.ffe",
89 | "Duration": 2000
90 | },
91 | {
92 | "Event": "Status.Overheating:True",
93 | "ForceFile": "VibrateSide.ffe",
94 | "Duration": 250
95 | },
96 | {
97 | "Event": "Status.Overheating:False",
98 | "ForceFile": "VibrateSide.ffe",
99 | "Duration": 250
100 | }
101 | ]
102 | }
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settingsXboxAndCyborg.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | },
101 | {
102 | "ProductGuid": "ff1206a3-0000-0000-0000-504944564944",
103 | "ProductName": "",
104 | "AutoCenter": true,
105 | "ForceFeedbackGain": 10000,
106 |
107 | "StatusEvents": [
108 | {
109 | "Event": "Status.Docked:True",
110 | "ForceFile": "Dock.ffe",
111 | "Duration": 2000
112 | },
113 | {
114 | "Event": "Status.Docked:False",
115 | "ForceFile": "Dock.ffe",
116 | "Duration": 2000
117 | },
118 | {
119 | "Event": "Status.Gear:True",
120 | "ForceFile": "Gear.ffe",
121 | "Duration": 3000
122 | },
123 | {
124 | "Event": "Status.Gear:False",
125 | "ForceFile": "Gear.ffe",
126 | "Duration": 3000
127 | },
128 | {
129 | "Event": "Status.Lights:True",
130 | "ForceFile": "Vibrate.ffe",
131 | "Duration": 250
132 | },
133 | {
134 | "Event": "Status.Lights:False",
135 | "ForceFile": "Vibrate.ffe",
136 | "Duration": 250
137 | },
138 | {
139 | "Event": "Status.Hardpoints:True",
140 | "ForceFile": "Hardpoints.ffe",
141 | "Duration": 2000
142 | },
143 | {
144 | "Event": "Status.Hardpoints:False",
145 | "ForceFile": "Hardpoints.ffe",
146 | "Duration": 2000
147 | },
148 | {
149 | "Event": "Status.Landed:True",
150 | "ForceFile": "Hardpoints.ffe",
151 | "Duration": 1500
152 | },
153 | {
154 | "Event": "Status.Landed:False",
155 | "ForceFile": "Hardpoints.ffe",
156 | "Duration": 1500
157 | },
158 | {
159 | "Event": "Status.LowFuel:True",
160 | "ForceFile": "VibrateSide.ffe",
161 | "Duration": 500
162 | },
163 | {
164 | "Event": "Status.LowFuel:False",
165 | "ForceFile": "VibrateSide.ffe",
166 | "Duration": 500
167 | },
168 | {
169 | "Event": "Status.CargoScoop:True",
170 | "ForceFile": "Cargo.ffe",
171 | "Duration": 2000
172 | },
173 | {
174 | "Event": "Status.CargoScoop:False",
175 | "ForceFile": "Cargo.ffe",
176 | "Duration": 2000
177 | },
178 | {
179 | "Event": "Status.Overheating:True",
180 | "ForceFile": "VibrateSide.ffe",
181 | "Duration": 250
182 | },
183 | {
184 | "Event": "Status.Overheating:False",
185 | "ForceFile": "VibrateSide.ffe",
186 | "Duration": 250
187 | }
188 | ]
189 | }
190 | ]
191 | }
192 |
--------------------------------------------------------------------------------
/EDForceFeedbackConsole/settingsXboxAndMSFFB2.json:
--------------------------------------------------------------------------------
1 | {
2 | "KnownWorkingDevices": {
3 | "NOTES": "These are the ProductGuid and ProductNames values for devices known to work with this program.",
4 | "NOTES1": "Replace the ProductGuid or ProductName value below with the device values listed here.",
5 | "NOTES2": "The device search will match on either value",
6 | "Xbox One For Windows": "ProductGuid = 02dd045e-0000-0000-0000-504944564944 ProductName = 'Controller (Xbox One For Windows)'",
7 | "MSFF2": "ProductGuid = 001b045e-0000-0000-0000-504944564944 ProductName = 'SideWinder Force Feedback 2 Joystick'",
8 | "Saitek Cyborg 3D Force Stick": "ProductGuid = ff1206a3-0000-0000-0000-504944564944",
9 | "Saitek Cyborg Evo Force Stick": "ProductGuid = ffb506a3-0000-0000-0000-504944564944",
10 | "Teensy Boards": "ProductGuid = 230028de-0000-0000-0000-504944564944 ProductName = IMU"
11 | },
12 |
13 | "Devices": [
14 | {
15 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
16 | "ProductName": "Controller (Xbox One For Windows)",
17 |
18 | "StatusEvents": [
19 | {
20 | "Event": "Status.Docked:True",
21 | "ForceFile": "Dock.ffe",
22 | "Duration": 2000
23 | },
24 | {
25 | "Event": "Status.Docked:False",
26 | "ForceFile": "Dock.ffe",
27 | "Duration": 2000
28 | },
29 | {
30 | "Event": "Status.Gear:True",
31 | "ForceFile": "Gear.ffe",
32 | "Duration": 3000
33 | },
34 | {
35 | "Event": "Status.Gear:False",
36 | "ForceFile": "Gear.ffe",
37 | "Duration": 3000
38 | },
39 | {
40 | "Event": "Status.Lights:True",
41 | "ForceFile": "Vibrate.ffe",
42 | "Duration": 250
43 | },
44 | {
45 | "Event": "Status.Lights:False",
46 | "ForceFile": "Vibrate.ffe",
47 | "Duration": 250
48 | },
49 | {
50 | "Event": "Status.Hardpoints:True",
51 | "ForceFile": "Hardpoints.ffe",
52 | "Duration": 2000
53 | },
54 | {
55 | "Event": "Status.Hardpoints:False",
56 | "ForceFile": "Hardpoints.ffe",
57 | "Duration": 2000
58 | },
59 | {
60 | "Event": "Status.Landed:True",
61 | "ForceFile": "Hardpoints.ffe",
62 | "Duration": 1500
63 | },
64 | {
65 | "Event": "Status.Landed:False",
66 | "ForceFile": "Hardpoints.ffe",
67 | "Duration": 1500
68 | },
69 | {
70 | "Event": "Status.LowFuel:True",
71 | "ForceFile": "VibrateSide.ffe",
72 | "Duration": 500
73 | },
74 | {
75 | "Event": "Status.LowFuel:False",
76 | "ForceFile": "VibrateSide.ffe",
77 | "Duration": 500
78 | },
79 | {
80 | "Event": "Status.CargoScoop:True",
81 | "ForceFile": "Cargo.ffe",
82 | "Duration": 2000
83 | },
84 | {
85 | "Event": "Status.CargoScoop:False",
86 | "ForceFile": "Cargo.ffe",
87 | "Duration": 2000
88 | },
89 | {
90 | "Event": "Status.Overheating:True",
91 | "ForceFile": "VibrateSide.ffe",
92 | "Duration": 250
93 | },
94 | {
95 | "Event": "Status.Overheating:False",
96 | "ForceFile": "VibrateSide.ffe",
97 | "Duration": 250
98 | }
99 | ]
100 | },
101 | {
102 | "ProductGuid": "001b045e-0000-0000-0000-504944564944",
103 | "ProductName": "SideWinder Force Feedback 2 Joystick",
104 | "AutoCenter": true,
105 | "ForceFeedbackGain": 10000,
106 |
107 | "StatusEvents": [
108 | {
109 | "Event": "Status.Docked:True",
110 | "ForceFile": "Dock.ffe",
111 | "Duration": 2000
112 | },
113 | {
114 | "Event": "Status.Docked:False",
115 | "ForceFile": "Dock.ffe",
116 | "Duration": 2000
117 | },
118 | {
119 | "Event": "Status.Gear:True",
120 | "ForceFile": "Gear.ffe",
121 | "Duration": 3000
122 | },
123 | {
124 | "Event": "Status.Gear:False",
125 | "ForceFile": "Gear.ffe",
126 | "Duration": 3000
127 | },
128 | {
129 | "Event": "Status.Lights:True",
130 | "ForceFile": "Vibrate.ffe",
131 | "Duration": 250
132 | },
133 | {
134 | "Event": "Status.Lights:False",
135 | "ForceFile": "Vibrate.ffe",
136 | "Duration": 250
137 | },
138 | {
139 | "Event": "Status.Hardpoints:True",
140 | "ForceFile": "Hardpoints.ffe",
141 | "Duration": 2000
142 | },
143 | {
144 | "Event": "Status.Hardpoints:False",
145 | "ForceFile": "Hardpoints.ffe",
146 | "Duration": 2000
147 | },
148 | {
149 | "Event": "Status.Landed:True",
150 | "ForceFile": "Hardpoints.ffe",
151 | "Duration": 1500
152 | },
153 | {
154 | "Event": "Status.Landed:False",
155 | "ForceFile": "Hardpoints.ffe",
156 | "Duration": 1500
157 | },
158 | {
159 | "Event": "Status.LowFuel:True",
160 | "ForceFile": "VibrateSide.ffe",
161 | "Duration": 500
162 | },
163 | {
164 | "Event": "Status.LowFuel:False",
165 | "ForceFile": "VibrateSide.ffe",
166 | "Duration": 500
167 | },
168 | {
169 | "Event": "Status.CargoScoop:True",
170 | "ForceFile": "Cargo.ffe",
171 | "Duration": 2000
172 | },
173 | {
174 | "Event": "Status.CargoScoop:False",
175 | "ForceFile": "Cargo.ffe",
176 | "Duration": 2000
177 | },
178 | {
179 | "Event": "Status.Overheating:True",
180 | "ForceFile": "VibrateSide.ffe",
181 | "Duration": 250
182 | },
183 | {
184 | "Event": "Status.Overheating:False",
185 | "ForceFile": "VibrateSide.ffe",
186 | "Duration": 250
187 | }
188 | ]
189 | }
190 | ]
191 | }
192 |
--------------------------------------------------------------------------------
/ForceFeedback.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/ForceFeedback.PNG
--------------------------------------------------------------------------------
/ForceFeedbackSharpDx/ForceFeedbackController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using SharpDX;
3 | using SharpDX.DirectInput;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Threading.Tasks;
8 |
9 | namespace ForceFeedbackSharpDx
10 | {
11 | public class ForceFeedbackController : IDisposable
12 | {
13 | private const uint WINDOW_HANDLE_ERROR = 0x80070006;
14 |
15 | private Joystick joystick = null;
16 | private DirectInput directInput = null;
17 | private readonly Dictionary knownEffects = new Dictionary();
18 | private readonly Dictionary> fileEffects = new Dictionary>();
19 | public ILogger Logger { get; set; }
20 |
21 | public String StatusText;
22 |
23 | public bool Initialize(
24 | string productGuid,
25 | string productName,
26 | string forceFilesFolder,
27 | bool autoCenter,
28 | int forceFeedbackGain,
29 | int deadzone = 0,
30 | int saturation = 10000)
31 | {
32 | // Initialize DirectInput
33 | if (directInput != null)
34 | {
35 | directInput.Dispose();
36 | directInput = null;
37 | }
38 |
39 | directInput = new DirectInput();
40 |
41 | var product = new Guid(productGuid);
42 |
43 | // Find a Joystick Guid
44 | var joystickGuid = Guid.Empty;
45 | var joystickName = String.Empty;
46 |
47 | var directInputDevices = new List();
48 |
49 | directInputDevices.AddRange(directInput.GetDevices());
50 |
51 | // Filtered
52 | //directInputDevices.AddRange(directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices));
53 | //directInputDevices.AddRange(directInput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices));
54 | //directInputDevices.AddRange(directInput.GetDevices(DeviceType.Driving, DeviceEnumerationFlags.AllDevices));
55 |
56 | foreach (var deviceInstance in directInputDevices)
57 | {
58 | Logger?.LogDebug($"DeviceName: {deviceInstance.ProductName}: ProductGuid {deviceInstance.ProductGuid}");
59 |
60 | if (deviceInstance.ProductGuid == product || deviceInstance.ProductName == productName)
61 | {
62 | joystickGuid = deviceInstance.InstanceGuid;
63 | joystickName = deviceInstance.ProductName;
64 | break;
65 | }
66 | }
67 |
68 | // If Joystick not found, throws an error
69 | if (joystickGuid == Guid.Empty)
70 | {
71 | Logger?.LogDebug("No matching Joystick/Gamepad/Wheel found. {deviceInstance.ProductName} {productGuid}");
72 | return false;
73 | }
74 |
75 | // Instantiate the joystick
76 | joystick = new Joystick(directInput, joystickGuid);
77 |
78 | Logger?.LogDebug("Found Joystick/Gamepad {0}", joystickName);
79 |
80 | // Query all suported ForceFeedback effects
81 | var allEffects = joystick.GetEffects();
82 | foreach (var effectInfo in allEffects)
83 | {
84 | knownEffects.Add(effectInfo.Name, effectInfo);
85 | Logger?.LogDebug("Effect available {0}", effectInfo.Name);
86 | }
87 |
88 | // Load all of the effect files
89 | var forcesFolder = new DirectoryInfo(forceFilesFolder);
90 |
91 | foreach (var file in forcesFolder.GetFiles("*.ffe"))
92 | {
93 | var effectsFromFile = joystick.GetEffectsInFile(file.FullName, EffectFileFlags.ModidyIfNeeded);
94 | fileEffects.Add(file.Name.Trim().ToLower(), new List(effectsFromFile));
95 | Logger?.LogDebug($"File Effect available {file.Name}");
96 | }
97 |
98 | // Set BufferSize in order to use buffered data.
99 | joystick.Properties.BufferSize = 128;
100 |
101 | // DirectX requires a window handle to set the CooperativeLevel
102 | var handle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
103 |
104 | try
105 | {
106 | // Exclusive is required to control the forces
107 | joystick.SetCooperativeLevel(handle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
108 | }
109 | catch (SharpDX.SharpDXException ex) when ((uint)ex.HResult == WINDOW_HANDLE_ERROR)
110 | {
111 | Logger?.LogDebug(" Unable to access window handle. Do not run EDForceFeedback.exe in a console window.");
112 | StatusText = "Unable to access window handle";
113 | return false;
114 | }
115 |
116 | try
117 | {
118 | // Autocenter: For the MSFF2 joystick this value is a spring force that plays in the background.
119 | // If all effects are stopped. The spring will stop too. Reset will turn it back on.
120 | joystick.Properties.AutoCenter = autoCenter;
121 | }
122 | catch (SharpDXException)
123 | {
124 | // Some devices do not support this setting.
125 | }
126 |
127 | // Acquire the joystick
128 | joystick.Acquire();
129 |
130 | SetActuators(true);
131 |
132 | joystick.Properties.DeadZone = deadzone;
133 | joystick.Properties.Saturation = saturation;
134 | joystick.Properties.ForceFeedbackGain = forceFeedbackGain;
135 |
136 | StatusText = $"{joystickName}: Aquired";
137 |
138 | return true;
139 | }
140 |
141 | private void PlayEffect(Effect effect)
142 | {
143 | // See if our effects are playing. If not play them
144 | if (effect.Status != EffectStatus.Playing)
145 | {
146 | Logger?.LogDebug($"Effect {effect.Guid} starting");
147 | effect.Start(1, EffectPlayFlags.NoDownload);
148 | }
149 | }
150 |
151 | public void PlayEffects(IEnumerable effects)
152 | {
153 | foreach (var effect in effects)
154 | PlayEffect(effect);
155 | }
156 |
157 | ///
158 | /// Stop any effects that were started from the PlayFileEffect() method.
159 | ///
160 | ///
161 | public void StopEffects(IEnumerable effects, bool dispose = true)
162 | {
163 | if (effects == null)
164 | return;
165 |
166 | foreach (var effect in effects)
167 | {
168 | try { effect.Stop(); }
169 | catch (SharpDXException) { }
170 | }
171 |
172 | if (dispose)
173 | {
174 | foreach (var effect in effects)
175 | effect?.Dispose();
176 | }
177 |
178 | //Reset(); // This will kill all effects
179 | }
180 |
181 | ///
182 | /// Stop all effects. Reset to Default. Note: This reenables the center spring if autocenter is set.
183 | ///
184 | public void Reset()
185 | {
186 | joystick.SendForceFeedbackCommand(ForceFeedbackCommand.Reset);
187 | }
188 |
189 | ///
190 | /// Stop all effects. Note: This will disable the autocenter effect. To reenable call Reset().
191 | ///
192 | public void StopAllEffects()
193 | {
194 | joystick.SendForceFeedbackCommand(ForceFeedbackCommand.StopAll);
195 | }
196 |
197 | ///
198 | /// Set the actuators on/off
199 | ///
200 | public void SetActuators(bool on = true)
201 | {
202 | try
203 | {
204 | if (on)
205 | joystick.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOn);
206 | else
207 | joystick.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOff);
208 | }
209 | catch(Exception ex)
210 | {
211 | Logger?.LogError($"Exception {ex.Message}");
212 | }
213 | }
214 |
215 | ///
216 | /// Returns the effects in the effect file. Caller must dispose of the object when completed.
217 | ///
218 | ///
219 | ///
220 | public List GetEffectFromFile(string name)
221 | {
222 | try
223 | {
224 | var fileEffect = fileEffects[name.Trim().ToLower()];
225 |
226 | // Create a new List<> of effects
227 | return fileEffect.ConvertAll(x => new Effect(joystick, x.Guid, x.Parameters));
228 | }
229 | catch (KeyNotFoundException ex)
230 | {
231 | Logger?.LogError($"GetEffectFromFile Key: '{name}' Not Found Exception", ex);
232 | }
233 | catch (Exception ex)
234 | {
235 | Logger?.LogError("GetEffectFromFile Exception", ex);
236 | }
237 | return null;
238 | }
239 |
240 | ///
241 | /// Copy the effect file and begin playing it. If the duration is greater than zero the effect will play for that many milliseconds
242 | /// and then be stopped.
243 | ///
244 | /// Effect file name
245 | /// Zero and below will play until stopped. Above zero will play for that many milliseconds. Default: 250.
246 | /// The effects being played as a List or null if the effect file was not found.
247 | public List PlayFileEffect(string name, int duration = 250)
248 | {
249 | try
250 | {
251 | var fileEffect = fileEffects[name.Trim().ToLower()];
252 |
253 | // Create a new List<> of effects
254 | var forceEffects = fileEffect.ConvertAll(x => new Effect(joystick, x.Guid, x.Parameters));
255 |
256 | _ = Task.Run(async () =>
257 | {
258 | PlayEffects(forceEffects);
259 | if (duration > 0)
260 | {
261 | await Task.Delay(duration).ConfigureAwait(false);
262 | StopEffects(forceEffects);
263 | }
264 | else
265 | {
266 | // Wait a moment, effects don't seem to play if we exit fast
267 | await Task.Delay(100).ConfigureAwait(false);
268 | }
269 | }).ContinueWith(t =>
270 | {
271 | if (t.IsCanceled) Logger?.LogDebug($"Effect {name} cancelled");
272 | else if (t.IsFaulted) Logger?.LogDebug($"Effect {name} Exception {t.Exception.InnerException?.Message}");
273 | else Logger?.LogDebug($"Effect {name} complete");
274 | });
275 |
276 | return forceEffects;
277 | }
278 | catch(KeyNotFoundException ex)
279 | {
280 | Logger?.LogError($"PlayFileEffect Key: '{name}' Not Found Exception", ex);
281 | }
282 | catch (Exception ex)
283 | {
284 | Logger?.LogError("PlayFileEffect Exception", ex);
285 | }
286 |
287 | return null;
288 | }
289 |
290 | public void Dispose()
291 | {
292 | joystick?.Unacquire();
293 | joystick?.Dispose();
294 | joystick = null;
295 | directInput?.Dispose();
296 | directInput = null;
297 | }
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/ForceFeedbackSharpDx/ForceFeedbackSharpDx.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | d3981932-571e-4587-9ab1-a84feafe7953
6 | x86
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Journals/Client.cs:
--------------------------------------------------------------------------------
1 | using ForceFeedbackSharpDx;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace Journals
10 | {
11 | public class Client
12 | {
13 | private EliteAPI.Abstractions.IEliteDangerousApi eliteAPI;
14 | //private IShip ship;
15 | private ILogger logger;
16 | private IHost host;
17 |
18 | private readonly List Devices = new List();
19 |
20 | public async Task Initialize(Settings settings)
21 | {
22 | // Inject the logger and EliteApi services into host
23 | host = Host.CreateDefaultBuilder()
24 | .ConfigureServices((context, service) =>
25 | {
26 | service.AddEliteApi();
27 | service.AddTransient();
28 | service.AddLogging(builder =>
29 | builder.AddSimpleConsole(options => { options.SingleLine = true; options.TimestampFormat = "hh:mm:ss "; }).SetMinimumLevel(LogLevel.Debug));
30 | })
31 | .Build();
32 |
33 | // Get the services from the Host object
34 | eliteAPI = host.Services.GetService();
35 | //ship = host.Services.GetService();
36 | logger = host.Services.GetRequiredService>();
37 |
38 | foreach (var device in settings.Devices)
39 | {
40 | var ffDevice = new ForceFeedbackController() { Logger = logger };
41 | if (ffDevice.Initialize(
42 | device.ProductGuid,
43 | device.ProductName,
44 | @".\Forces",
45 | device.AutoCenter,
46 | device.ForceFeedbackGain) == false)
47 | {
48 | logger.LogError($"Device Initialization failed: {device.ProductGuid}: {device.ProductName}");
49 | continue;
50 | }
51 |
52 | var deviceEvents = new DeviceEvents
53 | {
54 | EventSettings = device.StatusEvents.ToDictionary(v => v.Event, v => v),
55 | Device = ffDevice
56 | };
57 |
58 | Devices.Add(deviceEvents);
59 | }
60 |
61 | // Start the api
62 | await eliteAPI.StartAsync().ConfigureAwait(false);
63 |
64 | eliteAPI.Events.OnAny( e => Events_AllEvent(e));
65 |
66 | eliteAPI.Events.On(e => FindEffect($"Status.Docked:{e.Value}"));
67 | eliteAPI.Events.On(e => FindEffect($"Status.Landed:{e.Value}"));
68 |
69 | eliteAPI.Events.On(e => ShipStatusEvent(e));
70 |
71 | //ship.Gear.OnChange += (obj, eventArgs) => FindEffect($"Status.Gear:{eventArgs}");
72 | //ship.Shields.OnChange += (obj, eventArgs) => FindEffect($"Status.Shields:{eventArgs}");
73 | //ship.Supercruise.OnChange += (obj, eventArgs) => FindEffect($"Status.Supercruise:{eventArgs}");
74 | //ship.FlightAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.FlightAssist:{eventArgs}");
75 | //ship.Hardpoints.OnChange += (obj, eventArgs) => FindEffect($"Status.Hardpoints:{eventArgs}");
76 | //ship.Winging.OnChange += (obj, eventArgs) => FindEffect($"Status.Winging:{eventArgs}");
77 | //ship.Lights.OnChange += (obj, eventArgs) => FindEffect($"Status.Lights:{eventArgs}");
78 | //ship.CargoScoop.OnChange += (obj, eventArgs) => FindEffect($"Status.CargoScoop:{eventArgs}");
79 | //ship.SilentRunning.OnChange += (obj, eventArgs) => FindEffect($"Status.SilentRunning:{eventArgs}");
80 | //ship.Scooping.OnChange += (obj, eventArgs) => FindEffect($"Status.Scooping:{eventArgs}");
81 | //ship.SrvHandbreak.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHandbreak:{eventArgs}");
82 | //ship.SrvTurrent.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvTurrent:{eventArgs}");
83 | //ship.SrvNearShip.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvNearShip:{eventArgs}");
84 | //ship.SrvDriveAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvDriveAssist:{eventArgs}");
85 | //ship.MassLocked.OnChange += (obj, eventArgs) => FindEffect($"Status.MassLocked:{eventArgs}");
86 | //ship.FsdCharging.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCharging:{eventArgs}");
87 | //ship.FsdCooldown.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCooldown:{eventArgs}");
88 | //ship.LowFuel.OnChange += (obj, eventArgs) => FindEffect($"Status.LowFuel:{eventArgs}");
89 | //ship.Overheating.OnChange += (obj, eventArgs) => FindEffect($"Status.Overheating:{eventArgs}");
90 | //ship.HasLatLong.OnChange += (obj, eventArgs) => FindEffect($"Status.HasLatLong:{eventArgs}");
91 | //ship.InDanger.OnChange += (obj, eventArgs) => FindEffect($"Status.InDanger:{eventArgs}");
92 | //ship.InInterdiction.OnChange += (obj, eventArgs) => FindEffect($"Status.InInterdiction:{eventArgs}");
93 | //ship.InMothership.OnChange += (obj, eventArgs) => FindEffect($"Status.InMothership:{eventArgs}");
94 | //ship.InFighter.OnChange += (obj, eventArgs) => FindEffect($"Status.InFighter:{eventArgs}");
95 | //ship.InSrv.OnChange += (obj, eventArgs) => FindEffect($"Status.InSrv:{eventArgs}");
96 | //ship.AnalysisMode.OnChange += (obj, eventArgs) => FindEffect($"Status.AnalysisMode:{eventArgs}");
97 | //ship.NightVision.OnChange += (obj, eventArgs) => FindEffect($"Status.NightVision:{eventArgs}");
98 | //ship.AltitudeFromAverageRadius.OnChange += (obj, eventArgs) => FindEffect($"Status.AltitudeFromAverageRadius:{eventArgs}");
99 | //ship.FsdJump.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdJump:{eventArgs}");
100 | //ship.SrvHighBeam.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHighBeam:{eventArgs}");
101 |
102 |
103 | //ship.Docked.OnChange += (obj, eventArgs) => FindEffect($"Status.Docked:{eventArgs}");
104 | //ship.Landed.OnChange += (obj, eventArgs) => FindEffect($"Status.Landed:{eventArgs}");
105 | //ship.Gear.OnChange += (obj, eventArgs) => FindEffect($"Status.Gear:{eventArgs}");
106 | //ship.Shields.OnChange += (obj, eventArgs) => FindEffect($"Status.Shields:{eventArgs}");
107 | //ship.Supercruise.OnChange += (obj, eventArgs) => FindEffect($"Status.Supercruise:{eventArgs}");
108 | //ship.FlightAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.FlightAssist:{eventArgs}");
109 | //ship.Hardpoints.OnChange += (obj, eventArgs) => FindEffect($"Status.Hardpoints:{eventArgs}");
110 | //ship.Winging.OnChange += (obj, eventArgs) => FindEffect($"Status.Winging:{eventArgs}");
111 | //ship.Lights.OnChange += (obj, eventArgs) => FindEffect($"Status.Lights:{eventArgs}");
112 | //ship.CargoScoop.OnChange += (obj, eventArgs) => FindEffect($"Status.CargoScoop:{eventArgs}");
113 | //ship.SilentRunning.OnChange += (obj, eventArgs) => FindEffect($"Status.SilentRunning:{eventArgs}");
114 | //ship.Scooping.OnChange += (obj, eventArgs) => FindEffect($"Status.Scooping:{eventArgs}");
115 | //ship.SrvHandbreak.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHandbreak:{eventArgs}");
116 | //ship.SrvTurrent.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvTurrent:{eventArgs}");
117 | //ship.SrvNearShip.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvNearShip:{eventArgs}");
118 | //ship.SrvDriveAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvDriveAssist:{eventArgs}");
119 | //ship.MassLocked.OnChange += (obj, eventArgs) => FindEffect($"Status.MassLocked:{eventArgs}");
120 | //ship.FsdCharging.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCharging:{eventArgs}");
121 | //ship.FsdCooldown.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCooldown:{eventArgs}");
122 | //ship.LowFuel.OnChange += (obj, eventArgs) => FindEffect($"Status.LowFuel:{eventArgs}");
123 | //ship.Overheating.OnChange += (obj, eventArgs) => FindEffect($"Status.Overheating:{eventArgs}");
124 | //ship.HasLatLong.OnChange += (obj, eventArgs) => FindEffect($"Status.HasLatLong:{eventArgs}");
125 | //ship.InDanger.OnChange += (obj, eventArgs) => FindEffect($"Status.InDanger:{eventArgs}");
126 | //ship.InInterdiction.OnChange += (obj, eventArgs) => FindEffect($"Status.InInterdiction:{eventArgs}");
127 | //ship.InMothership.OnChange += (obj, eventArgs) => FindEffect($"Status.InMothership:{eventArgs}");
128 | //ship.InFighter.OnChange += (obj, eventArgs) => FindEffect($"Status.InFighter:{eventArgs}");
129 | //ship.InSrv.OnChange += (obj, eventArgs) => FindEffect($"Status.InSrv:{eventArgs}");
130 | //ship.AnalysisMode.OnChange += (obj, eventArgs) => FindEffect($"Status.AnalysisMode:{eventArgs}");
131 | //ship.NightVision.OnChange += (obj, eventArgs) => FindEffect($"Status.NightVision:{eventArgs}");
132 | //ship.AltitudeFromAverageRadius.OnChange += (obj, eventArgs) => FindEffect($"Status.AltitudeFromAverageRadius:{eventArgs}");
133 | //ship.FsdJump.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdJump:{eventArgs}");
134 | //ship.SrvHighBeam.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHighBeam:{eventArgs}");
135 | }
136 |
137 | private void ShipStatusEvent(dynamic e)
138 | {
139 | logger.LogDebug($"Event {e}");
140 | }
141 |
142 | private void Events_AllEvent(dynamic e)
143 | {
144 | var eventKey = e.ToString();
145 | FindEffect(eventKey);
146 | }
147 |
148 | private void FindEffect(string eventKey)
149 | {
150 | logger.LogDebug($"Event {eventKey}");
151 |
152 | foreach (var device in Devices)
153 | {
154 | if (device.EventSettings.ContainsKey(eventKey))
155 | {
156 | var eventConfig = device.EventSettings[eventKey];
157 | var result = device.Device?.PlayFileEffect(eventConfig.ForceFile, eventConfig.Duration);
158 | }
159 | }
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/Journals/Device.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Journals
6 | {
7 | public class Device
8 | {
9 | public string ProductGuid { get; set; }
10 | public string ProductName { get; set; }
11 | public bool AutoCenter { get; set; } = true;
12 | public int ForceFeedbackGain { get; set; } = 10000;
13 | public List StatusEvents { get; set; } = new List();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Journals/DeviceEvents.cs:
--------------------------------------------------------------------------------
1 | using ForceFeedbackSharpDx;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Journals
7 | {
8 | public class DeviceEvents
9 | {
10 | public ForceFeedbackController Device { get; set; }
11 | public Dictionary EventSettings { get; set; } = new Dictionary();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Journals/EventConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Journals
6 | {
7 | public class EventConfiguration
8 | {
9 | public string Event { get; set; }
10 | public string ForceFile { get; set; }
11 | public int Duration { get; set; } = 250;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Journals/Journals.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Journals/Settings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Journals
6 | {
7 | public class Settings
8 | {
9 | public List Devices { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 bobhelander
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EDForceFeedback
2 | Elite Dangerous Force Feedback with a Microsoft Force Feedback 2 Joystick (MSFFB2)
3 |
4 | ### Description
5 | EDForceFeedback.exe is a console program that runs during a Elite Dangerous session. It watches the ED log files and responds to game events by playing a force feedback editor (.ffe) file.
6 |
7 | It has been tested with the following devices:
8 |
9 | [Microsoft XBox One Controller](https://en.wikipedia.org/wiki/Xbox_One_controller) running the [XInput modification](https://steamcommunity.com/discussions/forum/1/541907867790900215/)
10 |
11 | [Microsoft Sidewinder Force Feedback 2](https://en.wikipedia.org/wiki/Microsoft_SideWinder#Force_Feedback_2) joystick.
12 |
13 | [Saitek Cyborg 3D Force Stick](https://www.yumpu.com/en/document/view/38049421/cyborg-force-manualqxd-saitekcom)
14 |
15 | ### Usage
16 | 1. Connect your joystick/gamepad and run the EDForceFeedback.exe program.
17 | 2. Start Elite Dangerous
18 | 3. In-game events like deploy/retract hardpoints and deploy/retract landing gear will send the configured forces to the joystick.
19 |
20 | ### Configuration
21 |
22 | The `settings.json` file contains the device and the forces that will be played when an event occurs. Multiple different devices can be configured with different effects for each device.
23 |
24 | Included in the package are several different examples of different configurations.
25 |
26 | ###### Devices
27 |
28 |
29 | "Devices": [
30 | {
31 | "ProductGuid": "02dd045e-0000-0000-0000-504944564944",
32 | "ProductName": "Controller (Xbox One For Windows)",
33 |
34 | "StatusEvents": [
35 | ...
36 |
37 | Each device and the configured effects for the device has it's own section. If the device guid or product name are unknown, you may attempt to use the values the program outputs for the connected devices while it is initializing.
38 |
39 | ###### ProductGuid & ProductName
40 |
41 | Both values are searched against the list during initialization. If either is found the device is selected.
42 |
43 | ###### Autocenter
44 |
45 | The Microsoft Force Feedback device sometimes turns off the autocenter value after playing an effect. Setting this value to true, resets the centering spring.
46 |
47 | ###### ForceFeedbackGain
48 |
49 | This value is the strenth of the effects. The valid range is 0-10000.
50 |
51 | ###### StatusEvents
52 |
53 | Each event can have a different force played for the on or off state. The on/off state for the "Docked" event is the following events "Status.Docked:True" happens when the ship is docked and "Status.Docked:False" happens when the ship takes off.
54 |
55 | {
56 | "Event": "Status.Docked:True",
57 | "ForceFile": "Dock.ffe",
58 | "Duration": 2000
59 | }
60 |
61 | ###### Event
62 | The `"Event"` Field
63 | The [EliteAPI](https://github.com/EliteAPI/EliteAPI) StatusEvent name and state to respond to.
64 | The format is: Status.*StatusEventName*:*[True or False]*
65 |
66 | ###### ForceFile
67 | The `"ForceFile"` Field
68 | The name of the force file (.ffe) to play when this event is detected. The force files can be found under the .\Forces folder. There is a force file editor included under the .\FFUtils folder. See the *Creating And Editing* forces section for more information.
69 |
70 | ###### Duration
71 | The `"Duration"` Field
72 | This is how long the force will be played. The value is in milliseconds (1 Second = 1000 milliseconds). The forces will be stopped after this amount of time even if the .ffe file is configured to play longer.
73 |
74 | ##### Additional Events
75 | The `settings.json` [json](https://www.json.org/) file only has a few of the status events defined. Additional status events are provided by the [EliteAPI](https://github.com/EliteAPI/EliteAPI) and can be added to the `StatusEvents` array in the settings file. During game play, the console window will output the names of the events that were detected. You can use these names to add additional forces.
76 |
77 | ### Creating and Editing Forces
78 | On startup all .ffe files in the .\Forces folder will be loaded. To create new forces use `fedit.exe` and save the file in the .\Forces folder.
79 |
80 | ###### .\FFUtils
81 | These are Microsoft utilities to edit and configure force feedback devices. They may get removed from this location. They can be found in various locations on the internet. They were part of the DirectX DirectInput developer packages.
82 |
83 | csFeedback.exe
84 | fedit.exe
85 | FFConst.exe
86 |
87 | ###### fedit.exe
88 | This utility allows you to build your own custom forces. For an example, open the Cargo.ffe file. The forces can overlay and played before, after, and simultaneously to create complex movement and effects.
89 |
90 | Enjoy! - Bob (CMDR Axe_)
91 |
--------------------------------------------------------------------------------
/TestForceFeedback/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/TestForceFeedback/EliteAPIMock.cs:
--------------------------------------------------------------------------------
1 | using EliteAPI.Abstractions;
2 | using EliteAPI.Options.Bindings.Models;
3 | using EliteAPI.Status.Backpack.Abstractions;
4 | using EliteAPI.Status.Cargo.Abstractions;
5 | using EliteAPI.Status.Commander.Abstractions;
6 | using EliteAPI.Status.Market.Abstractions;
7 | using EliteAPI.Status.Modules.Abstractions;
8 | using EliteAPI.Status.NavRoute.Abstractions;
9 | using EliteAPI.Status.Outfitting.Abstractions;
10 | using EliteAPI.Status.Ship.Abstractions;
11 | using EliteAPI.Status.Shipyard.Abstractions;
12 | using System;
13 | using System.Collections.Generic;
14 | using System.Linq;
15 | using System.Text;
16 | using System.Threading.Tasks;
17 |
18 | namespace TestForceFeedback
19 | {
20 | public class EliteAPIMock : IEliteDangerousApi
21 | {
22 | public string Version => throw new NotImplementedException();
23 |
24 | public EliteAPI.Event.Handler.EventHandler Events => throw new NotImplementedException();
25 |
26 | public IShip Ship => throw new NotImplementedException();
27 |
28 | public ICommander Commander => throw new NotImplementedException();
29 |
30 | public IBackpack Backpack => throw new NotImplementedException();
31 |
32 | public IShipyard Shipyard => throw new NotImplementedException();
33 |
34 | public INavRoute NavRoute => throw new NotImplementedException();
35 |
36 | public ICargo Cargo => throw new NotImplementedException();
37 |
38 | public IMarket Market => throw new NotImplementedException();
39 |
40 | public IModules Modules => throw new NotImplementedException();
41 |
42 | public IOutfitting Outfitting => throw new NotImplementedException();
43 |
44 | public IBindings Bindings => throw new NotImplementedException();
45 |
46 | public bool IsInitialized => throw new NotImplementedException();
47 |
48 | public bool IsRunning => throw new NotImplementedException();
49 |
50 | public bool HasCatchedUp => throw new NotImplementedException();
51 |
52 | public event System.EventHandler OnCatchedUp;
53 | public event System.EventHandler OnStart;
54 | public event System.EventHandler OnStop;
55 | public event EventHandler OnError;
56 |
57 | public Task InitializeAsync()
58 | {
59 | throw new NotImplementedException();
60 | }
61 |
62 | public Task StartAsync()
63 | {
64 | throw new NotImplementedException();
65 | }
66 |
67 | public Task StopAsync()
68 | {
69 | throw new NotImplementedException();
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/TestForceFeedback/EliteShipMock.cs:
--------------------------------------------------------------------------------
1 | using EliteAPI.Status;
2 | using EliteAPI.Status.Abstractions;
3 | using EliteAPI.Status.Ship;
4 | using EliteAPI.Status.Ship.Abstractions;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace TestForceFeedback
12 | {
13 | public class EliteShipMock : EliteStatusMock, IShip
14 | {
15 | ///
16 | public StatusProperty Available { get; } = new StatusProperty(false);
17 |
18 | ///
19 | public StatusProperty Docked { get; } = new StatusProperty(false);
20 |
21 | ///
22 | public StatusProperty Landed { get; } = new StatusProperty(false);
23 |
24 | ///
25 | public StatusProperty Gear { get; } = new StatusProperty(false);
26 |
27 | ///
28 | public StatusProperty Shields { get; } = new StatusProperty(false);
29 |
30 | ///
31 | public StatusProperty Supercruise { get; } = new StatusProperty(false);
32 | ///
33 | public StatusProperty FlightAssist { get; } = new StatusProperty(false);
34 |
35 | ///
36 | public StatusProperty Hardpoints { get; } = new StatusProperty(false);
37 |
38 | ///
39 | public StatusProperty Winging { get; } = new StatusProperty(false);
40 |
41 | ///
42 | public StatusProperty Lights { get; } = new StatusProperty(false);
43 |
44 | ///
45 | public StatusProperty CargoScoop { get; } = new StatusProperty(false);
46 |
47 | ///
48 | public StatusProperty SilentRunning { get; } = new StatusProperty(false);
49 |
50 | ///
51 | public StatusProperty Scooping { get; } = new StatusProperty(false);
52 |
53 | ///
54 | public StatusProperty SrvHandbreak { get; } = new StatusProperty(false);
55 |
56 | ///
57 | public StatusProperty SrvTurrent { get; } = new StatusProperty(false);
58 |
59 | ///
60 | public StatusProperty SrvNearShip { get; } = new StatusProperty(false);
61 |
62 | ///
63 | public StatusProperty SrvDriveAssist { get; } = new StatusProperty(false);
64 |
65 | ///
66 | public StatusProperty MassLocked { get; } = new StatusProperty(false);
67 |
68 | ///
69 | public StatusProperty FsdCharging { get; } = new StatusProperty(false);
70 |
71 | ///
72 | public StatusProperty FsdCooldown { get; } = new StatusProperty(false);
73 |
74 | ///
75 | public StatusProperty LowFuel { get; } = new StatusProperty(false);
76 |
77 | ///
78 | public StatusProperty Overheating { get; } = new StatusProperty(false);
79 |
80 | ///
81 | public StatusProperty HasLatLong { get; } = new StatusProperty(false);
82 |
83 | ///
84 | public StatusProperty InDanger { get; } = new StatusProperty(false);
85 |
86 | ///
87 | public StatusProperty InInterdiction { get; } = new StatusProperty(false);
88 |
89 | ///
90 | public StatusProperty InMothership { get; } = new StatusProperty(false);
91 |
92 | ///
93 | public StatusProperty InFighter { get; } = new StatusProperty(false);
94 |
95 | ///
96 | public StatusProperty InSrv { get; } = new StatusProperty(false);
97 |
98 | ///
99 | public StatusProperty AnalysisMode { get; } = new StatusProperty(false);
100 |
101 | ///
102 | public StatusProperty NightVision { get; } = new StatusProperty(false);
103 |
104 | ///
105 | public StatusProperty AltitudeFromAverageRadius { get; } = new StatusProperty(false);
106 |
107 | ///
108 | public StatusProperty FsdJump { get; } = new StatusProperty(false);
109 |
110 | ///
111 | public StatusProperty SrvHighBeam { get; } = new StatusProperty(false);
112 |
113 | public StatusProperty Flags => throw new NotImplementedException();
114 |
115 | public StatusProperty Pips => throw new NotImplementedException();
116 |
117 | public StatusProperty FireGroup => throw new NotImplementedException();
118 |
119 | public StatusProperty GuiFocus => throw new NotImplementedException();
120 |
121 | public StatusProperty Fuel => throw new NotImplementedException();
122 |
123 | public StatusProperty Cargo => throw new NotImplementedException();
124 |
125 | public StatusProperty LegalState => throw new NotImplementedException();
126 |
127 | public StatusProperty Latitude => throw new NotImplementedException();
128 |
129 | public StatusProperty Altitude => throw new NotImplementedException();
130 |
131 | public StatusProperty Longitude => throw new NotImplementedException();
132 |
133 | public StatusProperty Heading => throw new NotImplementedException();
134 |
135 | public StatusProperty Body => throw new NotImplementedException();
136 |
137 | public StatusProperty BodyRadius => throw new NotImplementedException();
138 |
139 | ///
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/TestForceFeedback/EliteStatusMock.cs:
--------------------------------------------------------------------------------
1 | using EliteAPI.Status.Abstractions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace TestForceFeedback
9 | {
10 | public class EliteStatusMock : IStatus
11 | {
12 | //private IRawStatus _rawStatus;
13 |
14 | ///
15 | public event EventHandler OnChange;
16 |
17 | ///
18 | public string ToJson()
19 | {
20 | throw new NotImplementedException();
21 | }
22 |
23 | void IStatus.TriggerOnChange(IRawStatus status)
24 | {
25 | OnChange?.Invoke(this, status);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/TestForceFeedback/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/TestForceFeedback/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
23 |
24 |
25 |
26 |
27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
28 |
29 |
30 |
31 |
32 | The order of preloaded assemblies, delimited with line breaks.
33 |
34 |
35 |
36 |
37 |
38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
39 |
40 |
41 |
42 |
43 | Controls if .pdbs for reference assemblies are also embedded.
44 |
45 |
46 |
47 |
48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
49 |
50 |
51 |
52 |
53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
54 |
55 |
56 |
57 |
58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
59 |
60 |
61 |
62 |
63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
64 |
65 |
66 |
67 |
68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
69 |
70 |
71 |
72 |
73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
74 |
75 |
76 |
77 |
78 | A list of unmanaged 32 bit assembly names to include, delimited with |.
79 |
80 |
81 |
82 |
83 | A list of unmanaged 64 bit assembly names to include, delimited with |.
84 |
85 |
86 |
87 |
88 | The order of preloaded assemblies, delimited with |.
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
97 |
98 |
99 |
100 |
101 | A comma-separated list of error codes that can be safely ignored in assembly verification.
102 |
103 |
104 |
105 |
106 | 'false' to turn off automatic generation of the XML Schema file.
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Cargo.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Cargo.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/CenterSpringXY.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/CenterSpringXY.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Damper.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Damper.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Dock.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Dock.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Gear.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Gear.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Hardpoints.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Hardpoints.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Landed.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Landed.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/Vibrate.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/Vibrate.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Forces/VibrateSide.ffe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobhelander/EDForceFeedback/e5a23dca26507aa9b123912e81ea124b6fd11240/TestForceFeedback/Forces/VibrateSide.ffe
--------------------------------------------------------------------------------
/TestForceFeedback/Program.cs:
--------------------------------------------------------------------------------
1 | using EliteAPI.Abstractions;
2 | using ForceFeedbackSharpDx;
3 | using Journals;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 | using Microsoft.Extensions.Logging;
7 | using Newtonsoft.Json;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.IO;
11 | using System.Linq;
12 | using System.Text;
13 | using System.Threading.Tasks;
14 |
15 | namespace TestForceFeedback
16 | {
17 | internal static class Program
18 | {
19 | //static string feedbackGuid = "001b045e-0000-0000-0000-504944564944"; // MS ForceFeedBack 2
20 | //static string feedbackProduct = "SideWinder Force Feedback 2 Joystick"; // MS ForceFeedBack 2
21 |
22 | static string feedbackGuid = "02dd045e-0000-0000-0000-504944564944"; // XBOX One
23 | static string feedbackProduct = "Controller (Xbox One For Windows)"; // XBOX One
24 |
25 | static void Main_bak(string[] args)
26 | {
27 | var msffb2 = new ForceFeedbackController();
28 | msffb2.Initialize(feedbackGuid, feedbackProduct, @".\Forces", false, 10000);
29 |
30 | Console.ReadKey();
31 |
32 | Console.WriteLine("Damper.ffe");
33 | var effects = msffb2.PlayFileEffect("Damper.ffe", -1);
34 |
35 | Console.ReadKey();
36 |
37 | Console.WriteLine("SetActuators(false)");
38 | msffb2.SetActuators(false);
39 |
40 | Console.ReadKey();
41 |
42 | Console.WriteLine("SetActuators(true)");
43 | msffb2.SetActuators(true);
44 |
45 | Console.ReadKey();
46 |
47 | Console.WriteLine("VibrateSide.ffe");
48 | var vibrate = msffb2.PlayFileEffect("VibrateSide.ffe", -1);
49 |
50 | Console.ReadKey();
51 |
52 | Console.WriteLine("StopEffects");
53 | msffb2.StopEffects(effects);
54 | msffb2.StopEffects(vibrate);
55 |
56 | Console.ReadKey();
57 |
58 | Console.WriteLine("CenterSpringXY.ffe");
59 | var centerEffects = msffb2.PlayFileEffect("CenterSpringXY.ffe", -1);
60 |
61 | Console.ReadKey();
62 |
63 | if (centerEffects != null)
64 | {
65 | Console.WriteLine("Gain = 5000");
66 | var effectParams = centerEffects[0].GetParameters(SharpDX.DirectInput.EffectParameterFlags.Gain);
67 |
68 | effectParams.Gain = 5000;
69 |
70 | centerEffects[0].SetParameters(effectParams, SharpDX.DirectInput.EffectParameterFlags.Gain | SharpDX.DirectInput.EffectParameterFlags.NoRestart);
71 |
72 | Console.ReadKey();
73 |
74 | Console.WriteLine("Gain = 10000");
75 | effectParams.Gain = 10000;
76 |
77 | centerEffects[0].SetParameters(effectParams, SharpDX.DirectInput.EffectParameterFlags.Gain | SharpDX.DirectInput.EffectParameterFlags.NoRestart);
78 |
79 | Console.ReadKey();
80 | }
81 |
82 | Console.WriteLine("StopEffects(centerEffects)");
83 | msffb2.StopEffects(centerEffects);
84 |
85 | Console.ReadKey();
86 | /*
87 | msffb2.PlayFileEffect("VibrateSide.ffe");
88 | //msffb2.PlayFileEffect("VibrateSide.ffe");
89 | // msffb2.PlayFileEffect("VibrateSide.ffe");
90 |
91 | Console.ReadKey();
92 |
93 | msffb2.PlayFileEffect("Landed.ffe");
94 |
95 | Console.ReadKey();
96 |
97 | msffb2.PlayFileEffect("Gear.ffe");
98 |
99 | //msffb2.CenterOff();
100 |
101 | Console.ReadKey();
102 | */
103 | }
104 |
105 | public static IServiceCollection AddEliteAPI(this IServiceCollection services)
106 | {
107 | // EliteAPI
108 | services.AddSingleton();
109 | services.AddSingleton();
110 | return services;
111 | }
112 |
113 |
114 | static void Main(string[] args)
115 | {
116 | var fileName = $"{Directory.GetCurrentDirectory()}\\settings.json";
117 |
118 | // Check if a settings file was specified
119 | if (args?.Length == 1)
120 | {
121 | if (args[0].CompareTo("-h") == 0 || args[0].CompareTo("help") == 0)
122 | {
123 | Console.WriteLine("EDForceFeedBack: EDForceFeedback.exe is a console program that runs during a Elite Dangerous session.");
124 | Console.WriteLine("It watches the ED log files and responds to game events by playing a force feedback editor (.ffe) file.");
125 | Console.WriteLine();
126 | Console.WriteLine("Usage:");
127 | Console.WriteLine("EDForceFeedback.exe -h Output this help.");
128 | Console.WriteLine(@"EDForceFeedback.exe c:\settings.json Override the default settings file and use this instead.");
129 | Console.WriteLine($"EDForceFeedback.exe Will default to the settings file {Directory.GetCurrentDirectory()}\\settings.json");
130 | return;
131 | }
132 | else
133 | {
134 | fileName = args[0];
135 | }
136 | }
137 |
138 | Console.WriteLine($"Using setting file: {fileName}");
139 |
140 | var settings = JsonConvert.DeserializeObject(File.ReadAllText(fileName));
141 |
142 | IEliteDangerousApi eliteAPI;
143 | EliteAPI.Status.Ship.Abstractions.IShip ship;
144 | ILogger logger;
145 | IHost host;
146 |
147 | List Devices = new List();
148 |
149 | // Inject the logger and EliteApi services into host
150 | host = Host.CreateDefaultBuilder()
151 | .ConfigureServices((context, service) =>
152 | {
153 | service.AddEliteAPI();
154 | service.AddTransient();
155 | service.AddLogging(builder =>
156 | builder.AddSimpleConsole(options => { options.SingleLine = true; options.TimestampFormat = "hh:mm:ss "; }).SetMinimumLevel(LogLevel.Debug));
157 | })
158 | .Build();
159 |
160 | // Get the services from the Host object
161 | eliteAPI = host.Services.GetService();
162 | ship = host.Services.GetService();
163 | logger = host.Services.GetRequiredService>();
164 |
165 | foreach (var device in settings.Devices)
166 | {
167 | var ffDevice = new ForceFeedbackController() { Logger = logger };
168 | if (ffDevice.Initialize(
169 | device.ProductGuid,
170 | device.ProductName,
171 | @".\Forces",
172 | device.AutoCenter,
173 | device.ForceFeedbackGain) == false)
174 | {
175 | logger.LogError($"Device Initialization failed: {device.ProductGuid}: {device.ProductName}");
176 | continue;
177 | }
178 |
179 | var deviceEvents = new DeviceEvents
180 | {
181 | EventSettings = device.StatusEvents.ToDictionary(v => v.Event, v => v),
182 | Device = ffDevice
183 | };
184 |
185 | Devices.Add(deviceEvents);
186 | }
187 |
188 |
189 | // Start the api
190 | //await eliteAPI.StartAsync().ConfigureAwait(false);
191 |
192 | //eliteAPI.Events.AllEvent += Events_AllEvent;
193 |
194 | ship.Docked.OnChange += (obj, eventArgs) => FindEffect($"Status.Docked:{eventArgs}", Devices);
195 | ship.Landed.OnChange += (obj, eventArgs) => FindEffect($"Status.Landed:{eventArgs}", Devices);
196 | ship.Gear.OnChange += (obj, eventArgs) => FindEffect($"Status.Gear:{eventArgs}", Devices);
197 | ship.Shields.OnChange += (obj, eventArgs) => FindEffect($"Status.Shields:{eventArgs}", Devices);
198 | ship.Supercruise.OnChange += (obj, eventArgs) => FindEffect($"Status.Supercruise:{eventArgs}", Devices);
199 | ship.FlightAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.FlightAssist:{eventArgs}", Devices);
200 | ship.Hardpoints.OnChange += (obj, eventArgs) => FindEffect($"Status.Hardpoints:{eventArgs}", Devices);
201 | ship.Winging.OnChange += (obj, eventArgs) => FindEffect($"Status.Winging:{eventArgs}", Devices);
202 | ship.Lights.OnChange += (obj, eventArgs) => FindEffect($"Status.Lights:{eventArgs}", Devices);
203 | ship.CargoScoop.OnChange += (obj, eventArgs) => FindEffect($"Status.CargoScoop:{eventArgs}", Devices);
204 | ship.SilentRunning.OnChange += (obj, eventArgs) => FindEffect($"Status.SilentRunning:{eventArgs}", Devices);
205 | ship.Scooping.OnChange += (obj, eventArgs) => FindEffect($"Status.Scooping:{eventArgs}", Devices);
206 | ship.SrvHandbreak.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHandbreak:{eventArgs}", Devices);
207 | ship.SrvTurrent.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvTurrent:{eventArgs}", Devices);
208 | ship.SrvNearShip.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvNearShip:{eventArgs}", Devices);
209 | ship.SrvDriveAssist.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvDriveAssist:{eventArgs}", Devices);
210 | ship.MassLocked.OnChange += (obj, eventArgs) => FindEffect($"Status.MassLocked:{eventArgs}", Devices);
211 | ship.FsdCharging.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCharging:{eventArgs}", Devices);
212 | ship.FsdCooldown.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdCooldown:{eventArgs}", Devices);
213 | ship.LowFuel.OnChange += (obj, eventArgs) => FindEffect($"Status.LowFuel:{eventArgs}", Devices);
214 | ship.Overheating.OnChange += (obj, eventArgs) => FindEffect($"Status.Overheating:{eventArgs}", Devices);
215 | ship.HasLatLong.OnChange += (obj, eventArgs) => FindEffect($"Status.HasLatLong:{eventArgs}", Devices);
216 | ship.InDanger.OnChange += (obj, eventArgs) => FindEffect($"Status.InDanger:{eventArgs}", Devices);
217 | ship.InInterdiction.OnChange += (obj, eventArgs) => FindEffect($"Status.InInterdiction:{eventArgs}", Devices);
218 | ship.InMothership.OnChange += (obj, eventArgs) => FindEffect($"Status.InMothership:{eventArgs}", Devices);
219 | ship.InFighter.OnChange += (obj, eventArgs) => FindEffect($"Status.InFighter:{eventArgs}", Devices);
220 | ship.InSrv.OnChange += (obj, eventArgs) => FindEffect($"Status.InSrv:{eventArgs}", Devices);
221 | ship.AnalysisMode.OnChange += (obj, eventArgs) => FindEffect($"Status.AnalysisMode:{eventArgs}", Devices);
222 | ship.NightVision.OnChange += (obj, eventArgs) => FindEffect($"Status.NightVision:{eventArgs}", Devices);
223 | ship.AltitudeFromAverageRadius.OnChange += (obj, eventArgs) => FindEffect($"Status.AltitudeFromAverageRadius:{eventArgs}", Devices);
224 | ship.FsdJump.OnChange += (obj, eventArgs) => FindEffect($"Status.FsdJump:{eventArgs}", Devices);
225 | ship.SrvHighBeam.OnChange += (obj, eventArgs) => FindEffect($"Status.SrvHighBeam:{eventArgs}", Devices);
226 |
227 | while (true)
228 | {
229 | Console.WriteLine("0: Quit");
230 | Console.WriteLine("1: Docked (true)");
231 | Console.WriteLine("2: Landed (true)");
232 | Console.WriteLine("3: Gear (deployed)");
233 | Console.WriteLine("4: Gear (retracted)");
234 | Console.WriteLine("5: Hardpoints (deployed)");
235 | Console.WriteLine("6: Hardpoints (retracted)");
236 | Console.WriteLine("7: Overheating");
237 |
238 | var key = Console.ReadKey();
239 | if (key.KeyChar == '0')
240 | break;
241 | switch (key.KeyChar)
242 | {
243 | case '1':
244 | ship.Docked.OnChange.Invoke(null, true);
245 | break;
246 | case '2':
247 | ship.Landed.OnChange.Invoke(null, true);
248 | break;
249 | case '3':
250 | ship.Gear.OnChange.Invoke(null, true);
251 | break;
252 | case '4':
253 | ship.Gear.OnChange.Invoke(null, false);
254 | break;
255 | case '5':
256 | ship.Hardpoints.OnChange.Invoke(null, true);
257 | break;
258 | case '6':
259 | ship.Hardpoints.OnChange.Invoke(null, false);
260 | break;
261 | case '7':
262 | ship.Overheating.OnChange.Invoke(null, true);
263 | break;
264 | }
265 | }
266 | }
267 |
268 | //private static void Events_AllEvent(object sender, dynamic e)
269 | //{
270 | // var eventKey = e.ToString();
271 | // FindEffect(eventKey);
272 | //}
273 |
274 | private static void FindEffect(string eventKey, IEnumerable Devices)
275 | {
276 | foreach (var device in Devices)
277 | {
278 | if (device.EventSettings.ContainsKey(eventKey))
279 | {
280 | var eventConfig = device.EventSettings[eventKey];
281 | var result = device.Device?.PlayFileEffect(eventConfig.ForceFile, eventConfig.Duration);
282 | }
283 | }
284 | }
285 | }
286 | }
287 |
--------------------------------------------------------------------------------
/TestForceFeedback/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TestForceFeedback")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestForceFeedback")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("574005ed-6b12-4092-ac48-71b5b302f8ad")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TestForceFeedback/TestForceFeedback.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {574005ED-6B12-4092-AC48-71B5B302F8AD}
8 | Exe
9 | TestForceFeedback
10 | TestForceFeedback
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
38 |
39 |
40 | ..\packages\Microsoft.Extensions.DependencyInjection.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.dll
41 |
42 |
43 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll
44 |
45 |
46 | ..\packages\Microsoft.Extensions.Logging.5.0.0\lib\net461\Microsoft.Extensions.Logging.dll
47 |
48 |
49 | ..\packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll
50 |
51 |
52 | ..\packages\Microsoft.Extensions.Options.5.0.0\lib\net461\Microsoft.Extensions.Options.dll
53 |
54 |
55 | ..\packages\Microsoft.Extensions.Primitives.5.0.0\lib\net461\Microsoft.Extensions.Primitives.dll
56 |
57 |
58 | ..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll
59 |
60 |
61 | ..\packages\SharpDX.DirectInput.4.2.0\lib\net45\SharpDX.DirectInput.dll
62 |
63 |
64 |
65 |
66 | ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll
67 |
68 |
69 | ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Always
87 |
88 |
89 | Always
90 |
91 |
92 | Always
93 |
94 |
95 | Always
96 |
97 |
98 | Always
99 |
100 |
101 | Always
102 |
103 |
104 | Always
105 |
106 |
107 | Always
108 |
109 |
110 | Always
111 |
112 |
113 |
114 |
115 | {D3C53E08-943F-4DD8-9939-6CD5858E28AC}
116 | ForceFeedbackSharpDx
117 |
118 |
119 |
120 |
121 | 9.0.3
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/TestForceFeedback/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
--------------------------------------------------------------------------------