-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
253 lines (220 loc) · 7.32 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
102
103
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
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Runtime.Versioning;
[SupportedOSPlatform("windows")]
class Program
{
[DllImport("user32.dll")]
private static extern bool EnumDisplayDevices(string? lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DISPLAY_DEVICE
{
public uint cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceString;
public uint StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceKey;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public uint dmFields;
public int dmPositionX;
public int dmPositionY;
public uint dmDisplayOrientation;
public uint dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public uint dmBitsPerPel;
public uint dmPelsWidth;
public uint dmPelsHeight;
public uint dmDisplayFlags;
public uint dmDisplayFrequency;
public uint dmICMMethod;
public uint dmICMIntent;
public uint dmMediaType;
public uint dmDitherType;
public uint dmReserved1;
public uint dmReserved2;
public uint dmPanningWidth;
public uint dmPanningHeight;
}
private const int ENUM_CURRENT_SETTINGS = -1;
static bool isDebug;
static void Main(string[] args)
{
if (!OperatingSystem.IsWindows())
{
Console.WriteLine("This application only runs on Windows.");
return;
}
isDebug = args.Contains("--debug");
int targetResolution = 3840;
for (int i = 0; i < args.Length - 1; i++)
{
if (args[i] is "--resolution" or "-r")
{
if (int.TryParse(args[i + 1], out int resolution))
{
targetResolution = resolution;
}
break;
}
}
Log($"Starting monitor detection (Target Resolution: {targetResolution})...");
var displays = EnumerateDisplays();
int targetIndex = -1;
for (int i = 0; i < displays.Count; i++)
{
var (deviceName, width, height) = displays[i];
Log($"Monitor {i}: {deviceName} - {width}x{height}");
if (width == targetResolution)
{
targetIndex = i;
break;
}
}
if (targetIndex != -1)
{
Log($"Found display with resolution {targetResolution} at index {targetIndex}");
UpdateRegistry(targetIndex);
UpdateIniFile(targetIndex);
}
else
{
Log($"No display with resolution {targetResolution} found!");
}
if (isDebug) Thread.Sleep(3000);
}
static List<(string deviceName, uint width, uint height)> EnumerateDisplays()
{
var displays = new List<(string, uint, uint)>();
var device = new DISPLAY_DEVICE();
var devMode = new DEVMODE();
device.cb = (uint)Marshal.SizeOf(device);
devMode.dmSize = (short)Marshal.SizeOf(devMode);
try
{
for (uint id = 0; EnumDisplayDevices(null, id, ref device, 0); id++)
{
if ((device.StateFlags & 0x1) != 0) // DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
{
if (EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS, ref devMode))
{
displays.Add((device.DeviceName, devMode.dmPelsWidth, devMode.dmPelsHeight));
}
}
}
}
catch (Exception ex)
{
Log($"Error enumerating displays: {ex.Message}");
throw;
}
if (displays.Count == 0)
{
Log("Warning: No displays detected!");
}
return displays;
}
static void UpdateRegistry(int index)
{
if (index < 0)
{
throw new ArgumentException("Display index cannot be negative", nameof(index));
}
Log($"Updating VPinballX registry with display index: {index}");
try
{
using var key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Visual Pinball\VP10\Player");
key.SetValue("Display", index, RegistryValueKind.DWord);
Log("Registry update successful");
}
catch (Exception ex)
{
Log($"Registry update failed: {ex.Message}");
throw;
}
}
static void UpdateIniFile(int index)
{
if (index < 0)
{
throw new ArgumentException("Display index cannot be negative", nameof(index));
}
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"VPinballX",
"VPinballX.ini"
);
Log($"Updating VPinballX config at: {path}");
try
{
var lines = File.Exists(path)
? File.ReadAllLines(path).ToList()
: new List<string>();
bool foundSection = false;
bool foundSetting = false;
int sectionIndex = -1;
for (int i = 0; i < lines.Count; i++)
{
if (lines[i].Trim() == "[Player]")
{
foundSection = true;
sectionIndex = i;
break;
}
}
if (!foundSection)
{
lines.Add("[Player]");
sectionIndex = lines.Count - 1;
}
for (int i = sectionIndex + 1; i < lines.Count; i++)
{
if (lines[i].Trim().StartsWith("[")) break;
if (lines[i].StartsWith("Display = "))
{
lines[i] = $"Display = {index}";
foundSetting = true;
break;
}
}
if (!foundSetting)
{
lines.Insert(sectionIndex + 1, $"Display = {index}");
}
File.WriteAllLines(path, lines);
Log("INI file updated successfully");
}
catch (Exception ex)
{
Log($"INI update failed: {ex.Message}");
throw;
}
}
static void Log(string message)
{
if (isDebug)
Console.WriteLine(message);
}
}