Add initial AnyAspectRatio support

This commit is contained in:
Fayaz Shaikh 2026-03-03 15:51:00 -05:00
parent 384b9f4445
commit 158881800c
12 changed files with 249 additions and 18 deletions

View file

@ -181,7 +181,9 @@ UIController::UIController()
// 4J Stu - This is a bit of a hack until we change the Minecraft initialisation to store the proper screen size for other platforms
#if defined _WINDOWS64 || defined _DURANGO || defined __ORBIS__
m_fScreenWidth = 1920.0f;
m_fScreenHeight = 1080.0f;
m_fScreenHeight = 1080.0f;\
aar_Width = 1920.0f;
aar_Height = 1080.0f;
m_bScreenWidthSetup = false;
#else
m_fScreenWidth = 1280.0f;
@ -1209,10 +1211,37 @@ void UIController::getRenderDimensions(C4JRender::eViewportType viewport, S32 &w
{
switch( viewport )
{
case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
width = (S32)(getScreenWidth());
height = (S32)(getScreenHeight());
break;
case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
{
// AnyAspectRatio support by Fayaz
// We must clamp the render dimensions to 16:9 so Iggy doesn't stretch content.
float targetAspect = 16.0f / 9.0f;
float currentAspect = aar_Width / aar_Height;
if (currentAspect > targetAspect)
{
// Screen is Ultrawide (Wider than 16:9):
// Lock height to screen, calculate width based on 16:9 ratio
width = (S32)(aar_Height * targetAspect);
height = (S32)aar_Height;
}
else if (currentAspect < targetAspect)
{
// Screen is Tall (Taller than 16:9, e.g. 4:3, 16:10, Steam Deck):
// Lock width to screen, calculate height based on 16:9 ratio
width = (S32)aar_Width;
// Height = Width / 1.777
height = (S32)(aar_Width / targetAspect);
}
else
{
// Standard 16:9: Use actual screen dimensions
width = (S32)aar_Width;
height = (S32)aar_Height;
}
}
break;
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
width = (S32)(getScreenWidth() / 2);
@ -1233,16 +1262,81 @@ void UIController::getRenderDimensions(C4JRender::eViewportType viewport, S32 &w
}
}
// AAR - Handle window resizing by updating the width and height variables
// AAR - Handle window resizing by updating the width and height variables
// AAR - Handle window resizing by updating the width and height variables
void UIController::resize(S32 width, S32 height)
{
// Store the new dimensions
aar_Width = (float)width;
aar_Height = (float)height;
m_fScreenWidth = (float)width;
m_fScreenHeight = (float)height;
// Notify all UIGroups about the resize
for (unsigned int i = 0; i < eUIGroup_COUNT; ++i)
{
if (m_groups[i])
{
m_groups[i]->OnResize(width, height);
}
}
// Force a render position update on next render
m_currentRenderViewport = (C4JRender::eViewportType)-1; // Force recalculation
// Update the Iggy global display if needed
// (Some Iggy versions need global display size updates)
}
void UIController::setupRenderPosition(C4JRender::eViewportType viewport)
{
if(m_bCustomRenderPosition || m_currentRenderViewport != viewport)
// AAR - Force update for fullscreen to ensure offsets are calculated (fix for constructor init issue)
if(m_bCustomRenderPosition || m_currentRenderViewport != viewport || viewport == C4JRender::VIEWPORT_TYPE_FULLSCREEN)
{
m_currentRenderViewport = viewport;
m_bCustomRenderPosition = false;
S32 xPos = 0;
S32 yPos = 0;
switch( viewport )
{
case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
{
// AnyAspectRatio support by Fayaz (related code has AAR prefix)
// Calculate target 16:9 width based on current height
float targetAspect = 16.0f / 9.0f;
float currentAspect = aar_Width / aar_Height;
// Screen is wider than 16:9 (Ultrawide)
if (currentAspect > targetAspect)
{
// find what the width of 16/9 would be at this height
S32 width169 = (S32)(aar_Height * targetAspect);
// Center the UI by setting the width to have the difference of 16/9 width and current width
xPos = (S32)(aar_Width - width169) * 0.5;
yPos = 0;
}
// Screen is taller than 16:9 (like 4:3 or Steam Deck)
else if (currentAspect < targetAspect)
{
// find what the height of 16/9 would be at this width
S32 height169 = (S32)(aar_Width / targetAspect);
// Center the UI by setting the height to have the difference of 16/9 height and current height
xPos = 0;
yPos = (S32)(aar_Height - height169) * -0.5; // 0, 0 is top left, so we need to negate the yPos
}
// Otherwise, assume current aspect ratio is 16:9
else
{
// 16:9 - Fill screen normally (starts at 0,0)
xPos = 0;
yPos = 0;
}
}
break;
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
xPos = (S32)(getScreenWidth() / 4);
break;
@ -1317,7 +1411,7 @@ void UIController::setupCustomDrawGameState()
PIXBeginNamedEvent(0,"Final setup");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, m_fScreenWidth, m_fScreenHeight, 0, 1000, 3000);
glOrtho(0, aar_Width, aar_Height, 0, 1000, 3000); // AAR - Changed to allow resizing
glMatrixMode(GL_MODELVIEW);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1f);
@ -1365,16 +1459,21 @@ void UIController::setupCustomDrawMatrices(UIScene *scene, CustomDrawData *custo
{
m_fScreenWidth=(float)pMinecraft->width_phys;
m_fScreenHeight=(float)pMinecraft->height_phys;
aar_Width = (float)pMinecraft->width_phys;
aar_Height = (float)pMinecraft->height_phys;
m_bScreenWidthSetup = true;
}
}
glLoadIdentity();
glTranslatef(0, 0, -2000);
// Fayaz - Apply the calculated tile origin
glTranslatef((float)m_tileOriginX, (float)m_tileOriginY, 0.0f);
// Iggy translations are based on a double-size target, with the origin in the centre
glTranslatef((m_fScreenWidth + customDrawRegion->mat[(0*4)+3]*m_fScreenWidth)/2,(m_fScreenHeight - customDrawRegion->mat[(1*4)+3]*m_fScreenHeight)/2,0);
glTranslatef((aar_Width + customDrawRegion->mat[(0 * 4) + 3] * aar_Width) / 2, (aar_Height - customDrawRegion->mat[(1 * 4) + 3] * aar_Height) / 2, 0);
// Iggy scales are based on a double-size target
glScalef( (m_fScreenWidth * customDrawRegion->mat[0])/2,(m_fScreenHeight * -customDrawRegion->mat[(1*4) + 1])/2,1.0f);
glScalef((aar_Width * customDrawRegion->mat[0]) / 2, (aar_Height * -customDrawRegion->mat[(1 * 4) + 1]) / 2, 1.0f);
}
void UIController::setupCustomDrawGameStateAndMatrices(UIScene *scene, CustomDrawData *customDrawRegion)

View file

@ -34,6 +34,8 @@ private:
float m_fScreenWidth;
float m_fScreenHeight;
float aar_Width;
float aar_Height;
bool m_bScreenWidthSetup;
S32 m_tileOriginX, m_tileOriginY;
@ -172,6 +174,7 @@ private:
public:
UIController();
void resize(S32 width, S32 height);
#ifdef __PSVITA__
void TouchBoxAdd(UIControl *pControl,UIScene *pUIScene);
bool TouchBoxHit(UIScene *pUIScene,S32 x, S32 y);

View file

@ -333,6 +333,41 @@ bool UIGroup::IsFullscreenGroup()
return m_group == eUIGroup_Fullscreen;
}
void UIGroup::OnResize(S32 width, S32 height)
{
// Update all layers in this group
for (int layer = 0; layer < LAYER_COUNT; ++layer)
{
if (m_layers[layer])
{
m_layers[layer]->OnResize();
}
}
//// Update HUD if it exists
//if (m_hud)
//{
// m_hud->OnResize();
//}
//// Update tooltips if they exist
//if (m_tooltips)
//{
// m_tooltips->OnResize();
//}
//// Update tutorial popup if it exists
//if (m_tutorialPopup)
//{
// m_tutorialPopup->OnResize();
//}
//// Update press start to play if it exists
//if (m_pressStartToPlay)
//{
// m_pressStartToPlay->OnResize();
//}
}
void UIGroup::handleUnlockFullVersion()
{

View file

@ -101,6 +101,10 @@ public:
bool IsFullscreenGroup();
void handleUnlockFullVersion();
void OnResize(S32 width, S32 height);
static const int LAYER_COUNT = eUILayer_COUNT;
void PrintTotalMemoryUsage(__int64 &totalStatic, __int64 &totalDynamic);

View file

@ -872,6 +872,35 @@ C4JRender::eViewportType UILayer::getViewport()
return m_parentGroup->GetViewportType();
}
void UILayer::OnResize()
{
// Update all components
for (auto component : m_components)
{
if (component)
{
component->OnResize();
}
}
// Update all scenes in the stack
for (auto scene : m_sceneStack)
{
if (scene)
{
scene->OnResize();
}
}
// Update any scenes pending deletion
for (auto scene : m_scenesToDelete)
{
if (scene)
{
scene->OnResize();
}
}
}
void UILayer::handleUnlockFullVersion()
{

View file

@ -34,7 +34,7 @@ public:
UIGroup *m_parentGroup;
public:
UILayer(UIGroup *parent);
void UILayer::OnResize();
void tick();
void render(S32 width, S32 height, C4JRender::eViewportType viewport);
void getRenderDimensions(S32 &width, S32 &height);

View file

@ -1199,6 +1199,46 @@ void UIScene::_handleFocusChange(F64 controlId, F64 childId)
ui.PlayUISFX(eSFX_Focus);
}
void UIScene::OnResize()
{
if (!swf)
{
return;
}
// Update the Iggy player with new display size
S32 width, height;
m_parentLayer->getRenderDimensions(width, height);
IggyPlayerSetDisplaySize(swf, width, height);
// Update safe zone
updateSafeZone();
// Notify the Flash movie about resize (if it has a resize handler)
IggyDataValue result;
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result,
IggyPlayerRootPath(getMovie()),
registerFastName(L"OnResize"),
0, NULL);
// Force a redraw of cached content
m_needsCacheRendered = true;
}
void UIScene::UpdateDisplaySize()
{
if (!swf)
{
return;
}
S32 width, height;
m_parentLayer->getRenderDimensions(width, height);
IggyPlayerSetDisplaySize(swf, width, height);
updateSafeZone();
}
void UIScene::_handleInitFocus(F64 controlId, F64 childId)
{
m_iFocusControl = (int)controlId;

View file

@ -122,6 +122,8 @@ protected:
virtual bool mapElementsAndNames();
void initialiseMovie();
void loadMovie();
virtual void OnResize();
virtual void UpdateDisplaySize();
private:
void getDebugMemoryUseRecursive(const wstring &moviePath, IggyMemoryUseInfo &memoryInfo);

View file

@ -973,6 +973,9 @@ void gdraw_D3D1X_(SetRendertargetSize)(S32 w, S32 h)
void gdraw_D3D1X_(SetTileOrigin)(ID3D1X(RenderTargetView) *main_rt, ID3D1X(DepthStencilView) *main_ds, ID3D1X(ShaderResourceView) *non_msaa_rt, S32 x, S32 y)
{
if (!gdraw) return; // AAR - saftey check because windows calls resize early
D3D1X_(RENDER_TARGET_VIEW_DESC) desc;
if (gdraw->frame_done) {

View file

@ -85,13 +85,24 @@ BOOL g_bWidescreen = TRUE;
int g_iScreenWidth = 1920;
int g_iScreenHeight = 1080;
UINT g_ScreenWidth = 1920;
UINT g_ScreenHeight = 1080;
float g_iAspectRatio = (float)g_iScreenWidth / (float)g_iScreenHeight;
// Fullscreen toggle state
static bool g_isFullscreen = false;
static WINDOWPLACEMENT g_wpPrev = { sizeof(g_wpPrev) };
//--------------------------------------------------------------------------------------
// Update the Aspect Ratio to support Any Aspect Ratio
//--------------------------------------------------------------------------------------
void UpdateAspectRatio(int width, int height)
{
g_iAspectRatio = (float)width / (float)height;
// printf("Window resized to: %d x %d, aspect ratio: %.2f\n", width, height, g_iAspectRatio);
// Update the UI components as well
ui.resize(width, height);
}
void DefineActions(void)
{
// The app needs to define the actions required, and the possible mappings for these
@ -320,6 +331,7 @@ ID3D11Texture2D* g_pDepthStencilBuffer = NULL;
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
// WM_SIZE - handle resizing logic to support Any Aspect Ratio
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
@ -429,6 +441,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_SIZE:
{
UpdateAspectRatio(LOWORD(lParam), HIWORD(lParam));
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
@ -563,7 +580,7 @@ HRESULT InitDevice()
//app.DebugPrintf("width: %d, height: %d\n", width, height);
width = g_iScreenWidth;
height = g_iScreenHeight;
app.DebugPrintf("width: %d, height: %d\n", width, height);
//app.DebugPrintf("width: %d, height: %d\n", width, height);
UINT createDeviceFlags = 0;
#ifdef _DEBUG

View file

@ -9,6 +9,7 @@
ConsoleUIController ui;
void ConsoleUIController::init(ID3D11Device *dev, ID3D11DeviceContext *ctx, ID3D11RenderTargetView* pRenderTargetView, ID3D11DepthStencilView* pDepthStencilView, S32 w, S32 h)
{
#ifdef _ENABLEIGGY

View file

@ -48,13 +48,11 @@ void glLoadIdentity()
RenderManager.MatrixSetIdentity();
}
extern int g_iScreenWidth;
extern int g_iScreenHeight;
// AAR - Use calculated aspect ratio to support dynamic resizing
extern float g_iAspectRatio;
void gluPerspective(float fovy, float aspect, float zNear, float zFar)
{
float dynamicAspect = (float)g_iScreenWidth / (float)g_iScreenHeight;
RenderManager.MatrixPerspective(fovy, dynamicAspect, zNear, zFar);
RenderManager.MatrixPerspective(fovy, g_iAspectRatio, zNear, zFar);
}
void glOrtho(float left,float right,float bottom,float top,float zNear,float zFar)