aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/GameRenderer.cpp
diff options
context:
space:
mode:
authorMrTheShy <49885496+MrTheShy@users.noreply.github.com>2026-03-09 04:16:58 +0100
committerGitHub <noreply@github.com>2026-03-08 22:16:58 -0500
commite2adaa082c219c4c5f2025ae4898d3711000cab9 (patch)
treeeab47ca9db8d338811333bde4fbe04815adc38d7 /Minecraft.Client/GameRenderer.cpp
parent42164eeb897bd5a8a409aa7fa8539ab1f2a77b45 (diff)
Fix split-screen UI wrong positioning on window resize (#989)
* Fix split-screen UI wrong positioning on window resize In vertical split at window heights below 1080, ComputeTileScale's min-scale clamp (>= 1.0) prevented the SWF from scaling down to fit, cropping the bottom and causing repositionHud to shift HUD elements downward. Chat and Tooltips additionally applied an offset from ComputeSplitContentOffset that only produced correct values at the 1920x1080 design resolution. Override the scale for vertical split so the SWF fits the full window height when it is shorter than the movie. Remove the broken content offset from Chat and Tooltips -- the tile crop already positions the content correctly. * Fix gamma post-process in split-screen The gamma shader sampled the full backbuffer texture (UV 0..1) into each player's viewport, stretching the entire screen into every split region. Extended the shader constant buffer with per-viewport UV offset and scale so each pass samples only its own portion of the backbuffer. ComputeViewportForPlayer was hardcoded to top/bottom for 2 players, ignoring the vertical split setting. Rewrote it to read each player's m_iScreenSection directly, which already accounts for the split orientation preference. Secondary players have no Graphics menu and cannot change gamma. CachePlayerGammas now reads the primary player's setting and applies it uniformly to all viewports.
Diffstat (limited to 'Minecraft.Client/GameRenderer.cpp')
-rw-r--r--Minecraft.Client/GameRenderer.cpp123
1 files changed, 51 insertions, 72 deletions
diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp
index 169f1280..73b39529 100644
--- a/Minecraft.Client/GameRenderer.cpp
+++ b/Minecraft.Client/GameRenderer.cpp
@@ -954,91 +954,70 @@ float GameRenderer::ComputeGammaFromSlider(float slider0to100)
void GameRenderer::CachePlayerGammas()
{
- for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j)
- {
- std::shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j];
- if (!player)
- {
- m_cachedGammaPerPlayer[j] = 1.0f;
- continue;
- }
+ const float slider = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_Gamma);
+ const float gamma = ComputeGammaFromSlider(slider);
- const float slider = app.GetGameSettings(j, eGameSetting_Gamma); // 0..100
- m_cachedGammaPerPlayer[j] = ComputeGammaFromSlider(slider);
- }
+ for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j)
+ m_cachedGammaPerPlayer[j] = gamma;
}
bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const
{
- // Use the actual backbuffer dimensions so viewports adapt to window resize.
extern int g_rScreenWidth;
extern int g_rScreenHeight;
- int active = 0;
- int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1};
- for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i)
- {
- if (Minecraft::GetInstance()->localplayers[i])
- indexMap[active++] = i;
- }
-
- if (active <= 1)
- {
- outViewport.TopLeftX = 0.0f;
- outViewport.TopLeftY = 0.0f;
- outViewport.Width = static_cast<FLOAT>(g_rScreenWidth);
- outViewport.Height = static_cast<FLOAT>(g_rScreenHeight);
- outViewport.MinDepth = 0.0f;
- outViewport.MaxDepth = 1.0f;
- return true;
- }
-
- int k = -1;
- for (int ord = 0; ord < active; ++ord)
- if (indexMap[ord] == j)
- {
- k = ord;
- break;
- }
- if (k < 0)
+ std::shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j];
+ if (!player)
return false;
- const float width = static_cast<float>(g_rScreenWidth);
- const float height = static_cast<float>(g_rScreenHeight);
+ const float w = static_cast<float>(g_rScreenWidth);
+ const float h = static_cast<float>(g_rScreenHeight);
+ const float halfW = w * 0.5f;
+ const float halfH = h * 0.5f;
- if (active == 2)
- {
- const float halfH = height * 0.5f;
- outViewport.TopLeftX = 0.0f;
- outViewport.Width = width;
- outViewport.MinDepth = 0.0f;
- outViewport.MaxDepth = 1.0f;
- if (k == 0)
- {
- outViewport.TopLeftY = 0.0f;
- outViewport.Height = halfH;
- }
- else
- {
- outViewport.TopLeftY = halfH;
- outViewport.Height = halfH;
- }
- return true;
- }
- else
+ outViewport.MinDepth = 0.0f;
+ outViewport.MaxDepth = 1.0f;
+
+ switch (static_cast<C4JRender::eViewportType>(player->m_iScreenSection))
{
- const float halfW = width * 0.5f;
- const float halfH = height * 0.5f;
- const int row = (k >= 2) ? 1 : 0;
- const int col = (k % 2);
- outViewport.TopLeftX = col ? halfW : 0.0f;
- outViewport.TopLeftY = row ? halfH : 0.0f;
- outViewport.Width = halfW;
- outViewport.Height = halfH;
- outViewport.MinDepth = 0.0f;
- outViewport.MaxDepth = 1.0f;
- return true;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
+ outViewport.Width = w; outViewport.Height = halfH;
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH;
+ outViewport.Width = w; outViewport.Height = halfH;
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
+ outViewport.Width = halfW; outViewport.Height = h;
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
+ outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0;
+ outViewport.Width = halfW; outViewport.Height = h;
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
+ outViewport.Width = halfW; outViewport.Height = halfH;
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
+ outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0;
+ outViewport.Width = halfW; outViewport.Height = halfH;
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH;
+ outViewport.Width = halfW; outViewport.Height = halfH;
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
+ outViewport.TopLeftX = halfW; outViewport.TopLeftY = halfH;
+ outViewport.Width = halfW; outViewport.Height = halfH;
+ break;
+ default:
+ outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
+ outViewport.Width = w; outViewport.Height = h;
+ break;
}
+ return true;
}
uint32_t GameRenderer::BuildPlayerViewports(D3D11_VIEWPORT *outViewports, float *outGammas, UINT maxCount) const