From a5111562982684b0ef08863845f6452c7162fd98 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 25 Sep 2025 12:33:33 -0400 Subject: [PATCH] v3.2.5: adjusted iOS dynamic island handling for buff indicator change --- .../scenes/GameScene.java | 15 +++--------- .../ios/IOSPlatformSupport.java | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 15cdecacd..ffc77e832 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -374,17 +374,8 @@ public class GameScene extends PixelScene { int hpBarMaxWidth = 50; //default max width float buffBarTopRowMaxWidth = 55; //default max width if (largeInsetTop == 0 && insets.top > 0){ - //iOS's Dynamic island badly obstructs the first buff bar row - if (DeviceCompat.isiOS()){ - //TODO bad to hardcode and approximate this atm - // need to change this so iOS platformsupport returns cutout dimensions - // which would also help with detecting if the cutout is big enough to put into 2nd row =S - //note that the island is a bit smaller in terms of screen % on bigger iPhones - // we try to average that a bit here - float cutoutLeft = (Game.width*0.34f)/defaultZoom; - buffBarTopRowMaxWidth = Math.min(55, cutoutLeft - 32 + 3); - } else if (DeviceCompat.isAndroid()) { - //Android hole punches are of varying size and may obstruct various UI elements + //smaller non-notch cutouts are of varying size and may obstruct various UI elements + // some are small hole punches, some are huge dynamic islands RectF cutout = Game.platform.getDisplayCutout().scale(1f / defaultZoom); //if the cutout is positioned to obstruct the hero portrait in the status pane if (cutout.top < 30 @@ -417,8 +408,8 @@ public class GameScene extends PixelScene { && cutout.bottom > 11) { //subtract starting position, add a bit back to allow slight overlap buffBarTopRowMaxWidth = cutout.left - 32 + 3; + //TODO dynamic island can block 2nd row too =S } - } } float screentop = largeInsetTop; diff --git a/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java b/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java index 4debb6072..82ad8deef 100644 --- a/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java +++ b/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java @@ -58,6 +58,30 @@ public class IOSPlatformSupport extends PlatformSupport { return Gdx.graphics.getSafeInsetBottom() > 0; } + @Override + public RectF getDisplayCutout() { + int topInset = Gdx.graphics.getSafeInsetTop(); + + //older device with no cutout, or landscape (we ignore cutouts in this case) + if (topInset == 0){ + return new RectF(); + } + + //magic number BS for larger status bar caused by dynamic island + boolean hasDynamicIsland = topInset / Gdx.graphics.getBackBufferScale() >= 51; + + if (!hasDynamicIsland){ + //classic notch, just shrink for the oversized safe are and then return all top. + // this is inaccurate, as there's space left and right, but we don't care + return new RectF(0, 0, Game.width, topInset / 1.2f); + } else { + //we estimate dynamic island as being 130x390 px, 35px from top. + // this is mostly accurate, slightly oversized + RectF cutout = new RectF( Game.width/2 - 195, 35, Game.width/2 + 195, 165); + return cutout; + } + } + @Override public RectF getSafeInsets(int level) { RectF insets = super.getSafeInsets(INSET_ALL);