aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-01 21:41:49 -0500
committerDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-01 21:54:48 -0500
commit9acc324228b7028f947e053a08c18543f631e5ce (patch)
treeb08e665d1bcccaf6f52278466db182b6cb439939 /src
parenta169391e6019d6356cc0492c5a25cf7dbfc22fa3 (diff)
nx2:vi2: report the display's maximum buffer resolution
Command 106 was auto-stubbed, and Fire Emblem: Fortune's Weave treats its empty reply as mode 0 and picks its 720p tier (rendering at 360p). Report mode 4 (1440p) docked and 2 (1080p, the screen) handheld; the game then renders at 720p and 540p and upscales to those. EDEN_VI2_MAX_RESOLUTION_MODE overrides the mode. Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nx2_gsv.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h
index 397e2aacb8..5a2963f179 100644
--- a/src/core/hle/service/nx2_gsv.h
+++ b/src/core/hle/service/nx2_gsv.h
@@ -1454,6 +1454,7 @@ public:
// auto stub's empty success reply works, but logged two lines per call (a 50 MB log
// in an 18 minute session).
{105, &INx2Vi2Session::SucceedQuietly, "Unknown105 (display \"default\")"},
+ {106, &INx2Vi2Session::GetBufferMaxResolution, "GetBufferMaxResolution"},
{228, &INx2Vi2Session::CancelClientBuffer, "CancelClientBuffer"},
{229, &INx2Vi2Session::PresentClientBuffer, "PresentClientBuffer"},
});
@@ -1847,6 +1848,29 @@ private:
rb.Push<u32>(0);
}
+ // The highest buffer resolution mode of the "default" display. Fire Emblem: Fortune's Weave picks
+ // its output from it: 1 -> 1280x720, 2 -> 1920x1080, 4 and 8 -> 2560x1440; 0 (the auto stub's
+ // reply), 3 and 5 fall back to 720p. Docked reports 4, handheld 2 (the screen is 1080p);
+ // EDEN_VI2_MAX_RESOLUTION_MODE=<n> overrides.
+ void GetBufferMaxResolution(HLERequestContext& ctx) {
+ const auto* packet = ctx.CommandBuffer();
+ const u64 name = u64{packet[2]} | (u64{packet[3]} << 32);
+ constexpr u64 DefaultDisplay = 0x00746c7561666564ULL; // "default"
+ Result result = Kernel::ResultInvalidCombination;
+ u64 mode{};
+ if (packet[0] == 0x7a && packet[1] == 2) {
+ result = Result{ErrorModule::VI, 7};
+ if (name == DefaultDisplay) {
+ static const char* forced = std::getenv("EDEN_VI2_MAX_RESOLUTION_MODE");
+ mode = forced ? std::strtoull(forced, nullptr, 0) : Settings::IsDockedMode() ? 4 : 2;
+ result = ResultSuccess;
+ }
+ }
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result.raw);
+ rb.Push(mode);
+ }
+
// The same reply as the auto stub (success, no data), without its log lines.
void SucceedQuietly(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};