graphics: option to change primary monitor before launching game (#608)

## Description of change

Adds `-mainmonitor` option which changes the monitor layout before
launching the game. This is much more reliable than the old `-monitor`
option which operated at DX9 level. This works for TDJ/UFC subscreens,
for example.

Rename `-monitor` option to `-dx9mainadapter` to discourage use.
`-monitor` will continue to work, of course.

Changing of primary monitor happens first before any orientation changes
/ refresh rate changes, which means those options will result in the
logically correct configuration.

Create a new option category for `Monitor` (rotate, refresh rate, etc).

Add a monitor selection widget for `-mainmonitor` option in the
configurator.

Improve how we log names of monitors in the log during boot - should be
less of "Generic PnP Monitor" after this.
This commit is contained in:
bicarus
2026-04-04 23:26:38 -07:00
committed by GitHub
parent a4c3eddc2f
commit ee3fa58bfa
9 changed files with 377 additions and 73 deletions
+25
View File
@@ -34,6 +34,7 @@
#include "util/resutils.h"
#include "util/scope_guard.h"
#include "util/time.h"
#include "util/sysutils.h"
#include "util/utils.h"
#ifdef min
@@ -4237,6 +4238,8 @@ namespace overlay::windows {
return "File Picker";
case OptionPickerType::DirectoryPath:
return "Folder Picker";
case OptionPickerType::Monitor:
return "Monitor Picker";
default:
return "Unknown Picker";
};
@@ -4467,6 +4470,28 @@ namespace overlay::windows {
ImGui::EndDisabled();
}
} else if (definition.picker == OptionPickerType::Monitor) {
const auto &monitors = sysutils::enumerate_monitors();
if (monitors.empty()) {
ImGui::TextUnformatted("Failed to fetch monitors. Requires Win7+");
} else {
ImGui::TextUnformatted("Pick from monitors:");
ImGui::SetNextItemWidth(300.f);
if (ImGui::BeginListBox("##monitors")) {
for (const auto &monitor : monitors) {
const bool is_selected = option.value == monitor.display_name;
auto friendly = wchar_to_u8(monitor.friendly_name.c_str());
if (ImGui::Selectable(
fmt::format("{} ({})", monitor.display_name, friendly).c_str(),
is_selected)) {
option.value = monitor.display_name;
}
}
ImGui::EndListBox();
}
}
} else {
ImGui::TextUnformatted("No picker available for this option. How did you get here?");
}