diff options
Diffstat (limited to 'Minecraft.Client/Common/UI/UIController.cpp')
| -rw-r--r-- | Minecraft.Client/Common/UI/UIController.cpp | 149 |
1 files changed, 80 insertions, 69 deletions
diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 840ed389..b0bd7dd3 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -13,6 +13,7 @@ #include "..\..\EnderDragonRenderer.h" #include "..\..\MultiPlayerLocalPlayer.h" #include "UIFontData.h" +#include "UISplitScreenHelpers.h" #ifdef _WINDOWS64 #include "..\..\Windows64\KeyboardMouseInput.h" #endif @@ -57,6 +58,8 @@ bool UIController::ms_bReloadSkinCSInitialised = false; DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME; +// GetViewportRect and Fit16x9 are now in UISplitScreenHelpers.h + #ifdef _WINDOWS64 static UIControl_Slider *FindSliderById(UIScene *pScene, int sliderId) { @@ -806,13 +809,16 @@ void UIController::tickInput() eUILayer_Fullscreen, eUILayer_Scene, }; - for (int l = 0; l < _countof(mouseLayers) && !pScene; ++l) + // Only check the fullscreen group and the primary (KBM) player's group. + // Other splitscreen players use controllers — mouse must not affect them. + const int mouseGroups[] = { (int)eUIGroup_Fullscreen, ProfileManager.GetPrimaryPad() + 1 }; + for (int l = 0; l < _countof(mouseLayers) && !pScene; ++l) + { + for (int g = 0; g < _countof(mouseGroups) && !pScene; ++g) { - for (int grp = 0; grp < eUIGroup_COUNT && !pScene; ++grp) - { - pScene = m_groups[grp]->GetTopScene(mouseLayers[l]); - } + pScene = m_groups[mouseGroups[g]]->GetTopScene(mouseLayers[l]); } + } if (pScene && pScene->getMovie()) { int rawMouseX = g_KBMInput.GetMouseX(); @@ -825,7 +831,12 @@ void UIController::tickInput() m_lastHoverMouseX = rawMouseX; m_lastHoverMouseY = rawMouseY; - // Convert mouse to scene/movie coordinates + // Convert mouse window-pixel coords to Flash/SWF authoring coords. + // In split-screen the scene is rendered at a tile-origin offset + // and at a smaller display size, so we must: + // 1. Map window pixels -> UIController screen space + // 2. Subtract the viewport tile origin + // 3. Scale from display dimensions to SWF authoring dimensions F32 sceneMouseX = (F32)rawMouseX; F32 sceneMouseY = (F32)rawMouseY; { @@ -837,8 +848,30 @@ void UIController::tickInput() int winH = rc.bottom - rc.top; if (winW > 0 && winH > 0) { - sceneMouseX = sceneMouseX * ((F32)pScene->getRenderWidth() / (F32)winW); - sceneMouseY = sceneMouseY * ((F32)pScene->getRenderHeight() / (F32)winH); + // Step 1: window pixels -> screen space + F32 screenX = sceneMouseX * (getScreenWidth() / (F32)winW); + F32 screenY = sceneMouseY * (getScreenHeight() / (F32)winH); + + // Step 2 & 3: account for split-screen viewport + C4JRender::eViewportType vp = pScene->GetParentLayer()->getViewport(); + S32 displayW = 0, displayH = 0; + getRenderDimensions(vp, displayW, displayH); + + F32 vpOriginX, vpOriginY, vpW, vpH; + GetViewportRect(getScreenWidth(), getScreenHeight(), vp, vpOriginX, vpOriginY, vpW, vpH); + // All viewports use Fit16x9 for menu scenes + S32 fitW, fitH, fitOffsetX, fitOffsetY; + Fit16x9(vpW, vpH, fitW, fitH, fitOffsetX, fitOffsetY); + S32 originX = (S32)vpOriginX + fitOffsetX; + S32 originY = (S32)vpOriginY + fitOffsetY; + displayW = fitW; + displayH = fitH; + + if (displayW > 0 && displayH > 0) + { + sceneMouseX = (screenX - originX) * ((F32)pScene->getRenderWidth() / (F32)displayW); + sceneMouseY = (screenY - originY) * ((F32)pScene->getRenderHeight() / (F32)displayH); + } } } } @@ -1566,73 +1599,48 @@ void UIController::renderScenes() void UIController::getRenderDimensions(C4JRender::eViewportType viewport, S32 &width, S32 &height) { - switch( viewport ) + F32 originX, originY, viewW, viewH; + GetViewportRect(getScreenWidth(), getScreenHeight(), viewport, originX, originY, viewW, viewH); + + if(viewport == C4JRender::VIEWPORT_TYPE_FULLSCREEN) { - case C4JRender::VIEWPORT_TYPE_FULLSCREEN: - width = (S32)(getScreenWidth()); - height = (S32)(getScreenHeight()); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: - case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: - width = (S32)(getScreenWidth() / 2); - height = (S32)(getScreenHeight() / 2); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: - case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: - width = (S32)(getScreenWidth() / 2); - height = (S32)(getScreenHeight() / 2); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: - width = (S32)(getScreenWidth() / 2); - height = (S32)(getScreenHeight() / 2); - break; + S32 offsetX, offsetY; + Fit16x9(viewW, viewH, width, height, offsetX, offsetY); + } + else + { + // Split-screen: use raw viewport dims — the SWF tiling code handles non-16:9 + width = (S32)viewW; + height = (S32)viewH; } } void UIController::setupRenderPosition(C4JRender::eViewportType viewport) { - if(m_bCustomRenderPosition || m_currentRenderViewport != viewport) + m_currentRenderViewport = viewport; + m_bCustomRenderPosition = false; + + F32 vpOriginX, vpOriginY, vpW, vpH; + GetViewportRect(getScreenWidth(), getScreenHeight(), viewport, vpOriginX, vpOriginY, vpW, vpH); + + S32 xPos, yPos; + if(viewport == C4JRender::VIEWPORT_TYPE_FULLSCREEN) { - m_currentRenderViewport = viewport; - m_bCustomRenderPosition = false; - S32 xPos = 0; - S32 yPos = 0; - switch( viewport ) - { - case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: - xPos = (S32)(getScreenWidth() / 4); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: - xPos = (S32)(getScreenWidth() / 4); - yPos = (S32)(getScreenHeight() / 2); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: - yPos = (S32)(getScreenHeight() / 4); - break; - case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: - xPos = (S32)(getScreenWidth() / 2); - yPos = (S32)(getScreenHeight() / 4); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: - xPos = (S32)(getScreenWidth() / 2); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: - yPos = (S32)(getScreenHeight() / 2); - break; - case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: - xPos = (S32)(getScreenWidth() / 2); - yPos = (S32)(getScreenHeight() / 2); - break; - } - m_tileOriginX = xPos; - m_tileOriginY = yPos; - setTileOrigin(xPos, yPos); + S32 fitW, fitH, fitOffsetX, fitOffsetY; + Fit16x9(vpW, vpH, fitW, fitH, fitOffsetX, fitOffsetY); + xPos = (S32)vpOriginX + fitOffsetX; + yPos = (S32)vpOriginY + fitOffsetY; + } + else + { + // Split-screen: position at viewport origin, no 16:9 fitting + xPos = (S32)vpOriginX; + yPos = (S32)vpOriginY; } + + m_tileOriginX = xPos; + m_tileOriginY = yPos; + setTileOrigin(xPos, yPos); } void UIController::setupRenderPosition(S32 xOrigin, S32 yOrigin) @@ -1840,8 +1848,11 @@ void RADLINK UIController::TextureSubstitutionDestroyCallback ( void * user_call ui.destroySubstitutionTexture(user_callback_data, handle); - Textures *t = Minecraft::GetInstance()->textures; - t->releaseTexture( id ); + Minecraft* mc = Minecraft::GetInstance(); + if (mc && mc->textures) + { + mc->textures->releaseTexture( id ); + } } void UIController::registerSubstitutionTexture(const wstring &textureName, PBYTE pbData, DWORD dwLength) |
