diff options
| author | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:41:49 -0500 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:54:48 -0500 |
| commit | 9acc324228b7028f947e053a08c18543f631e5ce (patch) | |
| tree | b08e665d1bcccaf6f52278466db182b6cb439939 | |
| parent | a169391e6019d6356cc0492c5a25cf7dbfc22fa3 (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>
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 24 |
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}; |
