mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
Split-screen UI system with full ultrawide and multi-aspect-ratio support
Screen resolution is now auto-detected from the monitor at startup instead of being hardcoded to 1920x1080. This fixes rendering on ultrawide (21:9), super-ultrawide (32:9), 16:10, and any other aspect ratio -- both in singleplayer and split-screen multiplayer. The 3D world renders at native resolution so the full monitor is used. Flash UI is 16:9-fitted and centered inside each viewport, pillarboxed on wide displays and letterboxed on tall ones. Logical game dimensions (used for ortho projection and HUD layout) are computed proportionally from the real screen aspect ratio, fixing the stretched world projection and HUD that the old hardcoded 1280x720 caused on non-16:9 monitors. GameRenderer::ComputeViewportForPlayer uses the actual backbuffer size instead of the logical game size, which was causing split-screen viewports to be sized incorrectly. UIScene::render fits menus to 16:9 within each split viewport using GetViewportRect + Fit16x9, keeping inventory/crafting/options screens at their designed aspect ratio instead of stretching. Panorama and MenuBackground render at full viewport size with proper tile scaling so the background fills the entire area without gaps in vertical split and quadrant layouts. HUD tile rendering uses ComputeTileScale to uniformly scale the SWF and show the bottom portion (hotbar, hearts, hunger) in horizontal and quadrant splits. repositionHud passes visible SWF-space dimensions to ActionScript for proper element centering within each viewport. Chat and Tooltips overlays use ComputeTileScale and ComputeSplitContentOffset to anchor correctly to the bottom of each player's viewport tile. Container menus apply Fit16x9 to pointer coordinate mapping so the cursor tracks correctly in split-screen. getMouseToSWFScale moved out of the header into the .cpp. Mouse input in onMouseTick is gated to pad 0 since raw mouse deltas should only drive player 1. All shared viewport math lives in UISplitScreenHelpers.h: - GetViewportRect: origin and dimensions for any viewport type - Fit16x9: aspect-correct fitting with centering offsets - ComputeTileScale: uniform scale and Y-offset for tile rendering - ComputeSplitContentOffset: content centering for overlay components
This commit is contained in:
parent
8c3eaff0f4
commit
7cd990eefb
|
|
@ -481,25 +481,15 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
if (!g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
if (iPad == 0 && !g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
{
|
{
|
||||||
int deltaX = g_KBMInput.GetMouseDeltaX();
|
int deltaX = g_KBMInput.GetMouseDeltaX();
|
||||||
int deltaY = g_KBMInput.GetMouseDeltaY();
|
int deltaY = g_KBMInput.GetMouseDeltaY();
|
||||||
|
|
||||||
extern HWND g_hWnd;
|
float scaleX, scaleY;
|
||||||
RECT rc;
|
getMouseToSWFScale(scaleX, scaleY);
|
||||||
GetClientRect(g_hWnd, &rc);
|
|
||||||
int winW = rc.right - rc.left;
|
|
||||||
int winH = rc.bottom - rc.top;
|
|
||||||
|
|
||||||
if (winW > 0 && winH > 0)
|
|
||||||
{
|
|
||||||
float scaleX = (float)getMovieWidth() / (float)winW;
|
|
||||||
float scaleY = (float)getMovieHeight() / (float)winH;
|
|
||||||
|
|
||||||
vPointerPos.x += (float)deltaX * scaleX;
|
vPointerPos.x += (float)deltaX * scaleX;
|
||||||
vPointerPos.y += (float)deltaY * scaleY;
|
vPointerPos.y += (float)deltaY * scaleY;
|
||||||
}
|
|
||||||
|
|
||||||
if (deltaX != 0 || deltaY != 0)
|
if (deltaX != 0 || deltaY != 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -277,4 +277,5 @@ public:
|
||||||
virtual int getPad() = 0;
|
virtual int getPad() = 0;
|
||||||
virtual int getMovieWidth() = 0;
|
virtual int getMovieWidth() = 0;
|
||||||
virtual int getMovieHeight() = 0;
|
virtual int getMovieHeight() = 0;
|
||||||
|
virtual void getMouseToSWFScale(float &scaleX, float &scaleY) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIComponent_Chat.h"
|
#include "UIComponent_Chat.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
#include "..\..\Minecraft.h"
|
#include "..\..\Minecraft.h"
|
||||||
#include "..\..\Gui.h"
|
#include "..\..\Gui.h"
|
||||||
|
|
||||||
|
|
@ -114,6 +115,7 @@ void UIComponent_Chat::render(S32 width, S32 height, C4JRender::eViewportType vi
|
||||||
S32 tileWidth = width;
|
S32 tileWidth = width;
|
||||||
S32 tileHeight = height;
|
S32 tileHeight = height;
|
||||||
|
|
||||||
|
bool needsYTile = false;
|
||||||
switch( viewport )
|
switch( viewport )
|
||||||
{
|
{
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
|
@ -121,22 +123,27 @@ void UIComponent_Chat::render(S32 width, S32 height, C4JRender::eViewportType vi
|
||||||
tileHeight = (S32)(ui.getScreenHeight());
|
tileHeight = (S32)(ui.getScreenHeight());
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
|
||||||
break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IggyPlayerSetDisplaySize( getMovie(), m_movieWidth, m_movieHeight );
|
F32 scale;
|
||||||
|
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
|
S32 contentOffX, contentOffY;
|
||||||
|
ComputeSplitContentOffset(viewport, m_movieWidth, m_movieHeight, scale, tileWidth, tileHeight, tileYStart, contentOffX, contentOffY);
|
||||||
|
xPos += contentOffX;
|
||||||
|
yPos += contentOffY;
|
||||||
|
ui.setupRenderPosition(xPos, yPos);
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,21 +68,26 @@ void UIComponent_MenuBackground::render(S32 width, S32 height, C4JRender::eViewp
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
tileYStart = (S32)(ui.getScreenHeight() / 2);
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
tileYStart = (S32)(ui.getScreenHeight() / 2);
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
tileYStart = (S32)(ui.getScreenHeight() / 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IggyPlayerSetDisplaySize( getMovie(), m_movieWidth, m_movieHeight );
|
F32 scaleW = (F32)(tileXStart + tileWidth) / (F32)m_movieWidth;
|
||||||
|
F32 scaleH = (F32)(tileYStart + tileHeight) / (F32)m_movieHeight;
|
||||||
|
F32 scale = (scaleW > scaleH) ? scaleW : scaleH;
|
||||||
|
if(scale < 1.0f) scale = 1.0f;
|
||||||
|
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
@ -98,6 +103,10 @@ void UIComponent_MenuBackground::render(S32 width, S32 height, C4JRender::eViewp
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UIScene::render(width, height, viewport);
|
if(m_bIsReloading) return;
|
||||||
|
if(!m_hasTickedOnce || !getMovie()) return;
|
||||||
|
ui.setupRenderPosition(0, 0);
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)ui.getScreenWidth(), (S32)ui.getScreenHeight() );
|
||||||
|
IggyPlayerDraw( getMovie() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,15 +93,27 @@ void UIComponent_Panorama::render(S32 width, S32 height, C4JRender::eViewportTyp
|
||||||
}
|
}
|
||||||
ui.setupRenderPosition(xPos, yPos);
|
ui.setupRenderPosition(xPos, yPos);
|
||||||
|
|
||||||
if((viewport == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT) || (viewport == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT))
|
|
||||||
{
|
|
||||||
// Need to render at full height, but only the left side of the scene
|
|
||||||
S32 tileXStart = 0;
|
S32 tileXStart = 0;
|
||||||
S32 tileYStart = 0;
|
S32 tileYStart = 0;
|
||||||
S32 tileWidth = width;
|
S32 tileWidth = width;
|
||||||
S32 tileHeight = (S32)(ui.getScreenHeight());
|
S32 tileHeight = height;
|
||||||
|
|
||||||
IggyPlayerSetDisplaySize( getMovie(), m_movieWidth, m_movieHeight );
|
if((viewport == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT) || (viewport == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT))
|
||||||
|
{
|
||||||
|
tileHeight = (S32)(ui.getScreenHeight());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
|
tileYStart = (S32)(ui.getScreenHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 scaleW = (F32)(tileXStart + tileWidth) / (F32)m_movieWidth;
|
||||||
|
F32 scaleH = (F32)(tileYStart + tileHeight) / (F32)m_movieHeight;
|
||||||
|
F32 scale = (scaleW > scaleH) ? scaleW : scaleH;
|
||||||
|
if(scale < 1.0f) scale = 1.0f;
|
||||||
|
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
@ -117,16 +129,13 @@ void UIComponent_Panorama::render(S32 width, S32 height, C4JRender::eViewportTyp
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Need to render at full height, and full width. But compressed into the viewport
|
if(m_bIsReloading) return;
|
||||||
IggyPlayerSetDisplaySize( getMovie(), ui.getScreenWidth(), ui.getScreenHeight()/2 );
|
if(!m_hasTickedOnce || !getMovie()) return;
|
||||||
|
ui.setupRenderPosition(0, 0);
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)ui.getScreenWidth(), (S32)ui.getScreenHeight() );
|
||||||
IggyPlayerDraw( getMovie() );
|
IggyPlayerDraw( getMovie() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
UIScene::render(width, height, viewport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UIComponent_Panorama::setPanorama(bool isDay)
|
void UIComponent_Panorama::setPanorama(bool isDay)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIComponent_Tooltips.h"
|
#include "UIComponent_Tooltips.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
|
|
||||||
UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||||
{
|
{
|
||||||
|
|
@ -224,6 +225,7 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
|
||||||
S32 tileWidth = width;
|
S32 tileWidth = width;
|
||||||
S32 tileHeight = height;
|
S32 tileHeight = height;
|
||||||
|
|
||||||
|
bool needsYTile = false;
|
||||||
switch( viewport )
|
switch( viewport )
|
||||||
{
|
{
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
|
@ -231,22 +233,27 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
|
||||||
tileHeight = (S32)(ui.getScreenHeight());
|
tileHeight = (S32)(ui.getScreenHeight());
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
|
||||||
break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IggyPlayerSetDisplaySize( getMovie(), m_movieWidth, m_movieHeight );
|
F32 scale;
|
||||||
|
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
|
S32 contentOffX, contentOffY;
|
||||||
|
ComputeSplitContentOffset(viewport, m_movieWidth, m_movieHeight, scale, tileWidth, tileHeight, tileYStart, contentOffX, contentOffY);
|
||||||
|
xPos += contentOffX;
|
||||||
|
yPos += contentOffY;
|
||||||
|
ui.setupRenderPosition(xPos, yPos);
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "..\..\EnderDragonRenderer.h"
|
#include "..\..\EnderDragonRenderer.h"
|
||||||
#include "..\..\MultiPlayerLocalPlayer.h"
|
#include "..\..\MultiPlayerLocalPlayer.h"
|
||||||
#include "UIFontData.h"
|
#include "UIFontData.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
#include "..\..\Windows64\KeyboardMouseInput.h"
|
#include "..\..\Windows64\KeyboardMouseInput.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -57,6 +58,8 @@ bool UIController::ms_bReloadSkinCSInitialised = false;
|
||||||
|
|
||||||
DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME;
|
DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME;
|
||||||
|
|
||||||
|
// GetViewportRect and Fit16x9 are now in UISplitScreenHelpers.h
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
static UIControl_Slider *FindSliderById(UIScene *pScene, int sliderId)
|
static UIControl_Slider *FindSliderById(UIScene *pScene, int sliderId)
|
||||||
{
|
{
|
||||||
|
|
@ -854,28 +857,15 @@ void UIController::tickInput()
|
||||||
S32 displayW = 0, displayH = 0;
|
S32 displayW = 0, displayH = 0;
|
||||||
getRenderDimensions(vp, displayW, displayH);
|
getRenderDimensions(vp, displayW, displayH);
|
||||||
|
|
||||||
S32 originX = 0, originY = 0;
|
F32 vpOriginX, vpOriginY, vpW, vpH;
|
||||||
switch (vp)
|
GetViewportRect(getScreenWidth(), getScreenHeight(), vp, vpOriginX, vpOriginY, vpW, vpH);
|
||||||
{
|
// All viewports use Fit16x9 for menu scenes
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
S32 fitW, fitH, fitOffsetX, fitOffsetY;
|
||||||
originX = (S32)(getScreenWidth() / 4); break;
|
Fit16x9(vpW, vpH, fitW, fitH, fitOffsetX, fitOffsetY);
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
S32 originX = (S32)vpOriginX + fitOffsetX;
|
||||||
originX = (S32)(getScreenWidth() / 4);
|
S32 originY = (S32)vpOriginY + fitOffsetY;
|
||||||
originY = (S32)(getScreenHeight() / 2); break;
|
displayW = fitW;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
displayH = fitH;
|
||||||
originY = (S32)(getScreenHeight() / 4); break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
|
||||||
originX = (S32)(getScreenWidth() / 2);
|
|
||||||
originY = (S32)(getScreenHeight() / 4); break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
|
||||||
originX = (S32)(getScreenWidth() / 2); break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
|
||||||
originY = (S32)(getScreenHeight() / 2); break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
|
||||||
originX = (S32)(getScreenWidth() / 2);
|
|
||||||
originY = (S32)(getScreenHeight() / 2); break;
|
|
||||||
default: break; // FULLSCREEN and QUADRANT_TOP_LEFT: origin (0,0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (displayW > 0 && displayH > 0)
|
if (displayW > 0 && displayH > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1609,74 +1599,48 @@ void UIController::renderScenes()
|
||||||
|
|
||||||
void UIController::getRenderDimensions(C4JRender::eViewportType viewport, S32 &width, S32 &height)
|
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:
|
S32 offsetX, offsetY;
|
||||||
width = (S32)(getScreenWidth());
|
Fit16x9(viewW, viewH, width, height, offsetX, offsetY);
|
||||||
height = (S32)(getScreenHeight());
|
}
|
||||||
break;
|
else
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
{
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
// Split-screen: use raw viewport dims — the SWF tiling code handles non-16:9
|
||||||
width = (S32)(getScreenWidth() / 2);
|
width = (S32)viewW;
|
||||||
height = (S32)(getScreenHeight() / 2);
|
height = (S32)viewH;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIController::setupRenderPosition(C4JRender::eViewportType viewport)
|
void UIController::setupRenderPosition(C4JRender::eViewportType viewport)
|
||||||
{
|
|
||||||
if(m_bCustomRenderPosition || m_currentRenderViewport != viewport)
|
|
||||||
{
|
{
|
||||||
m_currentRenderViewport = viewport;
|
m_currentRenderViewport = viewport;
|
||||||
m_bCustomRenderPosition = false;
|
m_bCustomRenderPosition = false;
|
||||||
S32 xPos = 0;
|
|
||||||
S32 yPos = 0;
|
F32 vpOriginX, vpOriginY, vpW, vpH;
|
||||||
switch( viewport )
|
GetViewportRect(getScreenWidth(), getScreenHeight(), viewport, vpOriginX, vpOriginY, vpW, vpH);
|
||||||
|
|
||||||
|
S32 xPos, yPos;
|
||||||
|
if(viewport == C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||||
{
|
{
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
S32 fitW, fitH, fitOffsetX, fitOffsetY;
|
||||||
xPos = (S32)(getScreenWidth() / 4);
|
Fit16x9(vpW, vpH, fitW, fitH, fitOffsetX, fitOffsetY);
|
||||||
break;
|
xPos = (S32)vpOriginX + fitOffsetX;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
yPos = (S32)vpOriginY + fitOffsetY;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Split-screen: position at viewport origin, no 16:9 fitting
|
||||||
|
xPos = (S32)vpOriginX;
|
||||||
|
yPos = (S32)vpOriginY;
|
||||||
|
}
|
||||||
|
|
||||||
m_tileOriginX = xPos;
|
m_tileOriginX = xPos;
|
||||||
m_tileOriginY = yPos;
|
m_tileOriginY = yPos;
|
||||||
setTileOrigin(xPos, yPos);
|
setTileOrigin(xPos, yPos);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void UIController::setupRenderPosition(S32 xOrigin, S32 yOrigin)
|
void UIController::setupRenderPosition(S32 xOrigin, S32 yOrigin)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIScene.h"
|
#include "UIScene.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
|
|
||||||
#include "..\..\Lighting.h"
|
#include "..\..\Lighting.h"
|
||||||
#include "..\..\LocalPlayer.h"
|
#include "..\..\LocalPlayer.h"
|
||||||
|
|
@ -685,10 +686,24 @@ void UIScene::render(S32 width, S32 height, C4JRender::eViewportType viewport)
|
||||||
{
|
{
|
||||||
if(m_bIsReloading) return;
|
if(m_bIsReloading) return;
|
||||||
if(!m_hasTickedOnce || !swf) return;
|
if(!m_hasTickedOnce || !swf) return;
|
||||||
|
|
||||||
|
if(viewport != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||||
|
{
|
||||||
|
F32 originX, originY, viewW, viewH;
|
||||||
|
GetViewportRect(ui.getScreenWidth(), ui.getScreenHeight(), viewport, originX, originY, viewW, viewH);
|
||||||
|
S32 fitW, fitH, offsetX, offsetY;
|
||||||
|
Fit16x9(viewW, viewH, fitW, fitH, offsetX, offsetY);
|
||||||
|
ui.setupRenderPosition((S32)originX + offsetX, (S32)originY + offsetY);
|
||||||
|
IggyPlayerSetDisplaySize( swf, fitW, fitH );
|
||||||
|
IggyPlayerDraw( swf );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ui.setupRenderPosition(viewport);
|
ui.setupRenderPosition(viewport);
|
||||||
IggyPlayerSetDisplaySize( swf, width, height );
|
IggyPlayerSetDisplaySize( swf, width, height );
|
||||||
IggyPlayerDraw( swf );
|
IggyPlayerDraw( swf );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UIScene::setOpacity(float percent)
|
void UIScene::setOpacity(float percent)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIScene_AbstractContainerMenu.h"
|
#include "UIScene_AbstractContainerMenu.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
|
|
||||||
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
||||||
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
||||||
|
|
@ -187,6 +188,11 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||||
IggyEvent mouseEvent;
|
IggyEvent mouseEvent;
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
|
|
||||||
|
C4JRender::eViewportType vp = m_parentLayer->getViewport();
|
||||||
|
if(vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||||
|
Fit16x9(width, height);
|
||||||
|
|
||||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
||||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
||||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||||
|
|
@ -212,6 +218,10 @@ void UIScene_AbstractContainerMenu::tick()
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
|
|
||||||
|
C4JRender::eViewportType vp = m_parentLayer->getViewport();
|
||||||
|
if(vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||||
|
Fit16x9(width, height);
|
||||||
|
|
||||||
S32 x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
S32 x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
||||||
S32 y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
S32 y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
||||||
|
|
||||||
|
|
@ -251,6 +261,27 @@ void UIScene_AbstractContainerMenu::render(S32 width, S32 height, C4JRender::eVi
|
||||||
m_needsCacheRendered = false;
|
m_needsCacheRendered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIScene_AbstractContainerMenu::getMouseToSWFScale(float &scaleX, float &scaleY)
|
||||||
|
{
|
||||||
|
extern HWND g_hWnd;
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(g_hWnd, &rc);
|
||||||
|
int winW = rc.right - rc.left;
|
||||||
|
int winH = rc.bottom - rc.top;
|
||||||
|
if(winW <= 0 || winH <= 0) { scaleX = 1.0f; scaleY = 1.0f; return; }
|
||||||
|
|
||||||
|
S32 renderW, renderH;
|
||||||
|
C4JRender::eViewportType vp = GetParentLayer()->getViewport();
|
||||||
|
ui.getRenderDimensions(vp, renderW, renderH);
|
||||||
|
if(vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||||
|
Fit16x9(renderW, renderH);
|
||||||
|
|
||||||
|
float screenW = (float)ui.getScreenWidth();
|
||||||
|
float screenH = (float)ui.getScreenHeight();
|
||||||
|
scaleX = (float)m_movieWidth * screenW / ((float)renderW * (float)winW);
|
||||||
|
scaleY = (float)m_movieHeight * screenH / ((float)renderH * (float)winH);
|
||||||
|
}
|
||||||
|
|
||||||
void UIScene_AbstractContainerMenu::customDraw(IggyCustomDrawCallbackRegion *region)
|
void UIScene_AbstractContainerMenu::customDraw(IggyCustomDrawCallbackRegion *region)
|
||||||
{
|
{
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ public:
|
||||||
int getPad() { return m_iPad; }
|
int getPad() { return m_iPad; }
|
||||||
int getMovieWidth() { return m_movieWidth; }
|
int getMovieWidth() { return m_movieWidth; }
|
||||||
int getMovieHeight() { return m_movieHeight; }
|
int getMovieHeight() { return m_movieHeight; }
|
||||||
|
void getMouseToSWFScale(float &scaleX, float &scaleY);
|
||||||
bool getIgnoreInput() { return m_bIgnoreInput; }
|
bool getIgnoreInput() { return m_bIgnoreInput; }
|
||||||
void setIgnoreInput(bool bVal) { m_bIgnoreInput=bVal; }
|
void setIgnoreInput(bool bVal) { m_bIgnoreInput=bVal; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIScene_HUD.h"
|
#include "UIScene_HUD.h"
|
||||||
|
#include "UISplitScreenHelpers.h"
|
||||||
#include "BossMobGuiInfo.h"
|
#include "BossMobGuiInfo.h"
|
||||||
#include "..\..\Minecraft.h"
|
#include "..\..\Minecraft.h"
|
||||||
#include "..\..\MultiplayerLocalPlayer.h"
|
#include "..\..\MultiplayerLocalPlayer.h"
|
||||||
|
|
@ -266,8 +267,6 @@ void UIScene_HUD::handleReload()
|
||||||
|
|
||||||
SetDisplayName(ProfileManager.GetDisplayName(m_iPad));
|
SetDisplayName(ProfileManager.GetDisplayName(m_iPad));
|
||||||
|
|
||||||
repositionHud();
|
|
||||||
|
|
||||||
SetTooltipsEnabled(((ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad())) || (app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Tooltips) != 0)));
|
SetTooltipsEnabled(((ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad())) || (app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Tooltips) != 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,6 +696,7 @@ void UIScene_HUD::render(S32 width, S32 height, C4JRender::eViewportType viewpor
|
||||||
S32 tileWidth = width;
|
S32 tileWidth = width;
|
||||||
S32 tileHeight = height;
|
S32 tileHeight = height;
|
||||||
|
|
||||||
|
bool needsYTile = false;
|
||||||
switch( viewport )
|
switch( viewport )
|
||||||
{
|
{
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
|
@ -704,22 +704,24 @@ void UIScene_HUD::render(S32 width, S32 height, C4JRender::eViewportType viewpor
|
||||||
tileHeight = (S32)(ui.getScreenHeight());
|
tileHeight = (S32)(ui.getScreenHeight());
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
|
||||||
break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
tileWidth = (S32)(ui.getScreenWidth());
|
tileWidth = (S32)(ui.getScreenWidth());
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
tileYStart = (S32)(m_movieHeight / 2);
|
needsYTile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IggyPlayerSetDisplaySize( getMovie(), m_movieWidth, m_movieHeight );
|
F32 scale;
|
||||||
|
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
||||||
|
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
|
repositionHud(tileWidth, tileHeight, scale);
|
||||||
|
|
||||||
m_renderWidth = tileWidth;
|
m_renderWidth = tileWidth;
|
||||||
m_renderHeight = tileHeight;
|
m_renderHeight = tileHeight;
|
||||||
|
|
@ -784,34 +786,24 @@ void UIScene_HUD::handleTimerComplete(int id)
|
||||||
//setVisible(anyVisible);
|
//setVisible(anyVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIScene_HUD::repositionHud()
|
void UIScene_HUD::repositionHud(S32 tileWidth, S32 tileHeight, F32 scale)
|
||||||
{
|
{
|
||||||
if(!m_bSplitscreen) return;
|
if(!m_bSplitscreen) return;
|
||||||
|
|
||||||
S32 width = 0;
|
// Pass the visible tile area in SWF coordinates so ActionScript
|
||||||
S32 height = 0;
|
// positions elements (crosshair, hotbar, etc.) centered in the
|
||||||
m_parentLayer->getRenderDimensions( width, height );
|
// actually visible region, not the raw viewport.
|
||||||
|
S32 visibleW = (S32)(tileWidth / scale);
|
||||||
|
S32 visibleH = (S32)(tileHeight / scale);
|
||||||
|
|
||||||
switch( m_parentLayer->getViewport() )
|
app.DebugPrintf(app.USER_SR, "Reposition HUD: tile %dx%d, scale %.3f, visible SWF %dx%d\n", tileWidth, tileHeight, scale, visibleW, visibleH );
|
||||||
{
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
|
||||||
height = (S32)(ui.getScreenHeight());
|
|
||||||
break;
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
|
||||||
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
|
||||||
width = (S32)(ui.getScreenWidth());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.DebugPrintf(app.USER_SR, "Reposition HUD with dims %d, %d\n", width, height );
|
|
||||||
|
|
||||||
IggyDataValue result;
|
IggyDataValue result;
|
||||||
IggyDataValue value[2];
|
IggyDataValue value[2];
|
||||||
value[0].type = IGGY_DATATYPE_number;
|
value[0].type = IGGY_DATATYPE_number;
|
||||||
value[0].number = width;
|
value[0].number = visibleW;
|
||||||
value[1].type = IGGY_DATATYPE_number;
|
value[1].type = IGGY_DATATYPE_number;
|
||||||
value[1].number = height;
|
value[1].number = visibleH;
|
||||||
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcRepositionHud , 2 , value );
|
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcRepositionHud , 2 , value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,5 +176,5 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void repositionHud();
|
void repositionHud(S32 tileWidth, S32 tileHeight, F32 scale);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
114
Minecraft.Client/Common/UI/UISplitScreenHelpers.h
Normal file
114
Minecraft.Client/Common/UI/UISplitScreenHelpers.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Shared split-screen UI helpers to avoid duplicating viewport math
|
||||||
|
// across HUD, Chat, Tooltips, and container menus.
|
||||||
|
|
||||||
|
// Compute the raw viewport rectangle for a given viewport type.
|
||||||
|
inline void GetViewportRect(F32 screenW, F32 screenH, C4JRender::eViewportType viewport,
|
||||||
|
F32 &originX, F32 &originY, F32 &viewW, F32 &viewH)
|
||||||
|
{
|
||||||
|
originX = originY = 0;
|
||||||
|
viewW = screenW;
|
||||||
|
viewH = screenH;
|
||||||
|
switch(viewport)
|
||||||
|
{
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
|
viewH = screenH * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
|
originY = screenH * 0.5f; viewH = screenH * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
viewW = screenW * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
||||||
|
originX = screenW * 0.5f; viewW = screenW * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
|
viewW = screenW * 0.5f; viewH = screenH * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
|
originX = screenW * 0.5f; viewW = screenW * 0.5f; viewH = screenH * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
|
originY = screenH * 0.5f; viewW = screenW * 0.5f; viewH = screenH * 0.5f; break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
|
originX = screenW * 0.5f; originY = screenH * 0.5f;
|
||||||
|
viewW = screenW * 0.5f; viewH = screenH * 0.5f; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fit a 16:9 rectangle inside the given dimensions.
|
||||||
|
inline void Fit16x9(F32 viewW, F32 viewH, S32 &fitW, S32 &fitH, S32 &offsetX, S32 &offsetY)
|
||||||
|
{
|
||||||
|
const F32 kAspect = 16.0f / 9.0f;
|
||||||
|
if(viewW / viewH > kAspect)
|
||||||
|
{
|
||||||
|
fitH = (S32)viewH;
|
||||||
|
fitW = (S32)(viewH * kAspect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fitW = (S32)viewW;
|
||||||
|
fitH = (S32)(viewW / kAspect);
|
||||||
|
}
|
||||||
|
offsetX = (S32)((viewW - fitW) * 0.5f);
|
||||||
|
offsetY = (S32)((viewH - fitH) * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience: just fit 16:9 dimensions, ignore offsets.
|
||||||
|
inline void Fit16x9(S32 &width, S32 &height)
|
||||||
|
{
|
||||||
|
S32 offX, offY;
|
||||||
|
Fit16x9((F32)width, (F32)height, width, height, offX, offY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the uniform scale and tileYStart for split-screen tile rendering.
|
||||||
|
// Used by HUD, Chat, and Tooltips to scale the SWF movie to cover the viewport tile.
|
||||||
|
inline void ComputeTileScale(S32 tileWidth, S32 tileHeight, S32 movieWidth, S32 movieHeight,
|
||||||
|
bool needsYTile, F32 &outScale, S32 &outTileYStart)
|
||||||
|
{
|
||||||
|
F32 scaleW = (F32)tileWidth / (F32)movieWidth;
|
||||||
|
F32 scaleH = (F32)tileHeight / (F32)movieHeight;
|
||||||
|
F32 scale = (scaleW > scaleH) ? scaleW : scaleH;
|
||||||
|
if(scale < 1.0f) scale = 1.0f;
|
||||||
|
|
||||||
|
outTileYStart = 0;
|
||||||
|
if(needsYTile)
|
||||||
|
{
|
||||||
|
S32 dispH = (S32)(movieHeight * scale);
|
||||||
|
outTileYStart = dispH - tileHeight;
|
||||||
|
if(outTileYStart < 0) outTileYStart = 0;
|
||||||
|
scaleH = (F32)(outTileYStart + tileHeight) / (F32)movieHeight;
|
||||||
|
scale = (scaleW > scaleH) ? scaleW : scaleH;
|
||||||
|
if(scale < 1.0f) scale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
outScale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the render offset to center split-screen SWF content in the viewport.
|
||||||
|
// Used by Chat and Tooltips (HUD uses repositionHud instead).
|
||||||
|
inline void ComputeSplitContentOffset(C4JRender::eViewportType viewport, S32 movieWidth, S32 movieHeight,
|
||||||
|
F32 scale, S32 tileWidth, S32 tileHeight, S32 tileYStart,
|
||||||
|
S32 &outXOffset, S32 &outYOffset)
|
||||||
|
{
|
||||||
|
S32 contentCenterX, contentCenterY;
|
||||||
|
if(viewport == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT || viewport == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT)
|
||||||
|
{
|
||||||
|
contentCenterX = (S32)(movieWidth * scale / 4);
|
||||||
|
contentCenterY = (S32)(movieHeight * scale / 2);
|
||||||
|
}
|
||||||
|
else if(viewport == C4JRender::VIEWPORT_TYPE_SPLIT_TOP || viewport == C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM)
|
||||||
|
{
|
||||||
|
contentCenterX = (S32)(movieWidth * scale / 2);
|
||||||
|
contentCenterY = (S32)(movieHeight * scale * 3 / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contentCenterX = (S32)(movieWidth * scale / 4);
|
||||||
|
contentCenterY = (S32)(movieHeight * scale * 3 / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
outXOffset = 0;
|
||||||
|
outYOffset = 0;
|
||||||
|
if(viewport == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT || viewport == C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT || viewport == C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT)
|
||||||
|
outXOffset = -(tileWidth / 2 - contentCenterX);
|
||||||
|
if(viewport == C4JRender::VIEWPORT_TYPE_SPLIT_TOP || viewport == C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT || viewport == C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT)
|
||||||
|
outYOffset = -(tileHeight / 2 - (contentCenterY - tileYStart));
|
||||||
|
}
|
||||||
|
|
@ -960,6 +960,10 @@ void GameRenderer::CachePlayerGammas()
|
||||||
|
|
||||||
bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const
|
bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const
|
||||||
{
|
{
|
||||||
|
// Use the actual backbuffer dimensions, not the game's logical size.
|
||||||
|
extern int g_iScreenWidth;
|
||||||
|
extern int g_iScreenHeight;
|
||||||
|
|
||||||
int active = 0;
|
int active = 0;
|
||||||
int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1};
|
int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1};
|
||||||
for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i)
|
for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i)
|
||||||
|
|
@ -972,8 +976,8 @@ bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport)
|
||||||
{
|
{
|
||||||
outViewport.TopLeftX = 0.0f;
|
outViewport.TopLeftX = 0.0f;
|
||||||
outViewport.TopLeftY = 0.0f;
|
outViewport.TopLeftY = 0.0f;
|
||||||
outViewport.Width = static_cast<FLOAT>(mc->width);
|
outViewport.Width = static_cast<FLOAT>(g_iScreenWidth);
|
||||||
outViewport.Height = static_cast<FLOAT>(mc->height);
|
outViewport.Height = static_cast<FLOAT>(g_iScreenHeight);
|
||||||
outViewport.MinDepth = 0.0f;
|
outViewport.MinDepth = 0.0f;
|
||||||
outViewport.MaxDepth = 1.0f;
|
outViewport.MaxDepth = 1.0f;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -989,8 +993,8 @@ bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport)
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const float width = static_cast<float>(mc->width);
|
const float width = static_cast<float>(g_iScreenWidth);
|
||||||
const float height = static_cast<float>(mc->height);
|
const float height = static_cast<float>(g_iScreenHeight);
|
||||||
|
|
||||||
if (active == 2)
|
if (active == 2)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4590,8 +4590,14 @@ void Minecraft::startAndConnectTo(const wstring& name, const wstring& sid, const
|
||||||
|
|
||||||
Minecraft *minecraft;
|
Minecraft *minecraft;
|
||||||
// 4J - was new Minecraft(frame, canvas, NULL, 854, 480, fullScreen);
|
// 4J - was new Minecraft(frame, canvas, NULL, 854, 480, fullScreen);
|
||||||
|
// Logical width is proportional to the real screen aspect ratio so that
|
||||||
|
// the ortho projection and HUD layout match the viewport without stretching.
|
||||||
|
extern int g_iScreenWidth;
|
||||||
|
extern int g_iScreenHeight;
|
||||||
|
int logicalH = 720;
|
||||||
|
int logicalW = logicalH * g_iScreenWidth / g_iScreenHeight;
|
||||||
|
|
||||||
minecraft = new Minecraft(NULL, NULL, NULL, 1280, 720, fullScreen);
|
minecraft = new Minecraft(NULL, NULL, NULL, logicalW, logicalH, fullScreen);
|
||||||
|
|
||||||
/* - 4J - removed
|
/* - 4J - removed
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -86,12 +86,9 @@ DWORD dwProfileSettingsA[NUM_PROFILE_VALUES]=
|
||||||
|
|
||||||
BOOL g_bWidescreen = TRUE;
|
BOOL g_bWidescreen = TRUE;
|
||||||
|
|
||||||
// DO NOT auto-detect from the monitor (GetSystemMetrics etc.) — the game resolution
|
// Screen resolution — auto-detected from the monitor at startup.
|
||||||
// must stay 1920x1080. The precompiled 4J_Render lib, all Flash SWF assets, and the
|
// The 3D world renders at native resolution; Flash UI is 16:9-fitted and centered
|
||||||
// split-screen viewport math (RenderManager.StateSetViewport, UIController::getRenderDimensions,
|
// within each viewport (pillarboxed on ultrawide, letterboxed on tall displays).
|
||||||
// setupRenderPosition) all assume a 16:9 framebuffer. Using the native monitor resolution
|
|
||||||
// breaks split-screen on ultrawide/non-16:9 displays: the UI renders offset and the
|
|
||||||
// bottom portion of each viewport is left empty.
|
|
||||||
// ApplyScreenMode() can still override these for debug/test resolutions via launch args.
|
// ApplyScreenMode() can still override these for debug/test resolutions via launch args.
|
||||||
int g_iScreenWidth = 1920;
|
int g_iScreenWidth = 1920;
|
||||||
int g_iScreenHeight = 1080;
|
int g_iScreenHeight = 1080;
|
||||||
|
|
@ -1184,8 +1181,10 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||||
if (pSlash) { *(pSlash + 1) = '\0'; SetCurrentDirectoryA(szExeDir); }
|
if (pSlash) { *(pSlash + 1) = '\0'; SetCurrentDirectoryA(szExeDir); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare DPI awareness so pixel coordinates are consistent
|
// Declare DPI awareness so GetSystemMetrics returns physical pixels
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
|
g_iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
g_iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||||
|
|
||||||
// Load username from username.txt
|
// Load username from username.txt
|
||||||
char exePath[MAX_PATH] = {};
|
char exePath[MAX_PATH] = {};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue