├── .gitignore
├── ConfigurationTool_Rewrite.sln
├── GensConfigTool
├── App.xaml
├── App.xaml.cs
├── ConfigurationTool.csproj
├── ConfigurationTool.ico
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── Handlers
│ ├── ConfigurationHandler.cs
│ ├── DevicesHandler.cs
│ ├── NvidiaHandler.cs
│ └── RegistryHandler.cs
├── Helpers
│ ├── EnumOrder.cs
│ ├── Extensions.cs
│ ├── GraphicsDeviceTypes.cs
│ ├── ThemeHelper.cs
│ └── UacHelper.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Model
│ ├── Configuration.cs
│ ├── Configurations
│ │ ├── AnalyticsConfiguration.cs
│ │ ├── AudioConfiguration.cs
│ │ ├── GraphicsConfiguration.cs
│ │ ├── IConfiguration.cs
│ │ ├── InputConfiguration.cs
│ │ └── RegistryConfiguration.cs
│ ├── Devices
│ │ ├── AudioDevice.cs
│ │ ├── GraphicsAdapter.cs
│ │ ├── InputDevice.cs
│ │ ├── Keyboard.cs
│ │ └── XinputController.cs
│ ├── Input
│ │ ├── AxisMap.cs
│ │ └── ButtonConfiguration.cs
│ └── Settings
│ │ ├── DepthFormat.cs
│ │ ├── DisplayMode.cs
│ │ ├── HighLow.cs
│ │ ├── Language.cs
│ │ ├── OnOff.cs
│ │ ├── RefreshRate.cs
│ │ └── Resolution.cs
└── Resources
│ ├── ConfigurationTool.ico
│ ├── Dictionary.xaml
│ ├── Images
│ ├── Buttons
│ │ ├── A.png
│ │ ├── B.png
│ │ ├── Back.png
│ │ ├── LB.png
│ │ ├── LT.png
│ │ ├── RB.png
│ │ ├── RT.png
│ │ ├── Start.png
│ │ ├── Stick.png
│ │ ├── Stick_Down.png
│ │ ├── Stick_Left.png
│ │ ├── Stick_Right.png
│ │ ├── Stick_Up.png
│ │ ├── X.png
│ │ └── Y.png
│ ├── Display.png
│ ├── FXAA.png
│ ├── Icon.png
│ ├── Misc.png
│ ├── None.png
│ ├── Res.png
│ ├── Shadows.png
│ └── Vsync.png
│ └── Themes
│ ├── Dark.xaml
│ ├── Light.xaml
│ └── ThemeBase.xaml
├── Images
├── Config.png
├── Config_Dark.png
├── Input.png
└── Input_Dark.png
├── README.md
└── appveyor.yml
/.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 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
352 | *.cfg
353 | *.config
354 | *.psd
--------------------------------------------------------------------------------
/ConfigurationTool_Rewrite.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30804.86
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigurationTool", "GensConfigTool\ConfigurationTool.csproj", "{06895F66-C403-4845-8CD9-711B839F52F0}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x86 = Debug|x86
12 | Release|Any CPU = Release|Any CPU
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {06895F66-C403-4845-8CD9-711B839F52F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {06895F66-C403-4845-8CD9-711B839F52F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {06895F66-C403-4845-8CD9-711B839F52F0}.Debug|x86.ActiveCfg = Debug|x86
19 | {06895F66-C403-4845-8CD9-711B839F52F0}.Debug|x86.Build.0 = Debug|x86
20 | {06895F66-C403-4845-8CD9-711B839F52F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {06895F66-C403-4845-8CD9-711B839F52F0}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {06895F66-C403-4845-8CD9-711B839F52F0}.Release|x86.ActiveCfg = Release|x86
23 | {06895F66-C403-4845-8CD9-711B839F52F0}.Release|x86.Build.0 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {001EEC94-DC53-4ADF-9631-A76311B5F954}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/GensConfigTool/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/GensConfigTool/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Handlers;
2 | using System;
3 | using System.Globalization;
4 | using System.Windows;
5 |
6 | namespace ConfigurationTool
7 | {
8 | ///
9 | /// Interaction logic for App.xaml
10 | ///
11 | public partial class App : Application
12 | {
13 | public App()
14 | {
15 | CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
16 | string[] args = Environment.GetCommandLineArgs();
17 | if (args.Length > 1)
18 | {
19 | RegistryHandler.FixRegistry(int.Parse(args[1]));
20 | Application.Current.Shutdown();
21 | }
22 | NvidiaHandler.InitializeDedicatedGraphics();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/GensConfigTool/ConfigurationTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net472
6 | true
7 | ConfigurationTool.ico
8 | ConfigurationTool.App
9 | Sonic Generations
10 | Sonic Generations
11 | Sonic Generations Configuration Tool
12 |
13 | PTKickass
14 | AnyCPU;x86
15 | ConfigurationTool
16 | ConfigurationTool
17 |
18 |
19 |
20 | true
21 | AnyCPU
22 |
23 | none
24 | false
25 |
26 |
27 |
28 | true
29 | AnyCPU
30 |
31 |
32 |
33 | AnyCPU
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | all
65 | runtime; build; native; contentfiles; analyzers; buildtransitive
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | $(DefaultXamlRuntime)
104 | Designer
105 | Never
106 |
107 |
108 |
109 | Never
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/GensConfigTool/ConfigurationTool.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/ConfigurationTool.ico
--------------------------------------------------------------------------------
/GensConfigTool/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/GensConfigTool/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 (.NET Core) runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
23 |
24 |
25 |
26 |
27 | A list of (.NET Core) runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
28 |
29 |
30 |
31 |
32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
33 |
34 |
35 |
36 |
37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
38 |
39 |
40 |
41 |
42 | The order of preloaded assemblies, delimited with line breaks.
43 |
44 |
45 |
46 |
47 |
48 | 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.
49 |
50 |
51 |
52 |
53 | Controls if .pdbs for reference assemblies are also embedded.
54 |
55 |
56 |
57 |
58 | Controls if (.NET Core) runtime assemblies are also embedded.
59 |
60 |
61 |
62 |
63 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
64 |
65 |
66 |
67 |
68 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
69 |
70 |
71 |
72 |
73 | 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.
74 |
75 |
76 |
77 |
78 | 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.
79 |
80 |
81 |
82 |
83 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
84 |
85 |
86 |
87 |
88 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
89 |
90 |
91 |
92 |
93 | A list of (.NET Core) runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
94 |
95 |
96 |
97 |
98 | A list of (.NET Core) runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.
99 |
100 |
101 |
102 |
103 | A list of unmanaged 32 bit assembly names to include, delimited with |.
104 |
105 |
106 |
107 |
108 | A list of unmanaged 64 bit assembly names to include, delimited with |.
109 |
110 |
111 |
112 |
113 | The order of preloaded assemblies, delimited with |.
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
122 |
123 |
124 |
125 |
126 | A comma-separated list of error codes that can be safely ignored in assembly verification.
127 |
128 |
129 |
130 |
131 | 'false' to turn off automatic generation of the XML Schema file.
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/GensConfigTool/Handlers/ConfigurationHandler.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model;
2 | using ConfigurationTool.Model.Configurations;
3 |
4 | namespace ConfigurationTool.Handlers
5 | {
6 | class ConfigurationHandler
7 | {
8 | private readonly IConfiguration RegistryConfiguration;
9 | private readonly IConfiguration GraphicsConfiguration;
10 | private readonly IConfiguration AudioConfiguration;
11 | private readonly IConfiguration AnalyticsConfiguration;
12 | private readonly IConfiguration InputConfiguration;
13 |
14 | public ConfigurationHandler()
15 | {
16 | RegistryConfiguration = new RegistryConfiguration();
17 | GraphicsConfiguration = new GraphicsConfiguration();
18 | AudioConfiguration = new AudioConfiguration();
19 | AnalyticsConfiguration = new AnalyticsConfiguration();
20 | InputConfiguration = new InputConfiguration();
21 | }
22 |
23 | public Configuration LoadConfiguration()
24 | {
25 | Configuration config = new Configuration();
26 |
27 | RegistryConfiguration.LoadConfiguration(config);
28 | GraphicsConfiguration.LoadConfiguration(config);
29 | AudioConfiguration.LoadConfiguration(config);
30 | AnalyticsConfiguration.LoadConfiguration(config);
31 | InputConfiguration.LoadConfiguration(config);
32 |
33 | return config;
34 | }
35 |
36 | public bool SaveConfiguration(Configuration config)
37 | {
38 | try
39 | {
40 | RegistryConfiguration.SaveConfiguration(config);
41 | GraphicsConfiguration.SaveConfiguration(config);
42 | AudioConfiguration.SaveConfiguration(config);
43 | AnalyticsConfiguration.SaveConfiguration(config);
44 | InputConfiguration.SaveConfiguration(config);
45 | }
46 | catch
47 | {
48 | return false;
49 | }
50 | return true;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/GensConfigTool/Handlers/DevicesHandler.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Helpers;
2 | using ConfigurationTool.Model.Devices;
3 | using ConfigurationTool.Model.Settings;
4 | using ConfigurationTool.Settings.Model;
5 | using SharpDX.Direct3D9;
6 | using SharpDX.DirectSound;
7 | using System.Collections.Generic;
8 | using System.Runtime.InteropServices;
9 | using static ConfigurationTool.Helpers.GraphicsDeviceTypes;
10 |
11 | namespace ConfigurationTool.Handlers
12 | {
13 | class DevicesHandler
14 | {
15 | public static List GetGraphicsAdapters()
16 | {
17 | List toReturn = new List();
18 |
19 | Direct3D d3d = new Direct3D();
20 | foreach (AdapterInformation adapter in d3d.Adapters)
21 | {
22 | GraphicsAdapter currAdapter = new GraphicsAdapter()
23 | {
24 | Name = adapter.Details.DeviceName,
25 | Description = adapter.Details.Description,
26 | GUID = adapter.Details.DeviceIdentifier.ToString(),
27 | Index = adapter.Adapter
28 | };
29 |
30 | // Get the monitor ID
31 | var monitor = new DISPLAYDEV();
32 | monitor.cb = Marshal.SizeOf(monitor);
33 | EnumDisplayDevices(currAdapter.Name, 0, ref monitor, 0);
34 |
35 | if (!string.IsNullOrEmpty(monitor.DeviceName))
36 | {
37 | currAdapter.MonitorID = monitor.DeviceID;
38 | }
39 |
40 | toReturn.InsertElementAscending(currAdapter);
41 |
42 | foreach (SharpDX.Direct3D9.DisplayMode mode in adapter.GetDisplayModes(adapter.CurrentDisplayMode.Format))
43 | {
44 | Resolution res = new Resolution()
45 | {
46 | Width = mode.Width,
47 | Height = mode.Height
48 | };
49 | RefreshRate refreshRate = new RefreshRate(mode.RefreshRate);
50 |
51 | int idx = currAdapter.Resolutions.IndexOf(res);
52 | if (idx >= 0)
53 | {
54 | currAdapter.Resolutions[idx].RefreshRates.InsertElementDescending(refreshRate);
55 | }
56 | else
57 | {
58 | res.RefreshRates.Add(refreshRate);
59 | currAdapter.Resolutions.InsertElementDescending(res);
60 | }
61 | }
62 | }
63 |
64 | return toReturn;
65 | }
66 |
67 | public static IEnumerable GetAudioDevices()
68 | {
69 | List toReturn = new List
70 | {
71 | new AudioDevice(),
72 | new AudioDevice()
73 | {
74 | Name = "None",
75 | GUID = "00000000-0000-0000-0000-000000000000"
76 | }
77 | };
78 | foreach (DeviceInformation device in DirectSound.GetDevices())
79 | {
80 | AudioDevice toAdd = new AudioDevice()
81 | {
82 | Name = device.Description,
83 | GUID = device.DriverGuid.ToString()
84 | };
85 |
86 | // Ignore repeated devices (will also skip default output due to having the same GUID as None)
87 | if (!toReturn.Contains(toAdd))
88 | {
89 | toReturn.Add(toAdd);
90 | }
91 | }
92 | return toReturn;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/GensConfigTool/Handlers/NvidiaHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ConfigurationTool.Handlers
4 | {
5 | class NvidiaHandler
6 | {
7 | [System.Runtime.InteropServices.DllImport("nvapi64.dll", EntryPoint = "fake")]
8 | static extern int LoadNvApi64();
9 |
10 | [System.Runtime.InteropServices.DllImport("nvapi.dll", EntryPoint = "fake")]
11 | static extern int LoadNvApi32();
12 |
13 | public static void InitializeDedicatedGraphics()
14 | {
15 | try
16 | {
17 | if (Environment.Is64BitProcess)
18 | LoadNvApi64();
19 | else
20 | LoadNvApi32();
21 | }
22 | catch { } // will always fail since 'fake' entry point doesn't exists
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/GensConfigTool/Handlers/RegistryHandler.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Configurations;
2 | using ConfigurationTool.Model.Settings;
3 | using Microsoft.Win32;
4 |
5 | namespace ConfigurationTool.Handlers
6 | {
7 | class RegistryHandler
8 | {
9 | public static void FixRegistry(int fixtype)
10 | {
11 | RegistryKey registryKey = null;
12 | bool fixAll = false;
13 |
14 | switch (fixtype)
15 | {
16 | case -1:
17 | registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).CreateSubKey(RegistryConfiguration.ConfigLocation);
18 | fixAll = true;
19 | goto case 1;
20 | case 1:
21 | registryKey = registryKey ?? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(RegistryConfiguration.ConfigLocation, true);
22 | registryKey.SetValue(RegistryConfiguration.REGDATA_LOCALE, ((int)Language.English).ToString());
23 | if (fixAll) goto case 2;
24 | break;
25 | case 2:
26 | registryKey = registryKey ?? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(RegistryConfiguration.ConfigLocation, true);
27 | registryKey.SetValue(RegistryConfiguration.REGDATA_SAVELOCATION, "My Games\\Sonic Generations\\Saved Games");
28 | break;
29 | }
30 | registryKey?.Close();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/GensConfigTool/Helpers/EnumOrder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace ConfigurationTool.Helpers
5 | {
6 | public class EnumOrder where TEnum : struct
7 | {
8 | public static readonly TEnum[] Values;
9 |
10 | static EnumOrder()
11 | {
12 | var fields = typeof(TEnum).GetFields(BindingFlags.Static | BindingFlags.Public);
13 | Values = Array.ConvertAll(fields, x => (TEnum)x.GetValue(null));
14 | }
15 |
16 | public static int IndexOf(TEnum value)
17 | {
18 | return Array.IndexOf(Values, value);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/GensConfigTool/Helpers/Extensions.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Settings;
2 | using SharpDX.DirectInput;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Windows;
6 |
7 | namespace ConfigurationTool.Helpers
8 | {
9 | public static class Extensions
10 | {
11 | // Key extensions
12 | public static string GetStringValue(this Key value)
13 | {
14 | switch ((int)value)
15 | {
16 | case -1:
17 | return Application.Current.TryFindResource("Null").ToString();
18 | case 0:
19 | return Application.Current.TryFindResource("Undefined").ToString();
20 | default:
21 | return value.ToString();
22 | }
23 | }
24 |
25 | public static void InsertElementDescending(this List source,
26 | T toAdd) where T : IComparable
27 | {
28 | int index = source.FindLastIndex(elem => elem.CompareTo(toAdd) > 0);
29 | source.Insert(index + 1, toAdd);
30 | }
31 |
32 | public static void InsertElementAscending(this List source,
33 | T toAdd) where T : IComparable
34 | {
35 | int index = source.FindIndex(elem => elem.CompareTo(toAdd) < 0);
36 | source.Insert(index + 1, toAdd);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/GensConfigTool/Helpers/GraphicsDeviceTypes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace ConfigurationTool.Helpers
5 | {
6 | public class GraphicsDeviceTypes
7 | {
8 | [DllImport("user32.dll", CharSet = CharSet.Unicode)]
9 | public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAYDEV lpDisplayDevice, uint dwFlags);
10 |
11 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
12 | public struct DISPLAYDEV
13 | {
14 | [MarshalAs(UnmanagedType.U4)]
15 | public int cb;
16 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
17 | public string DeviceName;
18 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
19 | public string DeviceString;
20 | [MarshalAs(UnmanagedType.U4)]
21 | public DisplayDeviceStateFlags StateFlags;
22 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
23 | public string DeviceID;
24 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
25 | public string DeviceKey;
26 | }
27 |
28 | [StructLayout(LayoutKind.Sequential)]
29 | public struct DeviceMode
30 | {
31 | private const int CCHDEVICENAME = 0x20;
32 | private const int CCHFORMNAME = 0x20;
33 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
34 | public string dmDeviceName;
35 | public short dmSpecVersion;
36 | public short dmDriverVersion;
37 | public short dmSize;
38 | public short dmDriverExtra;
39 | public int dmFields;
40 | public int dmPositionX;
41 | public int dmPositionY;
42 | public int dmDisplayOrientation;
43 | public int dmDisplayFixedOutput;
44 | public short dmColor;
45 | public short dmDuplex;
46 | public short dmYResolution;
47 | public short dmTTOption;
48 | public short dmCollate;
49 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
50 | public string dmFormName;
51 | public short dmLogPixels;
52 | public int dmBitsPerPel;
53 | public int dmPelsWidth;
54 | public int dmPelsHeight;
55 | public int dmDisplayFlags;
56 | public int dmDisplayFrequency;
57 | public int dmICMMethod;
58 | public int dmICMIntent;
59 | public int dmMediaType;
60 | public int dmDitherType;
61 | public int dmReserved1;
62 | public int dmReserved2;
63 | public int dmPanningWidth;
64 | public int dmPanningHeight;
65 | }
66 |
67 | [Flags()]
68 | public enum DisplayDeviceStateFlags : int
69 | {
70 | /// The device is part of the desktop.
71 | AttachedToDesktop = 0x1,
72 | MultiDriver = 0x2,
73 | /// The device is part of the desktop.
74 | PrimaryDevice = 0x4,
75 | /// Represents a pseudo device used to mirror application drawing for remoting or other purposes.
76 | MirroringDriver = 0x8,
77 | /// The device is VGA compatible.
78 | VGACompatible = 0x10,
79 | /// The device is removable; it cannot be the primary display.
80 | Removable = 0x20,
81 | /// The device has more display modes than its output devices support.
82 | ModesPruned = 0x8000000,
83 | Remote = 0x4000000,
84 | Disconnect = 0x2000000
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/GensConfigTool/Helpers/ThemeHelper.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using System;
3 | using System.Globalization;
4 | using System.Management;
5 | using System.Security.Principal;
6 |
7 | namespace ConfigurationTool.Helpers
8 | {
9 | class ThemeHelper
10 | {
11 | private const string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
12 | private const string RegistryValueName = "AppsUseLightTheme";
13 | private readonly string Query = String.Format(
14 | CultureInfo.InvariantCulture,
15 | @"SELECT * FROM RegistryValueChangeEvent WHERE Hive = 'HKEY_USERS' AND KeyPath = '{0}\\{1}' AND ValueName = '{2}'",
16 | WindowsIdentity.GetCurrent().User.Value,
17 | RegistryKeyPath.Replace(@"\", @"\\"),
18 | RegistryValueName);
19 |
20 | public enum WindowsTheme
21 | { Light, Dark }
22 |
23 | private readonly Action ThemeListener;
24 |
25 | public ThemeHelper(Action themeListener)
26 | {
27 | this.ThemeListener = themeListener;
28 | }
29 |
30 | public void WatchTheme()
31 | {
32 | try
33 | {
34 | var watcher = new ManagementEventWatcher(Query);
35 |
36 | watcher.EventArrived += (sender, args) =>
37 | {
38 | ThemeListener(GetWindowsTheme());
39 | };
40 |
41 | watcher.Start();
42 | }
43 | catch {}
44 |
45 | ThemeListener(GetWindowsTheme());
46 | }
47 |
48 | private static WindowsTheme GetWindowsTheme()
49 | {
50 | using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath))
51 | {
52 | object registryValueObject = key?.GetValue(RegistryValueName);
53 | if (registryValueObject == null)
54 | {
55 | return WindowsTheme.Light;
56 | }
57 |
58 | int registryValue = (int)registryValueObject;
59 |
60 | return registryValue > 0 ? WindowsTheme.Light : WindowsTheme.Dark;
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/GensConfigTool/Helpers/UacHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Drawing;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 | using System.Windows.Media.Imaging;
7 |
8 | namespace ConfigurationTool.Helpers
9 | {
10 | class UacHelper
11 | {
12 | [DllImport("Shell32.dll", SetLastError = false)]
13 | public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
14 |
15 | [DllImport("user32.dll", SetLastError = true)]
16 | static extern bool DestroyIcon(IntPtr hIcon);
17 |
18 | [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
19 | public struct SHSTOCKICONINFO
20 | {
21 | public UInt32 cbSize;
22 | public IntPtr hIcon;
23 | public Int32 iSysIconIndex;
24 | public Int32 iIcon;
25 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
26 | public string szPath;
27 | }
28 |
29 | [Flags]
30 | public enum SHGSI : uint
31 | {
32 | SHGSI_ICONLOCATION = 0,
33 | SHGSI_ICON = 0x000000100,
34 | SHGSI_SYSICONINDEX = 0x000004000,
35 | SHGSI_LINKOVERLAY = 0x000008000,
36 | SHGSI_SELECTED = 0x000010000,
37 | SHGSI_LARGEICON = 0x000000000,
38 | SHGSI_SMALLICON = 0x000000001,
39 | SHGSI_SHELLICONSIZE = 0x000000004
40 | }
41 |
42 | public enum SHSTOCKICONID : uint
43 | {
44 | SIID_DOCNOASSOC = 0,
45 | SIID_DOCASSOC = 1,
46 | SIID_APPLICATION = 2,
47 | SIID_FOLDER = 3,
48 | SIID_FOLDEROPEN = 4,
49 | SIID_DRIVE525 = 5,
50 | SIID_DRIVE35 = 6,
51 | SIID_DRIVEREMOVE = 7,
52 | SIID_DRIVEFIXED = 8,
53 | SIID_DRIVENET = 9,
54 | SIID_DRIVENETDISABLED = 10,
55 | SIID_DRIVECD = 11,
56 | SIID_DRIVERAM = 12,
57 | SIID_WORLD = 13,
58 | SIID_SERVER = 15,
59 | SIID_PRINTER = 16,
60 | SIID_MYNETWORK = 17,
61 | SIID_FIND = 22,
62 | SIID_HELP = 23,
63 | SIID_SHARE = 28,
64 | SIID_LINK = 29,
65 | SIID_SLOWFILE = 30,
66 | SIID_RECYCLER = 31,
67 | SIID_RECYCLERFULL = 32,
68 | SIID_MEDIACDAUDIO = 40,
69 | SIID_LOCK = 47,
70 | SIID_AUTOLIST = 49,
71 | SIID_PRINTERNET = 50,
72 | SIID_SERVERSHARE = 51,
73 | SIID_PRINTERFAX = 52,
74 | SIID_PRINTERFAXNET = 53,
75 | SIID_PRINTERFILE = 54,
76 | SIID_STACK = 55,
77 | SIID_MEDIASVCD = 56,
78 | SIID_STUFFEDFOLDER = 57,
79 | SIID_DRIVEUNKNOWN = 58,
80 | SIID_DRIVEDVD = 59,
81 | SIID_MEDIADVD = 60,
82 | SIID_MEDIADVDRAM = 61,
83 | SIID_MEDIADVDRW = 62,
84 | SIID_MEDIADVDR = 63,
85 | SIID_MEDIADVDROM = 64,
86 | SIID_MEDIACDAUDIOPLUS = 65,
87 | SIID_MEDIACDRW = 66,
88 | SIID_MEDIACDR = 67,
89 | SIID_MEDIACDBURN = 68,
90 | SIID_MEDIABLANKCD = 69,
91 | SIID_MEDIACDROM = 70,
92 | SIID_AUDIOFILES = 71,
93 | SIID_IMAGEFILES = 72,
94 | SIID_VIDEOFILES = 73,
95 | SIID_MIXEDFILES = 74,
96 | SIID_FOLDERBACK = 75,
97 | SIID_FOLDERFRONT = 76,
98 | SIID_SHIELD = 77,
99 | SIID_WARNING = 78,
100 | SIID_INFO = 79,
101 | SIID_ERROR = 80,
102 | SIID_KEY = 81,
103 | SIID_SOFTWARE = 82,
104 | SIID_RENAME = 83,
105 | SIID_DELETE = 84,
106 | SIID_MEDIAAUDIODVD = 85,
107 | SIID_MEDIAMOVIEDVD = 86,
108 | SIID_MEDIAENHANCEDCD = 87,
109 | SIID_MEDIAENHANCEDDVD = 88,
110 | SIID_MEDIAHDDVD = 89,
111 | SIID_MEDIABLURAY = 90,
112 | SIID_MEDIAVCD = 91,
113 | SIID_MEDIADVDPLUSR = 92,
114 | SIID_MEDIADVDPLUSRW = 93,
115 | SIID_DESKTOPPC = 94,
116 | SIID_MOBILEPC = 95,
117 | SIID_USERS = 96,
118 | SIID_MEDIASMARTMEDIA = 97,
119 | SIID_MEDIACOMPACTFLASH = 98,
120 | SIID_DEVICECELLPHONE = 99,
121 | SIID_DEVICECAMERA = 100,
122 | SIID_DEVICEVIDEOCAMERA = 101,
123 | SIID_DEVICEAUDIOPLAYER = 102,
124 | SIID_NETWORKCONNECT = 103,
125 | SIID_INTERNET = 104,
126 | SIID_ZIPFILE = 105,
127 | SIID_SETTINGS = 106,
128 | SIID_DRIVEHDDVD = 132,
129 | SIID_DRIVEBD = 133,
130 | SIID_MEDIAHDDVDROM = 134,
131 | SIID_MEDIAHDDVDR = 135,
132 | SIID_MEDIAHDDVDRAM = 136,
133 | SIID_MEDIABDROM = 137,
134 | SIID_MEDIABDR = 138,
135 | SIID_MEDIABDRE = 139,
136 | SIID_CLUSTEREDDRIVE = 140,
137 | SIID_MAX_ICONS = 175
138 | }
139 |
140 | public static BitmapSource GetUacIcon()
141 | {
142 | BitmapSource shieldSource = null;
143 |
144 | if (Environment.OSVersion.Version.Major >= 6)
145 | {
146 | SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
147 | sii.cbSize = (UInt32)Marshal.SizeOf(typeof(SHSTOCKICONINFO));
148 |
149 | Marshal.ThrowExceptionForHR(SHGetStockIconInfo(SHSTOCKICONID.SIID_SHIELD,
150 | SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON,
151 | ref sii));
152 |
153 | shieldSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
154 | sii.hIcon,
155 | Int32Rect.Empty,
156 | BitmapSizeOptions.FromEmptyOptions());
157 |
158 | DestroyIcon(sii.hIcon);
159 | }
160 | else
161 | {
162 | shieldSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
163 | SystemIcons.Shield.Handle,
164 | Int32Rect.Empty,
165 | BitmapSizeOptions.FromEmptyOptions());
166 | }
167 |
168 | return shieldSource;
169 | }
170 |
171 | public static void RestartAsAdmin(string args = null)
172 | {
173 | var psi = new ProcessStartInfo
174 | {
175 | UseShellExecute = true,
176 | FileName = Process.GetCurrentProcess().MainModule.FileName,
177 | Verb = "runas"
178 | };
179 | if (args != null) psi.Arguments = args;
180 |
181 | var process = new Process
182 | {
183 | StartInfo = psi
184 | };
185 | try
186 | {
187 | process.Start();
188 | Application.Current.Shutdown();
189 | }
190 | catch
191 | {
192 |
193 | }
194 | }
195 |
196 | public static void RestartAsAdminAndWait(string args = null)
197 | {
198 | var psi = new ProcessStartInfo
199 | {
200 | UseShellExecute = true,
201 | FileName = Process.GetCurrentProcess().MainModule.FileName,
202 | Verb = "runas"
203 | };
204 | if (args != null) psi.Arguments = args;
205 |
206 | var process = new Process
207 | {
208 | StartInfo = psi
209 | };
210 | try
211 | {
212 | process.Start();
213 | process.WaitForExit();
214 | }
215 | catch
216 | {
217 |
218 | }
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/GensConfigTool/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
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 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
--------------------------------------------------------------------------------
/GensConfigTool/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Handlers;
2 | using ConfigurationTool.Helpers;
3 | using ConfigurationTool.Model;
4 | using ConfigurationTool.Model.Devices;
5 | using ConfigurationTool.Model.Settings;
6 | using ConfigurationTool.Settings.Model;
7 | using SharpDX.DirectInput;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 | using System.Windows;
13 | using System.Windows.Controls;
14 | using System.Windows.Media;
15 | using System.Windows.Media.Imaging;
16 | using static ConfigurationTool.Helpers.ThemeHelper;
17 |
18 | namespace ConfigurationTool
19 | {
20 | ///
21 | /// Interaction logic for MainWindow.xaml
22 | ///
23 | public partial class MainWindow : Window
24 | {
25 | private readonly ConfigurationHandler Files;
26 |
27 | private readonly Configuration Configuration;
28 | private bool IgnoreSelectionTriggers = true;
29 |
30 | public MainWindow()
31 | {
32 | InitializeComponent();
33 |
34 | this.Files = new ConfigurationHandler();
35 | this.Configuration = Files.LoadConfiguration();
36 |
37 | // Get Graphics Adapters
38 | List adapters = DevicesHandler.GetGraphicsAdapters();
39 | this.GPUSelector.ItemsSource = adapters;
40 | this.ResSelector.ItemsSource = adapters[0].Resolutions;
41 |
42 | // Get Audio Devices
43 | this.AudioSelector.ItemsSource = DevicesHandler.GetAudioDevices();
44 |
45 | OnOff[] onOff = EnumOrder.Values;
46 | HighLow[] highLow = EnumOrder.Values;
47 |
48 | this.AntiAliasingSelector.ItemsSource = onOff;
49 | this.VSyncSelector.ItemsSource = onOff;
50 | this.AnalyticsSelector.ItemsSource = onOff;
51 |
52 | this.DispModeSelector.ItemsSource = Enum.GetValues(typeof(DisplayMode));
53 |
54 | this.ShadowSelector.ItemsSource = highLow;
55 | this.ReflectionSelector.ItemsSource = highLow;
56 |
57 | this.LanguageSelector.ItemsSource = EnumOrder.Values;
58 |
59 |
60 | this.InputSelector.Items.Add(this.Configuration.Keyboard);
61 | bool observed = this.Configuration.XinputController.IsConnected;
62 | if (observed) this.InputSelector.Items.Add(this.Configuration.XinputController);
63 |
64 | this.InputSelector.SelectedIndex = 0;
65 |
66 | UpdateConfigView();
67 | UpdateInputView();
68 |
69 | ThemeHelper winTheme = new ThemeHelper(theme =>
70 | {
71 | Application.Current.Resources.MergedDictionaries[0].Source = new Uri("/Resources/Themes/" +
72 | (theme == WindowsTheme.Light ? "Light.xaml" : "Dark.xaml"),
73 | UriKind.Relative);
74 | });
75 | winTheme.WatchTheme();
76 |
77 | PollXinput(observed, this.Configuration.XinputController);
78 | }
79 |
80 | private void UpdateConfigView()
81 | {
82 | int idx = this.GPUSelector.Items.IndexOf(null);
83 | if (idx >= 0)
84 | {
85 | this.GPUSelector.SelectedIndex = idx;
86 |
87 | this.ResSelector.ItemsSource = ((GraphicsAdapter)this.GPUSelector.SelectedItem).Resolutions;
88 | idx = this.ResSelector.Items.IndexOf(this.Configuration.Resolution); // We do this to not lose the Refresh Rate
89 | this.ResSelector.SelectedIndex = idx >= 0 ? idx : 0;
90 |
91 | this.RefreshRateSelector.ItemsSource = ((Resolution)this.ResSelector.SelectedItem).RefreshRates;
92 | if (idx >= 0)
93 | {
94 | this.RefreshRateSelector.SelectedItem = this.Configuration.RefreshRate;
95 | }
96 | else
97 | {
98 | this.RefreshRateSelector.SelectedIndex = 0;
99 | }
100 | }
101 | else
102 | {
103 | this.RefreshRateSelector.ItemsSource = ((Resolution)this.ResSelector.Items[0]).RefreshRates;
104 |
105 | this.Configuration.GraphicsAdapter = (GraphicsAdapter)this.GPUSelector.Items[0];
106 | this.Configuration.Resolution = this.Configuration.GraphicsAdapter.Resolutions[0];
107 | this.Configuration.RefreshRate = this.Configuration.GraphicsAdapter.Resolutions[0].RefreshRates[0];
108 |
109 | this.GPUSelector.SelectedIndex = 0;
110 | this.ResSelector.SelectedIndex = 0;
111 | this.RefreshRateSelector.SelectedIndex = 0;
112 | }
113 |
114 | this.AntiAliasingSelector.SelectedItem = this.Configuration.Antialiasing;
115 | this.VSyncSelector.SelectedItem = this.Configuration.VSync;
116 | this.DispModeSelector.SelectedItem = this.Configuration.DisplayMode;
117 | this.ShadowSelector.SelectedItem = this.Configuration.ShadowQuality;
118 | this.ReflectionSelector.SelectedItem = this.Configuration.ReflectionQuality;
119 |
120 | this.AudioSelector.SelectedItem = this.Configuration.AudioDevice;
121 |
122 | this.AnalyticsSelector.SelectedItem = this.Configuration.Analytics;
123 | this.LanguageSelector.SelectedItem = this.Configuration.Language;
124 |
125 | if (Configuration.ProcessIsElevated)
126 | {
127 | this.LanguageLabel.Opacity = 1;
128 | this.AdminButton.Visibility = Configuration.ProcessIsElevated ? Visibility.Collapsed : Visibility.Visible;
129 | this.AdminButtonCol.Width = GridLength.Auto;
130 | }
131 | else
132 | {
133 | this.LanguageSelector.Foreground = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0));
134 | this.LanguageSelector.IsEnabled = false;
135 | this.AdminButtonImage.Source = UacHelper.GetUacIcon();
136 | }
137 |
138 | IgnoreSelectionTriggers = false;
139 | }
140 |
141 | private void UpdateInputView()
142 | {
143 | InputDevice device = (InputDevice)this.InputSelector.SelectedItem;
144 |
145 | this.Button_A.Content = ((Key)device.Buttons.A).GetStringValue();
146 | this.Button_B.Content = ((Key)device.Buttons.B).GetStringValue();
147 | this.Button_X.Content = ((Key)device.Buttons.X).GetStringValue();
148 | this.Button_Y.Content = ((Key)device.Buttons.Y).GetStringValue();
149 |
150 | this.Button_RB.Content = ((Key)device.Buttons.RB).GetStringValue();
151 | this.Button_LB.Content = ((Key)device.Buttons.LB).GetStringValue();
152 |
153 | this.Button_RT.Content = ((Key)device.Buttons.RT).GetStringValue();
154 | this.Button_LT.Content = ((Key)device.Buttons.LT).GetStringValue();
155 |
156 | this.Button_Up.Content = ((Key)device.Buttons.Up).GetStringValue();
157 | this.Button_Down.Content = ((Key)device.Buttons.Down).GetStringValue();
158 | this.Button_Left.Content = ((Key)device.Buttons.Left).GetStringValue();
159 | this.Button_Right.Content = ((Key)device.Buttons.Right).GetStringValue();
160 |
161 | this.Button_Start.Content = ((Key)device.Buttons.Start).GetStringValue();
162 | this.Button_Back.Content = ((Key)device.Buttons.Back).GetStringValue();
163 | }
164 |
165 | private async Task PollXinput(bool initialConnectionState, InputDevice xinput)
166 | {
167 | bool isConnected = initialConnectionState;
168 |
169 | // Poll the Xbox controller port
170 | while (true)
171 | {
172 | await Task.Run(() =>
173 | {
174 | SpinWait.SpinUntil(() => isConnected != xinput.IsConnected);
175 | isConnected = !isConnected;
176 | });
177 |
178 | if (isConnected)
179 | {
180 | this.InputSelector.Items.Add(xinput);
181 | }
182 | else
183 | {
184 | this.InputSelector.SelectedIndex = 0;
185 | this.InputSelector.Items.Remove(xinput);
186 | }
187 | }
188 | }
189 |
190 | private void UI_Save_Click(object sender, RoutedEventArgs e)
191 | {
192 | Files.SaveConfiguration(this.Configuration);
193 | }
194 |
195 | private void UI_SaveAndQuit_Click(object sender, RoutedEventArgs e)
196 | {
197 | Files.SaveConfiguration(this.Configuration);
198 | Application.Current.Shutdown();
199 | }
200 |
201 | private void UI_Quit_Click(object sender, RoutedEventArgs e) => Application.Current.Shutdown();
202 | private void AdminButton_Click(object sender, RoutedEventArgs e) => UacHelper.RestartAsAdmin();
203 |
204 | private void GPUSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
205 | {
206 | this.Tooltip.Text = Application.Current.TryFindResource("GraphicsAdapter_Desc").ToString();
207 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Misc.png", UriKind.Relative));
208 | }
209 |
210 | private void ResSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
211 | {
212 | this.Tooltip.Text = Application.Current.TryFindResource("Resolution_Desc").ToString();
213 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Res.png", UriKind.Relative));
214 | }
215 |
216 | private void AntiAliasingSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
217 | {
218 | this.Tooltip.Text = Application.Current.TryFindResource("Antialiasing_Desc").ToString();
219 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/FXAA.png", UriKind.Relative));
220 | }
221 |
222 | private void DispModeSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
223 | {
224 | this.Tooltip.Text = Application.Current.TryFindResource("DisplayMode_Desc").ToString();
225 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Display.png", UriKind.Relative));
226 | }
227 |
228 | private void ShadowSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
229 | {
230 | this.Tooltip.Text = Application.Current.TryFindResource("ShadowQuality_Desc").ToString();
231 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Shadows.png", UriKind.Relative));
232 | }
233 |
234 | private void ReflectionSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
235 | {
236 | this.Tooltip.Text = Application.Current.TryFindResource("ReflectionQuality_Desc").ToString();
237 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Misc.png", UriKind.Relative));
238 | }
239 |
240 | private void VSyncSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
241 | {
242 | this.Tooltip.Text = Application.Current.TryFindResource("VSync_Desc").ToString();
243 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/VSync.png", UriKind.Relative));
244 | }
245 |
246 | private void AudioSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
247 | {
248 | this.Tooltip.Text = Application.Current.TryFindResource("AudioDevice_Desc").ToString();
249 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Misc.png", UriKind.Relative));
250 | }
251 |
252 | private void LanguageSelector_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
253 | {
254 | this.Tooltip.Text = Application.Current.TryFindResource("Language_Desc").ToString();
255 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Misc.png", UriKind.Relative));
256 | }
257 |
258 | private void AnalyticsZone_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
259 | {
260 | this.Tooltip.Text = Application.Current.TryFindResource("AnalyticsText").ToString();
261 | this.TooltipImage.Source = new BitmapImage(new Uri("Resources/Images/Misc.png", UriKind.Relative));
262 | }
263 |
264 | private void AnalyticsButton_Click(object sender, RoutedEventArgs e)
265 | {
266 | MessageBox.Show(
267 | Application.Current.TryFindResource("AnalyticsText").ToString(),
268 | Application.Current.TryFindResource("AnalyticsInfo").ToString());
269 | }
270 |
271 | private void GPUSelector_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
272 | {
273 | if (IgnoreSelectionTriggers) return;
274 |
275 | GraphicsAdapter adapter = (GraphicsAdapter)e.AddedItems[0];
276 | this.Configuration.GraphicsAdapter = adapter;
277 | IgnoreSelectionTriggers = true;
278 |
279 | this.ResSelector.ItemsSource = adapter.Resolutions;
280 |
281 | IgnoreSelectionTriggers = false;
282 | this.ResSelector.SelectedItem = adapter.Resolutions[0];
283 | }
284 |
285 | private void ResSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
286 | {
287 | if (IgnoreSelectionTriggers) return;
288 |
289 | this.Configuration.Resolution = (Resolution)e.AddedItems[0];
290 |
291 | IgnoreSelectionTriggers = true;
292 | this.RefreshRateSelector.ItemsSource = this.Configuration.Resolution.RefreshRates;
293 | IgnoreSelectionTriggers = false;
294 | this.RefreshRateSelector.SelectedIndex = 0;
295 | }
296 |
297 | private void RefreshRateSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
298 | {
299 | if (IgnoreSelectionTriggers) return;
300 |
301 | this.Configuration.RefreshRate = (RefreshRate)e.AddedItems[0];
302 | }
303 |
304 | private void AntiAliasingSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
305 | {
306 | if (IgnoreSelectionTriggers) return;
307 |
308 | this.Configuration.Antialiasing = (OnOff)e.AddedItems[0];
309 | }
310 |
311 | private void DispModeSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
312 | {
313 | if (IgnoreSelectionTriggers) return;
314 |
315 | this.Configuration.DisplayMode = (DisplayMode)e.AddedItems[0];
316 | }
317 |
318 | private void ShadowSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
319 | {
320 | if (IgnoreSelectionTriggers) return;
321 |
322 | this.Configuration.ShadowQuality = (HighLow)e.AddedItems[0];
323 | }
324 |
325 | private void ReflectionSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
326 | {
327 | if (IgnoreSelectionTriggers) return;
328 |
329 | this.Configuration.ReflectionQuality = (HighLow)e.AddedItems[0];
330 | }
331 |
332 | private void VSyncSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
333 | {
334 | if (IgnoreSelectionTriggers) return;
335 |
336 | this.Configuration.VSync = (OnOff)e.AddedItems[0];
337 | }
338 |
339 | private void AudioSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
340 | {
341 | if (IgnoreSelectionTriggers) return;
342 |
343 | this.Configuration.AudioDevice = (AudioDevice)e.AddedItems[0];
344 | }
345 |
346 | private void LanguageSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
347 | {
348 | if (IgnoreSelectionTriggers) return;
349 |
350 | this.Configuration.Language = (Language)e.AddedItems[0];
351 | }
352 |
353 | private void InputSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
354 | {
355 | if (IgnoreSelectionTriggers) return;
356 |
357 | Model.Devices.DeviceType type = ((InputDevice)e.AddedItems[0]).DeviceType;
358 | this.InputButtons.IsEnabled = type != Model.Devices.DeviceType.XINPUT;
359 | UpdateInputView();
360 | }
361 | private void AnalyticsSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
362 | {
363 | if (IgnoreSelectionTriggers) return;
364 |
365 | this.Configuration.Analytics = (OnOff)e.AddedItems[0];
366 | }
367 |
368 | private void InputButton_Click(object sender, RoutedEventArgs e)
369 | {
370 | Button src = (Button)e.Source;
371 | this.ParentGrid.IsEnabled = false;
372 | string orig = src.Content.ToString();
373 |
374 | src.Content = Application.Current.TryFindResource("InputTooltip");
375 |
376 | // Can be changed to use currently selected device when implementing Dinput
377 | this.Configuration.Keyboard.SetKey(src.Tag.ToString(), this.Configuration.Keyboard, key =>
378 | {
379 | UpdateInputView();
380 | this.ParentGrid.IsEnabled = true;
381 | });
382 | }
383 |
384 | private void ButtonDefault_Click(object sender, RoutedEventArgs e)
385 | {
386 | Button src = (Button)e.Source;
387 | this.Configuration.Keyboard.Buttons = new Model.Input.ButtonConfiguration();
388 | UpdateInputView();
389 | }
390 | }
391 | }
392 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configuration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Devices;
2 | using ConfigurationTool.Model.Settings;
3 | using ConfigurationTool.Settings.Model;
4 | using System;
5 | using System.Security.Principal;
6 |
7 | namespace ConfigurationTool.Model
8 | {
9 | class Configuration
10 | {
11 | public Resolution Resolution;
12 | public RefreshRate RefreshRate;
13 |
14 | public GraphicsAdapter GraphicsAdapter;
15 | public DepthFormat DepthFormat = DepthFormat.INTZ;
16 | public AudioDevice AudioDevice = new AudioDevice();
17 |
18 | public Keyboard Keyboard = new Keyboard();
19 | public XinputController XinputController = new XinputController(0);
20 |
21 | public OnOff Antialiasing = OnOff.On;
22 | public OnOff VSync = OnOff.On;
23 | public OnOff Analytics = OnOff.On;
24 |
25 | public HighLow ShadowQuality = HighLow.High;
26 | public HighLow ReflectionQuality = HighLow.High;
27 |
28 | public DisplayMode DisplayMode = DisplayMode.Letterbox;
29 |
30 | public bool ProcessIsElevated =>
31 | WindowsIdentity.GetCurrent().Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid);
32 |
33 | public Language Language = Language.English;
34 |
35 | // Relative to user Documents folder
36 | public string InputSaveLocation = "My Games\\Sonic Generations\\Saved Games";
37 | public string AbsoluteInputSaveLocation =>
38 | $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\{InputSaveLocation}";
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/AnalyticsConfiguration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Settings.Model;
2 | using System.IO;
3 |
4 | namespace ConfigurationTool.Model.Configurations
5 | {
6 | class AnalyticsConfiguration : IConfiguration
7 | {
8 | public const string ConfigLocation = "StatsConfig.cfg";
9 |
10 | public Configuration LoadConfiguration(Configuration config)
11 | {
12 | if (config == null) config = new Configuration();
13 |
14 | if (!File.Exists(ConfigLocation)) return config;
15 | try
16 | {
17 | using (StreamReader sr = new StreamReader(new BufferedStream(File.Open(ConfigLocation, FileMode.Open))))
18 | {
19 | int value = int.Parse(sr.ReadLine());
20 | config.Analytics = value > 0 ? OnOff.On : OnOff.Off;
21 | }
22 | return config;
23 | }
24 | catch
25 | {
26 | return new Configuration();
27 | }
28 | }
29 |
30 | public void SaveConfiguration(Configuration config)
31 | {
32 | using (StreamWriter writer = new StreamWriter(ConfigLocation))
33 | {
34 | writer.WriteLine((int)config.Analytics);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/AudioConfiguration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Devices;
2 | using System.IO;
3 |
4 | namespace ConfigurationTool.Model.Configurations
5 | {
6 | class AudioConfiguration : IConfiguration
7 | {
8 | public const string ConfigLocation = "AudioConfig.cfg";
9 |
10 | public Configuration LoadConfiguration(Configuration config)
11 | {
12 | if (config == null) config = new Configuration();
13 |
14 | if (!File.Exists(ConfigLocation)) return config;
15 | try
16 | {
17 | using (StreamReader sr = new StreamReader(new BufferedStream(File.Open(ConfigLocation, FileMode.Open))))
18 | {
19 | string name = sr.ReadLine();
20 | string guid = sr.ReadLine();
21 | config.AudioDevice = new AudioDevice()
22 | {
23 | Name = name,
24 | GUID = guid
25 | };
26 | }
27 | return config;
28 | }
29 | catch
30 | {
31 | return new Configuration();
32 | }
33 | }
34 |
35 | public void SaveConfiguration(Configuration config)
36 | {
37 | using (StreamWriter writer = new StreamWriter(ConfigLocation))
38 | {
39 | writer.WriteLine(config.AudioDevice.Name);
40 | writer.WriteLine(config.AudioDevice.GUID);
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/GraphicsConfiguration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Devices;
2 | using ConfigurationTool.Model.Settings;
3 | using ConfigurationTool.Settings.Model;
4 | using System;
5 | using System.IO;
6 | using System.Windows;
7 |
8 | namespace ConfigurationTool.Model.Configurations
9 | {
10 | class GraphicsConfiguration : IConfiguration
11 | {
12 | private string FileWarning => Application.Current.TryFindResource("GraphicsFile_Warning").ToString();
13 | public const string ConfigLocation = "GraphicsConfig.cfg";
14 |
15 | public Configuration LoadConfiguration(Configuration config)
16 | {
17 | if (config == null) config = new Configuration();
18 |
19 | if (!File.Exists(ConfigLocation)) return config;
20 | try
21 | {
22 | using (StreamReader sr = new StreamReader(new BufferedStream(File.Open(ConfigLocation, FileMode.Open))))
23 | {
24 | sr.ReadLine(); // Skip warning line
25 | string adapterDesc = sr.ReadLine();
26 | string adapterName = sr.ReadLine();
27 | if (String.IsNullOrEmpty(adapterName) || String.IsNullOrEmpty(adapterName))
28 | {
29 | return config;
30 | }
31 |
32 | string[] resString = sr.ReadLine().Split('.');
33 | config.Resolution = new Resolution()
34 | {
35 | Width = int.Parse(resString[0]),
36 | Height = int.Parse(resString[1]),
37 | };
38 | config.RefreshRate = new RefreshRate(int.Parse(resString[2]));
39 |
40 | config.Antialiasing = int.Parse(sr.ReadLine()) > 0 ? OnOff.On : OnOff.Off;
41 | config.VSync = int.Parse(sr.ReadLine()) > 0 ? OnOff.On : OnOff.Off;
42 |
43 | config.ShadowQuality = int.Parse(sr.ReadLine()) > 0 ? HighLow.High : HighLow.Low;
44 | config.ReflectionQuality = int.Parse(sr.ReadLine()) > 0 ? HighLow.High : HighLow.Low;
45 |
46 | config.DisplayMode = int.Parse(sr.ReadLine()) > 0 ? DisplayMode.Letterbox : DisplayMode.Widescreen;
47 |
48 | config.GraphicsAdapter = new GraphicsAdapter()
49 | {
50 | GUID = sr.ReadLine(),
51 | Name = adapterName,
52 | Description = adapterDesc,
53 | MonitorID = sr.ReadLine()
54 | };
55 |
56 | config.DepthFormat = DepthFormat.FromFourCC(int.Parse(sr.ReadLine()));
57 | return config;
58 | }
59 | }
60 | catch
61 | {
62 | return new Configuration();
63 | }
64 | }
65 |
66 | public void SaveConfiguration(Configuration config)
67 | {
68 |
69 | using (StreamWriter writer = new StreamWriter(ConfigLocation))
70 | {
71 | writer.WriteLine(FileWarning);
72 | writer.WriteLine(config.GraphicsAdapter.Description);
73 | writer.WriteLine(config.GraphicsAdapter.Name);
74 | Resolution res = config.Resolution;
75 | writer.WriteLine($"{res.Width}.{res.Height}.{config.RefreshRate.Value}");
76 | writer.WriteLine((int)config.Antialiasing);
77 | writer.WriteLine((int)config.VSync);
78 | writer.WriteLine((int)config.ShadowQuality);
79 | writer.WriteLine((int)config.ReflectionQuality);
80 | writer.WriteLine((int)config.DisplayMode);
81 | writer.WriteLine(config.GraphicsAdapter.GUID);
82 | writer.WriteLine(config.GraphicsAdapter.MonitorID);
83 | writer.WriteLine(config.DepthFormat.GetFourCC());
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/IConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Model.Configurations
2 | {
3 | // Should be able to save and load configurations from a set place
4 | interface IConfiguration
5 | {
6 | Configuration LoadConfiguration(Configuration config);
7 | void SaveConfiguration(Configuration config);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/InputConfiguration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Devices;
2 | using System.IO;
3 |
4 | namespace ConfigurationTool.Model.Configurations
5 | {
6 | class InputConfiguration : IConfiguration
7 | {
8 | public const string ConfigLocation = "PlayerInput.cfg";
9 | public string DefaultConfig => "DefaultInput.cfg";
10 |
11 | public Configuration LoadConfiguration(Configuration config)
12 | {
13 | if (config == null) config = new Configuration();
14 | string path = $"{config.AbsoluteInputSaveLocation}\\{ConfigLocation}";
15 |
16 | if (!File.Exists(path)) return config;
17 | try
18 | {
19 | using (StreamReader sr = new StreamReader(new BufferedStream(File.Open(path, FileMode.Open))))
20 | {
21 | string name = sr.ReadLine();
22 | string serialized = sr.ReadLine();
23 | config.Keyboard = Keyboard.DeSerialize(serialized);
24 | }
25 | return config;
26 | }
27 | catch
28 | {
29 | return new Configuration();
30 | }
31 | }
32 |
33 | public void SaveConfiguration(Configuration config)
34 | {
35 | string path = $"{config.AbsoluteInputSaveLocation}\\{ConfigLocation}";
36 |
37 | Directory.CreateDirectory(config.AbsoluteInputSaveLocation);
38 | using (StreamWriter writer = new StreamWriter(File.Create(path)))
39 | {
40 | writer.Write(config.Keyboard.Serialize());
41 | }
42 | using (StreamWriter writer = new StreamWriter(File.Create(DefaultConfig)))
43 | {
44 | writer.Write(new Keyboard().Serialize());
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Configurations/RegistryConfiguration.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Handlers;
2 | using ConfigurationTool.Helpers;
3 | using ConfigurationTool.Model.Settings;
4 | using Microsoft.Win32;
5 | using System;
6 | using System.Globalization;
7 | using System.IO;
8 | using System.Windows;
9 |
10 | namespace ConfigurationTool.Model.Configurations
11 | {
12 | class RegistryConfiguration : IConfiguration
13 | {
14 | public const string ConfigLocation = "SOFTWARE\\Sega\\Sonic Generations";
15 |
16 | // The game boots fine without the install path and exe path
17 | public const string REGDATA_INSTALLPATH = "install_path";
18 | public const string REGDATA_EXEPATH = "exe_path";
19 | public const string REGDATA_LOCALE = "locale";
20 | public const string REGDATA_SAVELOCATION = "SaveLocation";
21 |
22 | public Configuration LoadConfiguration(Configuration config)
23 | {
24 | int fixRegistry = 0;
25 |
26 | // Load Registry
27 | RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(ConfigLocation);
28 | if (registryKey == null)
29 | {
30 | fixRegistry = -1;
31 | registryKey = null;
32 | }
33 |
34 | // Load Locale
35 | try
36 | {
37 | object locale = registryKey?.GetValue(REGDATA_LOCALE);
38 | if (locale != null)
39 | {
40 | // Try parsing the locale
41 | if (!int.TryParse(locale.ToString(), out int regLocale))
42 | {
43 | CultureInfo culture = new CultureInfo(locale.ToString(), false);
44 | regLocale = culture.LCID;
45 | }
46 |
47 | if (Array.IndexOf((int[])Enum.GetValues(typeof(Language)), regLocale) >= 0)
48 | {
49 | config.Language = (Language)regLocale;
50 | }
51 | else
52 | {
53 | // Locale in registry was invalid
54 | fixRegistry = fixRegistry >= 0 ? 1 : fixRegistry;
55 | }
56 | }
57 | else
58 | {
59 | fixRegistry = fixRegistry >= 0 ? 1 : fixRegistry;
60 | }
61 | }
62 | catch
63 | {
64 |
65 | }
66 |
67 | // Load Input Save Location
68 | object saveLocation = registryKey?.GetValue(REGDATA_SAVELOCATION);
69 | if (saveLocation == null)
70 | {
71 | fixRegistry = fixRegistry >= 0 ? 2 : fixRegistry;
72 | }
73 | else
74 | {
75 | config.InputSaveLocation = (string)saveLocation;
76 | }
77 |
78 | registryKey?.Close();
79 |
80 |
81 | try
82 | {
83 | Directory.CreateDirectory(config.AbsoluteInputSaveLocation);
84 | }
85 | catch
86 | {
87 | // Directory in registry was invalid
88 | fixRegistry = fixRegistry >= 0 ? 2 : fixRegistry;
89 | }
90 |
91 | TryFixRegInSameProcess(fixRegistry, config.ProcessIsElevated);
92 | return config;
93 | }
94 |
95 | public void SaveConfiguration(Configuration config)
96 | {
97 | if (!config.ProcessIsElevated) return;
98 |
99 | RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(ConfigLocation, true);
100 | if (registryKey != null)
101 | {
102 | registryKey.SetValue(REGDATA_LOCALE, ((int)config.Language).ToString());
103 | registryKey.SetValue(REGDATA_SAVELOCATION, config.InputSaveLocation);
104 | }
105 | registryKey?.Close();
106 | }
107 |
108 | private static void TryFixRegInSameProcess(int fixType, bool isElevated)
109 | {
110 | if (fixType != 0)
111 | {
112 | if (isElevated)
113 | {
114 | RegistryHandler.FixRegistry(fixType);
115 | }
116 | else
117 | {
118 | if (MessageBox.Show(Application.Current.TryFindResource("RegError").ToString(),
119 | Application.Current.TryFindResource("RegError_Title").ToString(),
120 | MessageBoxButton.YesNo,
121 | MessageBoxImage.Warning) == MessageBoxResult.Yes)
122 | {
123 | UacHelper.RestartAsAdminAndWait(fixType.ToString());
124 | }
125 | }
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Devices/AudioDevice.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Model.Devices
2 | {
3 | public class AudioDevice
4 | {
5 | public string Name { get; set; }
6 | public string GUID { get; set; }
7 |
8 | public override string ToString() => Name;
9 |
10 | public AudioDevice()
11 | {
12 | // Start with Default
13 | this.Name = "Default";
14 | this.GUID = "ffffffff-ffff-ffff-ffff-ffffffffffff";
15 | }
16 |
17 | public override bool Equals(object obj)
18 | {
19 | AudioDevice dev = (AudioDevice)obj;
20 | return GUID.Equals(dev.GUID);
21 | }
22 |
23 | public override int GetHashCode()
24 | {
25 | return GUID.GetHashCode();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Devices/GraphicsAdapter.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Settings.Model;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace ConfigurationTool.Model.Devices
6 | {
7 | public class GraphicsAdapter : IComparable
8 | {
9 | public String Description { get; set; } // GPU Name
10 | public String Name { get; set; } // Monitor index (\\.\DISPLAY1)
11 | public String GUID { get; set; } // GPU GUID
12 | public int Index { get; set; } // Monitor index
13 | public String MonitorID { get; set; } // Monitor ID
14 |
15 | public List Resolutions = new List();
16 |
17 | public override String ToString() => $"{Description} (Display {Index + 1})";
18 |
19 | public override bool Equals(object obj)
20 | {
21 | GraphicsAdapter adapter = (GraphicsAdapter)obj;
22 | return Description.Equals(adapter.Description) &&
23 | Name.Equals(adapter.Name) &&
24 | GUID.Equals(adapter.GUID);
25 | }
26 |
27 | public override int GetHashCode()
28 | {
29 | return Tuple.Create(Description, Name, GUID).GetHashCode();
30 | }
31 | public int CompareTo(object other)
32 | {
33 | GraphicsAdapter adapter = (GraphicsAdapter)other;
34 |
35 | if (adapter == null)
36 | {
37 | return 1;
38 | }
39 |
40 | return this.Index.CompareTo(adapter.Index);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Devices/InputDevice.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Input;
2 | using System;
3 | using System.Reflection;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 |
7 | namespace ConfigurationTool.Model.Devices
8 | {
9 | public enum DeviceType { XINPUT, DINPUT, KEYBOARD }
10 | public enum MovementType { DPAD, JOYSTICK, KEYBOARD }
11 |
12 | abstract class InputDevice
13 | {
14 | public DeviceType DeviceType;
15 | public abstract bool IsConnected { get; }
16 |
17 | public string Name;
18 | public string GUID;
19 | public MovementType MovementType;
20 |
21 | public ButtonConfiguration Buttons = new ButtonConfiguration();
22 | public AxisMap AxisMap = new AxisMap(); // Only used when MovementType is set to JOYSTICK
23 | public int Deadzone = 0;
24 |
25 | protected abstract int[] InvalidKeyCodes { get; }
26 | protected abstract int GetCurrentKey();
27 |
28 | public string Serialize()
29 | {
30 | return $"{Name}\n$G:{GUID}$B:{Buttons} {(int)MovementType}$A:{AxisMap}$D:{Deadzone}$";
31 | }
32 |
33 | public async Task SetKey(string keyName, InputDevice targetDevice, Action keyConsumer)
34 | {
35 | int key = -1;
36 |
37 | await Task.Run(() =>
38 | {
39 | SpinWait.SpinUntil(() =>
40 | {
41 | key = GetCurrentKey();
42 | return key != 0 && !Array.Exists(InvalidKeyCodes, elem => elem == key);
43 | });
44 | });
45 |
46 | if (key != -1)
47 | {
48 | FieldInfo targetProperty = null;
49 | FieldInfo[] fields = typeof(ButtonConfiguration).GetFields();
50 |
51 | for (int i = 0; i < fields.Length; ++i)
52 | {
53 | FieldInfo currField = fields[i];
54 | if (currField.Name.Equals(keyName))
55 | {
56 | targetProperty = currField;
57 | }
58 | if ((int)currField.GetValue(targetDevice.Buttons) == key)
59 | {
60 | currField.SetValue(targetDevice.Buttons, 0);
61 | }
62 |
63 | }
64 |
65 | // Change when implementing Dinput
66 | targetProperty?.SetValue(targetDevice.Buttons, key);
67 | }
68 |
69 | keyConsumer(key);
70 | }
71 | public override string ToString()
72 | {
73 | return Name;
74 | }
75 |
76 | public override bool Equals(object obj)
77 | {
78 | InputDevice device = (InputDevice)obj;
79 |
80 | return GUID.Equals(device.GUID);
81 | }
82 |
83 | public override int GetHashCode()
84 | {
85 | return GUID.GetHashCode();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Devices/Keyboard.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Input;
2 | using SharpDX.DirectInput;
3 | using System.Collections.Generic;
4 | using System.Windows;
5 |
6 | namespace ConfigurationTool.Model.Devices
7 | {
8 | class Keyboard : InputDevice
9 | {
10 | public override bool IsConnected => true;
11 |
12 | readonly SharpDX.DirectInput.Keyboard keyboard = new SharpDX.DirectInput.Keyboard(new DirectInput());
13 |
14 | protected override int[] InvalidKeyCodes => new int[] {
15 | (int)Key.LeftWindowsKey,
16 | (int)Key.RightWindowsKey,
17 | (int)Key.LeftControl,
18 | (int)Key.RightControl,
19 | (int)Key.LeftAlt,
20 | (int)Key.RightAlt,
21 | (int)Key.LeftShift,
22 | (int)Key.RightShift,
23 | (int)Key.Applications,
24 | (int)Key.PrintScreen,
25 | (int)Key.Oem102,
26 | (int)Key.Apostrophe,
27 | (int)Key.Backslash,
28 | (int)Key.Grave
29 | };
30 |
31 | public Keyboard()
32 | {
33 | this.Name = Application.Current.TryFindResource("Keyboard").ToString();
34 | this.GUID = "00000001-0000-0000-0000-000000000000";
35 | this.DeviceType = DeviceType.KEYBOARD;
36 | this.MovementType = MovementType.KEYBOARD;
37 | }
38 |
39 | public static Keyboard DeSerialize(string serialized)
40 | {
41 | Keyboard toReturn = new Keyboard();
42 |
43 | string[] split = serialized.Split('$');
44 | for (int i = 1; i < split.Length - 1; ++i)
45 | {
46 | split[i] = split[i].Substring(2);
47 | }
48 |
49 | toReturn.GUID = split[1];
50 | toReturn.Buttons = ButtonConfiguration.DeSerialize(split[2]);
51 | toReturn.AxisMap = new AxisMap(); // It's unused to we force default
52 | toReturn.Deadzone = int.Parse(split[4]);
53 | return toReturn;
54 | }
55 |
56 | protected override int GetCurrentKey()
57 | {
58 | keyboard.Acquire();
59 | List keys = keyboard.GetCurrentState().PressedKeys;
60 |
61 | if (keys.Count > 0)
62 | {
63 | Key key = keys[0];
64 | if (key == Key.LeftControl || key == Key.RightControl)
65 | {
66 | return -1;
67 | }
68 | else
69 | {
70 | return (int)key;
71 | }
72 | }
73 | return 0;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Devices/XinputController.cs:
--------------------------------------------------------------------------------
1 | using SharpDX.XInput;
2 | using System.Reflection;
3 | using System.Windows;
4 |
5 | namespace ConfigurationTool.Model.Devices
6 | {
7 | class XinputController : InputDevice
8 | {
9 | public override bool IsConnected => Controller.IsConnected;
10 | protected override int[] InvalidKeyCodes => new int[] { };
11 |
12 | private readonly Controller Controller;
13 |
14 | public XinputController(UserIndex port)
15 | {
16 | this.Name = Application.Current.TryFindResource("XinputDevice").ToString();
17 | this.GUID = "00000000-0000-0000-0000-000000000000";
18 | this.DeviceType = DeviceType.XINPUT;
19 | this.MovementType = MovementType.JOYSTICK; // Unused
20 | this.Controller = new Controller(port);
21 |
22 | foreach (FieldInfo field in Buttons.GetType().GetFields())
23 | {
24 | field.SetValue(Buttons, -1);
25 | }
26 | }
27 |
28 | protected override int GetCurrentKey() => -1;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Input/AxisMap.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Model.Input
2 | {
3 | class AxisMap
4 | {
5 | readonly int YPositive = 0;
6 | readonly int YNegative = 0;
7 | readonly int XPositive = 0;
8 | readonly int XNegative = 0;
9 |
10 | public override string ToString()
11 | {
12 | return $"{YPositive} {YNegative} {XPositive} {XNegative} ";
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Input/ButtonConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Model.Input
2 | {
3 | class ButtonConfiguration
4 | {
5 | public int A = 31;
6 | public int X = 30;
7 | public int Y = 17;
8 | public int B = 32;
9 |
10 | public int Start = 28;
11 | public int Back = 14;
12 |
13 | public int LB = 16;
14 | public int RB = 18;
15 |
16 | public int LT = 2;
17 | public int RT = 4;
18 |
19 | public int Up = 200;
20 | public int Down = 208;
21 | public int Right = 205;
22 | public int Left = 203;
23 |
24 | public int Unknown0 = 0;
25 | public int Unknown1 = 0;
26 | public int Unknown2 = 0;
27 | public int Unknown3 = 0;
28 |
29 | public static ButtonConfiguration DeSerialize(string buttons)
30 | {
31 | ButtonConfiguration toReturn = new ButtonConfiguration();
32 |
33 | string[] split = buttons.Split(' ');
34 | toReturn.A = int.Parse(split[0]);
35 | toReturn.X = int.Parse(split[1]);
36 | toReturn.Y = int.Parse(split[2]);
37 | toReturn.B = int.Parse(split[3]);
38 |
39 | toReturn.Start = int.Parse(split[4]);
40 | toReturn.Back = int.Parse(split[5]);
41 |
42 | toReturn.LB = int.Parse(split[6]);
43 | toReturn.RB = int.Parse(split[7]);
44 |
45 | toReturn.LT = int.Parse(split[8]);
46 | toReturn.RT = int.Parse(split[9]);
47 |
48 | toReturn.Up = int.Parse(split[10]);
49 | toReturn.Down = int.Parse(split[11]);
50 | toReturn.Right = int.Parse(split[12]);
51 | toReturn.Left = int.Parse(split[13]);
52 |
53 | return toReturn;
54 | }
55 |
56 | public override string ToString()
57 | {
58 | return $"{A} {X} {Y} {B} {Start} {Back} {LB} {RB} {LT} {RT} {Up} {Down} {Right} {Left} {Unknown0} {Unknown1} {Unknown2} {Unknown3}";
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/DepthFormat.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ConfigurationTool.Settings.Model
6 | {
7 | public class DepthFormat
8 | {
9 | public readonly string Value;
10 |
11 | public static DepthFormat INTZ = new DepthFormat("INTZ");
12 | public static DepthFormat DF24 = new DepthFormat("DF24");
13 | public static DepthFormat DF16 = new DepthFormat("DF16");
14 |
15 | private DepthFormat(string value)
16 | {
17 | this.Value = value;
18 | }
19 |
20 | public static IEnumerable GetAll()
21 | {
22 | yield return INTZ;
23 | yield return DF24;
24 | yield return DF16;
25 | }
26 |
27 | public uint GetFourCC()
28 | {
29 | //return (uint)((Value[3] << 24) + (Value[2] << 16) + (Value[1] << 8) + Value[0]);
30 | return BitConverter.ToUInt32(Encoding.ASCII.GetBytes(Value), 0);
31 | }
32 |
33 | public static DepthFormat FromFourCC(int fourcc)
34 | {
35 | string depth = Encoding.ASCII.GetString(BitConverter.GetBytes(fourcc));
36 | return new DepthFormat(depth);
37 | }
38 |
39 | public override string ToString()
40 | {
41 | return Value;
42 | }
43 |
44 | public override bool Equals(object obj)
45 | {
46 | DepthFormat df = (DepthFormat)obj;
47 | return Value.Equals(df.Value);
48 | }
49 |
50 | public override int GetHashCode()
51 | {
52 | return Value.GetHashCode();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/DisplayMode.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Settings.Model
2 | {
3 | enum DisplayMode
4 | {
5 | Widescreen = 0,
6 | Letterbox = 1
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/HighLow.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Settings.Model
2 | {
3 | enum HighLow
4 | {
5 | High = 1,
6 | Low = 0
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/Language.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Model.Settings
2 | {
3 | enum Language
4 | {
5 | English = 1033,
6 | French = 1036,
7 | German = 1031,
8 | Italian = 1040,
9 | Spanish = 3082,
10 | Japanese = 0411
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/OnOff.cs:
--------------------------------------------------------------------------------
1 | namespace ConfigurationTool.Settings.Model
2 | {
3 | enum OnOff
4 | {
5 | On = 1,
6 | Off = 0
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/RefreshRate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ConfigurationTool.Model.Settings
8 | {
9 | public class RefreshRate : IComparable
10 | {
11 | public readonly int Value;
12 |
13 | public RefreshRate(int value)
14 | {
15 | this.Value = value;
16 | }
17 |
18 | public override string ToString()
19 | {
20 | return $"{Value}Hz";
21 | }
22 |
23 | public int CompareTo(object other)
24 | {
25 | RefreshRate refreshRate = (RefreshRate)other;
26 |
27 | if (refreshRate == null)
28 | {
29 | return 1;
30 | }
31 |
32 | return this.Value.CompareTo(refreshRate.Value);
33 | }
34 |
35 | public override bool Equals(object obj)
36 | {
37 | RefreshRate toCompare = (RefreshRate)obj;
38 | return Value == toCompare.Value;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/GensConfigTool/Model/Settings/Resolution.cs:
--------------------------------------------------------------------------------
1 | using ConfigurationTool.Model.Settings;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace ConfigurationTool.Settings.Model
6 | {
7 | public class Resolution : IComparable
8 | {
9 | public int Width { get; set; }
10 | public int Height { get; set; }
11 | public List RefreshRates = new List();
12 |
13 | public int CompareTo(object other)
14 | {
15 | Resolution res = (Resolution)other;
16 |
17 | if (other == null)
18 | {
19 | return 1;
20 | }
21 |
22 | if (this.Width == res.Width)
23 | {
24 | return this.Height.CompareTo(res.Height);
25 | }
26 |
27 | return this.Width.CompareTo(res.Width);
28 | }
29 | public override string ToString() => $"{Width} x {Height}";
30 |
31 | public override bool Equals(object obj)
32 | {
33 | Resolution res = (Resolution)obj;
34 |
35 | return Width == res.Width && Height == res.Height;
36 | }
37 |
38 | public override int GetHashCode()
39 | {
40 | return Tuple.Create(Width, Height).GetHashCode();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GensConfigTool/Resources/ConfigurationTool.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/ConfigurationTool.ico
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Dictionary.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 | Sonic Generations - Configuration
6 | N/A
7 | Undefined
8 |
9 | Settings
10 | Input
11 | Description
12 | Hover the cursor over an option to better understand its purpose
13 |
14 | Graphics
15 | Audio
16 | Other
17 |
18 | On
19 | Off
20 |
21 | Enable Analytics
22 | Disable Analytics
23 |
24 | High
25 | Low
26 |
27 | Widescreen
28 | Letterbox
29 |
30 | Save
31 | Quit
32 | Save and Quit
33 |
34 | Analytics
35 | Analytics Info
36 | Sonic Generations is supported by IncludeApp.
37 |
38 | IncludeApp was a game monitoring system that provided developers with detailed information regarding how their games were played. If you agreed to activate this feature, your game would upload data that could be used to analyse your game-play experience.
39 |
40 | IncludeApp was discontinued, so no data is currently being sent, although the data is still being collected from the game offline if you opt into the service.
41 |
42 | Adapter
43 | Resolution
44 | Anti-Aliasing (FXAA)
45 | Display Mode
46 | Shadow Quality
47 | Reflection Quality
48 | V-Sync
49 | Device
50 | Language
51 |
52 | Sets the adapter and display to use to display the game.
53 | Sets the resolution to display the game at.
54 | Reduces aliasing on sharp edges for visual clarity.
55 | Determines how the game should be displayed at non-wide resolutions.
56 | Sets the resolution of the real-time shadows.
57 | Sets the resolution of the real-time reflections.
58 | Reduces screen tearing by locking the games frame rate at your monitor's refresh rate. This may impact latency for inputs.
59 | Sets the device to use to play back audio for the game.
60 | Determines what language to use for the game.
61 |
62 | The configuration tool detected an invalid registry configuration. Would you like to fix the registry? Pressing No may result in the game being unable to boot.
63 | Registry Error
64 |
65 | Do not edit this file manually unless you know what you're doing
66 |
67 | Device
68 | Press any controller's Start button during play to switch to that controller
69 | XInput Device
70 | Keyboard
71 |
72 | Press a key to map this button. Press CTRL to cancel.
73 | Reset to Defaults
74 |
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/A.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/B.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/B.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Back.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/LB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/LB.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/LT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/LT.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/RB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/RB.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/RT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/RT.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Start.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Stick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Stick.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Stick_Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Stick_Down.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Stick_Left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Stick_Left.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Stick_Right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Stick_Right.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Stick_Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Stick_Up.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/X.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/X.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Buttons/Y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Buttons/Y.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Display.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Display.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/FXAA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/FXAA.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Icon.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Misc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Misc.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/None.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/None.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Res.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Res.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Shadows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Shadows.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Images/Vsync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/GensConfigTool/Resources/Images/Vsync.png
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Themes/Dark.xaml:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Themes/Light.xaml:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------
/GensConfigTool/Resources/Themes/ThemeBase.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
13 |
14 |
50 |
51 |
54 |
55 |
58 |
59 |
64 |
65 |
101 |
102 |
130 |
131 |
141 |
142 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
180 |
183 |
184 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
279 |
280 |
298 |
346 |
347 |
382 |
383 |
392 |
393 |
394 |
--------------------------------------------------------------------------------
/Images/Config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/Images/Config.png
--------------------------------------------------------------------------------
/Images/Config_Dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/Images/Config_Dark.png
--------------------------------------------------------------------------------
/Images/Input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/Images/Input.png
--------------------------------------------------------------------------------
/Images/Input_Dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTKay/GenerationsConfigTool_Rewrite/c31706b3295d0fd14ec2f53643a1f36ddeea5f79/Images/Input_Dark.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sonic Generations Configuration Tool (Rewrite)
2 | [](https://ci.appveyor.com/project/PTKickass/generationsconfigtool-rewrite)
3 |
4 | Rewriting Sonic Generations' Configuration Tool using WPF as a way to teach myself how to use it.
5 |
6 | ## Current features:
7 |
8 | - Supports Graphics, Audio and Analytics configuration, all in the same tab
9 | - Supports fixing the registry to avoid the `Game files either missing or corrupt please reinstall` issue
10 | - Supports proper scaling
11 | - Includes settings descriptions and images to better visualize the impact of each one
12 | - Proper Nvidia Optimus support, so the config tool will always detect your high performance Nvidia GPU
13 | - Supports changing the in-game language (requires admin rights because this is stored in LOCAL_MACHINE for some reason)
14 | - Supports Dark Theme
15 | - Significantly smaller file size compared to the original configuration tool (~5MB vs ~28MB)
16 |
17 | ## Current drawbacks:
18 | - No Dinput devices support, but since Sonic Generations doesn't properly support Dinput devices to begin with, it shouldn't matter that much
19 | - No proper 32-bit support if you have GCL (Generations Code Loader, included with HedgeModManager) installed
20 |
21 | ## Images
22 | Light Theme | Dark Theme
23 | :-------------------------:|:-------------------------:
24 |  | 
25 |  | 
26 |
27 | ## Credits
28 | - [PTKickass](https://github.com/PTKickass) - Code and UI
29 | - [M&M](https://github.com/ActualMandM) - Font images
30 | - [Hyper](https://github.com/HyperBE32) - Settings descriptions
31 | - Devil's Details - Original Configuration Tool
32 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: '1.0-dev_r{build}'
2 |
3 | environment:
4 | matrix:
5 | - appveyor_build_worker_image: Visual Studio 2019
6 | configuration: Debug
7 | platform: Any CPU
8 | - appveyor_build_worker_image: Visual Studio 2019
9 | configuration: Release
10 | platform: Any CPU
11 |
12 | before_build:
13 | - nuget restore
14 |
15 | build:
16 | verbosity: minimal
17 |
18 | artifacts:
19 | - path: 'GensConfigTool\bin\Debug'
20 | name: '$(appveyor_project_name) $(appveyor_build_version) [Debug]'
21 | type: exe
22 | - path: 'GensConfigTool\bin\Release'
23 | name: '$(appveyor_project_name) $(appveyor_build_version) [Release]'
24 | type: exe
25 |
26 |
--------------------------------------------------------------------------------