[Scummvm-git-logs] scummvm master -> 110a7773bffd0d598d48ce712a5b59160172d092
larsamannen
noreply at scummvm.org
Sun Jul 13 15:26:47 UTC 2025
This automated email contains information about 16 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
be80eedd91 COMMON: Make getOverlayHeight and getOverlayWidth constant
041ea90892 COMMON: Add getSafeOverlayArea as OSystem function
790aa75dd7 COMMON: Add constraining functions to Rect
d3121b0320 BACKENDS: Implement safe area handling in WindowedGraphicsManager
336aedaf3e GUI: Take safe insets into account
17085b9ad2 IOS7: Implement getSafeAreaInsets
68c27f907a ANDROID: Implement getSafeAreaInsets
908c7f7326 GUI: Remove useless sizing
7ddb851e41 GUI: Handle safe area in about dialog
dee1a77335 GUI: Handle safe area in console
9a158af369 GUI: Handle safe area in message dialogs
5e2828b4ae GUI: Handle safe area in text viewer dialog
0304c15ff6 GUI: Handle safe area in updates dialog
4f14363146 IOS7: Remove adjustment of virtual game controller
fd867964ab IOS7: Increase the margin for on-screen control buttons
110a7773bf GUI: Handle safe area in popup dialogs
Commit: be80eedd91ad1289c8f8a4cfffa8e5533e3a86b3
https://github.com/scummvm/scummvm/commit/be80eedd91ad1289c8f8a4cfffa8e5533e3a86b3
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
COMMON: Make getOverlayHeight and getOverlayWidth constant
This is cleaner and may allow some optimizations.
This was also already the case for modular graphics backends.
Changed paths:
backends/modular-backend.cpp
backends/modular-backend.h
backends/platform/3ds/osystem-graphics.cpp
backends/platform/3ds/osystem.h
backends/platform/dc/dc.h
backends/platform/dc/display.cpp
backends/platform/ds/ds-graphics.cpp
backends/platform/ds/osystem_ds.h
backends/platform/n64/osys_n64.h
backends/platform/n64/osys_n64_base.cpp
backends/platform/psp/osys_psp.cpp
backends/platform/psp/osys_psp.h
backends/platform/wii/osystem.h
backends/platform/wii/osystem_gfx.cpp
common/system.h
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 68cae30c7a0..8ecc94277a8 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -245,11 +245,11 @@ void ModularGraphicsBackend::copyRectToOverlay(const void *buf, int pitch, int x
_graphicsManager->copyRectToOverlay(buf, pitch, x, y, w, h);
}
-int16 ModularGraphicsBackend::getOverlayHeight() {
+int16 ModularGraphicsBackend::getOverlayHeight() const {
return _graphicsManager->getOverlayHeight();
}
-int16 ModularGraphicsBackend::getOverlayWidth() {
+int16 ModularGraphicsBackend::getOverlayWidth() const {
return _graphicsManager->getOverlayWidth();
}
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 0b13a155e4d..ad0146bd38f 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -116,8 +116,8 @@ public:
void clearOverlay() override final;
void grabOverlay(Graphics::Surface &surface) override final;
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override final;
- int16 getOverlayHeight() override final;
- int16 getOverlayWidth() override final;
+ int16 getOverlayHeight() const override final;
+ int16 getOverlayWidth() const override final;
float getHiDPIScreenFactor() const override final;
diff --git a/backends/platform/3ds/osystem-graphics.cpp b/backends/platform/3ds/osystem-graphics.cpp
index c3488f5d017..f7ca8f1d8f9 100644
--- a/backends/platform/3ds/osystem-graphics.cpp
+++ b/backends/platform/3ds/osystem-graphics.cpp
@@ -746,11 +746,11 @@ void OSystem_3DS::displayActivityIconOnOSD(const Graphics::Surface *icon) {
}
}
-int16 OSystem_3DS::getOverlayHeight() {
+int16 OSystem_3DS::getOverlayHeight() const {
return 240;
}
-int16 OSystem_3DS::getOverlayWidth() {
+int16 OSystem_3DS::getOverlayWidth() const {
return _screen == kScreenTop ? 400 : 320;
}
diff --git a/backends/platform/3ds/osystem.h b/backends/platform/3ds/osystem.h
index 6a53d51940b..75bf21bf644 100644
--- a/backends/platform/3ds/osystem.h
+++ b/backends/platform/3ds/osystem.h
@@ -172,8 +172,8 @@ public:
void grabOverlay(Graphics::Surface &surface);
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w,
int h);
- virtual int16 getOverlayHeight();
- virtual int16 getOverlayWidth();
+ virtual int16 getOverlayHeight() const;
+ virtual int16 getOverlayWidth() const;
void displayMessageOnOSD(const Common::U32String &msg) override;
void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h
index dd3b23c937e..75c11cfe167 100644
--- a/backends/platform/dc/dc.h
+++ b/backends/platform/dc/dc.h
@@ -151,8 +151,8 @@ public:
void quit();
// Overlay
- int16 getOverlayHeight();
- int16 getOverlayWidth();
+ int16 getOverlayHeight() const;
+ int16 getOverlayWidth() const;
bool isOverlayVisible() const { return _overlay_visible; }
void showOverlay(bool inGUI);
void hideOverlay();
diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp
index e4dfc2b90de..9b9e7a88766 100644
--- a/backends/platform/dc/display.cpp
+++ b/backends/platform/dc/display.cpp
@@ -702,12 +702,12 @@ void OSystem_Dreamcast::unlockScreen()
_screen_dirty = true;
}
-int16 OSystem_Dreamcast::getOverlayHeight()
+int16 OSystem_Dreamcast::getOverlayHeight() const
{
return OVL_H;
}
-int16 OSystem_Dreamcast::getOverlayWidth()
+int16 OSystem_Dreamcast::getOverlayWidth() const
{
return OVL_W;
}
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 8d6ecc2cf38..338f8bce98e 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -588,11 +588,11 @@ void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int
_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
}
-int16 OSystem_DS::getOverlayHeight() {
+int16 OSystem_DS::getOverlayHeight() const {
return _overlay.h;
}
-int16 OSystem_DS::getOverlayWidth() {
+int16 OSystem_DS::getOverlayWidth() const {
return _overlay.w;
}
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 9a411fd2354..456ecb5ed64 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -163,8 +163,8 @@ public:
virtual void clearOverlay();
virtual void grabOverlay(Graphics::Surface &surface);
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- virtual int16 getOverlayHeight();
- virtual int16 getOverlayWidth();
+ virtual int16 getOverlayHeight() const;
+ virtual int16 getOverlayWidth() const;
virtual Graphics::PixelFormat getOverlayFormat() const;
Common::Point transformPoint(int16 x, int16 y);
diff --git a/backends/platform/n64/osys_n64.h b/backends/platform/n64/osys_n64.h
index 1107ebcd045..729fe95d5d5 100644
--- a/backends/platform/n64/osys_n64.h
+++ b/backends/platform/n64/osys_n64.h
@@ -171,8 +171,8 @@ public:
virtual void clearOverlay();
virtual void grabOverlay(Graphics::Surface &surface);
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- virtual int16 getOverlayHeight();
- virtual int16 getOverlayWidth();
+ virtual int16 getOverlayHeight() const;
+ virtual int16 getOverlayWidth() const;
virtual Graphics::PixelFormat getOverlayFormat() const {
return Graphics::PixelFormat(2, 5, 5, 5, 0, 11, 6, 1, 0);
}
diff --git a/backends/platform/n64/osys_n64_base.cpp b/backends/platform/n64/osys_n64_base.cpp
index 8cbf7cae9e3..33477bed65a 100644
--- a/backends/platform/n64/osys_n64_base.cpp
+++ b/backends/platform/n64/osys_n64_base.cpp
@@ -729,11 +729,11 @@ void OSystem_N64::copyRectToOverlay(const void *buf, int pitch, int x, int y, in
return;
}
-int16 OSystem_N64::getOverlayHeight() {
+int16 OSystem_N64::getOverlayHeight() const {
return _overlayHeight;
}
-int16 OSystem_N64::getOverlayWidth() {
+int16 OSystem_N64::getOverlayWidth() const {
return _overlayWidth;
}
diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp
index 387594631a0..6c8454555b1 100644
--- a/backends/platform/psp/osys_psp.cpp
+++ b/backends/platform/psp/osys_psp.cpp
@@ -274,11 +274,11 @@ void OSystem_PSP::copyRectToOverlay(const void *buf, int pitch, int x, int y, in
_overlay.copyFromRect(buf, pitch, x, y, w, h);
}
-int16 OSystem_PSP::getOverlayWidth() {
+int16 OSystem_PSP::getOverlayWidth() const {
return (int16)_overlay.getWidth();
}
-int16 OSystem_PSP::getOverlayHeight() {
+int16 OSystem_PSP::getOverlayHeight() const {
return (int16)_overlay.getHeight();
}
diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h
index abf9d978be5..c8a3735581b 100644
--- a/backends/platform/psp/osys_psp.h
+++ b/backends/platform/psp/osys_psp.h
@@ -107,8 +107,8 @@ public:
void clearOverlay();
void grabOverlay(Graphics::Surface &surface);
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- int16 getOverlayHeight();
- int16 getOverlayWidth();
+ int16 getOverlayHeight() const;
+ int16 getOverlayWidth() const;
Graphics::PixelFormat getOverlayFormat() const { return Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12); }
// Mouse related
diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h
index 6c1432d0746..a68d7d2ae85 100644
--- a/backends/platform/wii/osystem.h
+++ b/backends/platform/wii/osystem.h
@@ -182,8 +182,8 @@ public:
void grabOverlay(Graphics::Surface &surface) override;
virtual void copyRectToOverlay(const void *buf, int pitch,
int x, int y, int w, int h) override;
- int16 getOverlayWidth() override;
- int16 getOverlayHeight() override;
+ int16 getOverlayWidth() const override;
+ int16 getOverlayHeight() const override;
Graphics::PixelFormat getOverlayFormat() const override;
bool showMouse(bool visible) override;
diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp
index 0808739922c..d44659ec2d7 100644
--- a/backends/platform/wii/osystem_gfx.cpp
+++ b/backends/platform/wii/osystem_gfx.cpp
@@ -651,11 +651,11 @@ void OSystem_Wii::copyRectToOverlay(const void *buf, int pitch, int x,
_overlayDirty = true;
}
-int16 OSystem_Wii::getOverlayWidth() {
+int16 OSystem_Wii::getOverlayWidth() const {
return _overlayWidth;
}
-int16 OSystem_Wii::getOverlayHeight() {
+int16 OSystem_Wii::getOverlayHeight() const {
return _overlayHeight;
}
diff --git a/common/system.h b/common/system.h
index 30f41558995..49bc6a4b2cc 100644
--- a/common/system.h
+++ b/common/system.h
@@ -1439,14 +1439,14 @@ public:
*
* @see getHeight
*/
- virtual int16 getOverlayHeight() = 0;
+ virtual int16 getOverlayHeight() const = 0;
/**
* Return the width of the overlay.
*
* @see getWidth
*/
- virtual int16 getOverlayWidth() = 0;
+ virtual int16 getOverlayWidth() const = 0;
/** @} */
Commit: 041ea908920f63a49b173444d03ef6476c37e95b
https://github.com/scummvm/scummvm/commit/041ea908920f63a49b173444d03ef6476c37e95b
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
COMMON: Add getSafeOverlayArea as OSystem function
This will let the GUI know where to put its widgets to avoid notches.
Changed paths:
backends/graphics/graphics.h
backends/modular-backend.cpp
backends/modular-backend.h
common/system.cpp
common/system.h
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index d551b460222..a5d30797f98 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -25,6 +25,7 @@
#include "common/system.h"
#include "common/noncopyable.h"
#include "common/keyboard.h"
+#include "common/rect.h"
#include "common/rotationmode.h"
#include "graphics/mode.h"
@@ -104,6 +105,13 @@ public:
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) = 0;
virtual int16 getOverlayHeight() const = 0;
virtual int16 getOverlayWidth() const = 0;
+ virtual Common::Rect getSafeOverlayArea(int16 *width, int16 *height) const {
+ int16 w = getOverlayWidth(),
+ h = getOverlayHeight();
+ if (width) *width = w;
+ if (height) *height = h;
+ return Common::Rect(w, h);
+ }
virtual float getHiDPIScreenFactor() const { return 1.0f; }
virtual bool showMouse(bool visible) = 0;
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 8ecc94277a8..d9ef67a441f 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -253,6 +253,10 @@ int16 ModularGraphicsBackend::getOverlayWidth() const {
return _graphicsManager->getOverlayWidth();
}
+Common::Rect ModularGraphicsBackend::getSafeOverlayArea(int16 *width, int16 *height) const {
+ return _graphicsManager->getSafeOverlayArea(width, height);
+}
+
float ModularGraphicsBackend::getHiDPIScreenFactor() const {
return _graphicsManager->getHiDPIScreenFactor();
}
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index ad0146bd38f..a5717601ddc 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -118,6 +118,7 @@ public:
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override final;
int16 getOverlayHeight() const override final;
int16 getOverlayWidth() const override final;
+ Common::Rect getSafeOverlayArea(int16 *width, int16 *height) const override final;
float getHiDPIScreenFactor() const override final;
diff --git a/common/system.cpp b/common/system.cpp
index 90f19047068..471d1e78ee9 100644
--- a/common/system.cpp
+++ b/common/system.cpp
@@ -223,6 +223,14 @@ bool OSystem::setRotationMode(int rotation) {
return setRotationMode(Common::parseRotationMode(rotation));
}
+Common::Rect OSystem::getSafeOverlayArea(int16 *width, int16 *height) const {
+ int16 w = getOverlayWidth(),
+ h = getOverlayHeight();
+ if (width) *width = w;
+ if (height) *height = h;
+ return Common::Rect(w, h);
+}
+
void OSystem::fatalError() {
quit();
exit(1);
diff --git a/common/system.h b/common/system.h
index 49bc6a4b2cc..53328db70e9 100644
--- a/common/system.h
+++ b/common/system.h
@@ -1448,6 +1448,19 @@ public:
*/
virtual int16 getOverlayWidth() const = 0;
+ /**
+ * Return the safe area for the overlay.
+ * This area does not interfere with any system UI elements
+ * such as the notch or home indicator on mobile devices.
+ * Also returns the full overlay size.
+ *
+ * @param width Returns the width of the overlay, if not nullptr
+ * @param height Returns the height of the overlay, if not nullptr
+ *
+ * @return The safe area in overlay coordinates.
+ */
+ virtual Common::Rect getSafeOverlayArea(int16 *width = nullptr, int16 *height = nullptr) const;
+
/** @} */
Commit: 790aa75dd71a8887ae8cae591d51d81abbfbf2ca
https://github.com/scummvm/scummvm/commit/790aa75dd71a8887ae8cae591d51d81abbfbf2ca
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
COMMON: Add constraining functions to Rect
This moves a rect inside the bounds of another one.
Changed paths:
common/rect.h
diff --git a/common/rect.h b/common/rect.h
index 10a59f40c7b..e8a25892d09 100644
--- a/common/rect.h
+++ b/common/rect.h
@@ -364,7 +364,40 @@ struct Rect {
moveTo(p.x, p.y);
}
- /**
+ /**
+ * Ensures the rectangle fits in an another one
+ *
+ * @return True if the rectangle could be constrained
+ */
+ bool constrain(const Rect &o) {
+ return o.constrain(left, top, width(), height());
+ }
+
+ /**
+ * Ensures the provided coordinates fit inside our rectangle
+ *
+ * @return True if the rectangle could be constrained
+ */
+ bool constrain(int16 &x, int16 &y, int16 w, int16 h) const {
+ if (w > width() || h > height()) {
+ return false;
+ }
+
+ if (x < left) {
+ x = left;
+ } else if (x > right - w) { // x + w > right
+ x = right - w;
+ }
+ if (y < top) {
+ y = top;
+ } else if (y > bottom - h) { // y + h > bottom
+ y = bottom - h;
+ }
+
+ return true;
+ }
+
+ /**
* Print debug messages related to this class.
*/
void debugPrint(int debuglevel = 0, const char *caption = "Rect:") const {
Commit: d3121b0320d7bbbae5f79d5edb9f9c5a764ffbf6
https://github.com/scummvm/scummvm/commit/d3121b0320d7bbbae5f79d5edb9f9c5a764ffbf6
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
BACKENDS: Implement safe area handling in WindowedGraphicsManager
Changed paths:
backends/graphics/windowed.h
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index cd71cf44ad4..2ba6bf625d4 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -104,6 +104,78 @@ public:
bool isOverlayVisible() const override { return _overlayVisible; }
+ Common::Rect getSafeOverlayArea(int16 *width, int16 *height) const override {
+ Insets insets = getSafeAreaInsets();
+
+ // Create the overlay rect cut of the insets
+ // in the window coordinate space
+ // Make sure to avoid a negative size (and an invalid rect)
+ const int safeLeft = MAX(_overlayDrawRect.left, insets.left),
+ safeTop = MAX(_overlayDrawRect.top, insets.top);
+ Common::Rect safeArea(safeLeft, safeTop,
+ MAX(safeLeft, MIN((int)_overlayDrawRect.right, _windowWidth - insets.right)),
+ MAX(safeTop, MIN((int)_overlayDrawRect.bottom, _windowHeight - insets.bottom)));
+
+ // Convert this safe area in the overlay coordinate space
+ const int targetWidth = getOverlayWidth(),
+ targetHeight = getOverlayHeight(),
+ sourceWidth = _overlayDrawRect.width(),
+ sourceHeight = _overlayDrawRect.height();
+
+ if (width) *width = targetWidth;
+ if (height) *height = targetHeight;
+
+ int rotatedTargetWidth = targetWidth,
+ rotatedTargetHeight = targetHeight;
+ if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
+ SWAP(rotatedTargetWidth, rotatedTargetHeight);
+ }
+
+ // First make it relative to overlay origin and scale it
+ safeArea.left = ((safeArea.left - _overlayDrawRect.left) * rotatedTargetWidth) / sourceWidth;
+ safeArea.top = ((safeArea.top - _overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
+ safeArea.right = ((safeArea.right - _overlayDrawRect.left) * rotatedTargetWidth) / sourceWidth;
+ safeArea.bottom = ((safeArea.bottom - _overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
+
+ // Now rotate it
+ switch (_rotationMode) {
+ default:
+ case Common::kRotationNormal:
+ // Nothing to do
+ break;
+ case Common::kRotation90: {
+ int16 tmp = safeArea.left;
+ safeArea.left = safeArea.top;
+ safeArea.top = rotatedTargetWidth - safeArea.right;
+ //safeArea.right = targetWidth - (rotatedTargetHeight - safeArea.bottom);
+ safeArea.right = safeArea.bottom; // targetWidth == rotatedTargetHeight
+ safeArea.bottom = targetHeight - tmp;
+ break;
+ }
+ case Common::kRotation180: {
+ int16 tmp;
+ tmp = safeArea.left;
+ safeArea.left = rotatedTargetWidth - safeArea.right;
+ safeArea.right = rotatedTargetWidth - tmp;
+ tmp = safeArea.top;
+ safeArea.top = rotatedTargetHeight - safeArea.bottom;
+ safeArea.bottom = rotatedTargetHeight - tmp;
+ break;
+ }
+ case Common::kRotation270: {
+ int16 tmp = safeArea.left;
+ safeArea.left = rotatedTargetHeight - safeArea.bottom;
+ //safeArea.bottom = targetHeight - (rotatedTargetWidth - safeArea.right);
+ safeArea.bottom = safeArea.right; // targetHeight == rotatedTargetWidth
+ safeArea.right = targetWidth - safeArea.top;
+ safeArea.top = tmp;
+ break;
+ }
+ }
+
+ return safeArea;
+ }
+
void setShakePos(int shakeXOffset, int shakeYOffset) override {
if (_gameScreenShakeXOffset != shakeXOffset || _gameScreenShakeYOffset != shakeYOffset) {
_gameScreenShakeXOffset = shakeXOffset;
@@ -236,6 +308,23 @@ protected:
return 1;
}
+ struct Insets {
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ };
+
+ /**
+ * Returns the insets needed to get a safe area which does not interfere
+ * with any system UI elements such as the notch or home indicator on mobile devices.
+ *
+ * @return The safe area insets
+ */
+ virtual Insets getSafeAreaInsets() const {
+ return {0, 0, 0, 0};
+ }
+
/**
* Called after the window has been updated with new dimensions.
*
@@ -257,13 +346,26 @@ protected:
return;
}
- populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), getWidth() * getGameRenderScale(), getHeight() * getGameRenderScale(), _gameDrawRect);
+ // Compute a safe area rectangle out of the insets
+ Insets insets = getSafeAreaInsets();
+ Common::Rect safeArea(insets.left, insets.top,
+ _windowWidth - insets.right,
+ _windowHeight - insets.bottom);
+
+ // Create a game draw rect using the safe are dimensions
+ populateDisplayAreaDrawRect(getDesiredGameAspectRatio(),
+ getWidth() * getGameRenderScale(), getHeight() * getGameRenderScale(),
+ safeArea, _gameDrawRect);
+
+ // Move the game draw rect in the safe area
+ _gameDrawRect.constrain(safeArea);
if (getOverlayHeight()) {
const int16 overlayWidth = getOverlayWidth(),
overlayHeight = getOverlayHeight();
const frac_t overlayAspect = intToFrac(overlayWidth) / overlayHeight;
- populateDisplayAreaDrawRect(overlayAspect, overlayWidth, overlayHeight, _overlayDrawRect);
+ populateDisplayAreaDrawRect(overlayAspect, overlayWidth, overlayHeight,
+ Common::Rect(_windowWidth, _windowHeight),_overlayDrawRect);
}
if (_overlayInGUI) {
@@ -450,52 +552,54 @@ protected:
int _cursorX, _cursorY;
private:
- void populateDisplayAreaDrawRect(const frac_t displayAspect, int originalWidth, int originalHeight, Common::Rect &drawRect) const {
+ void populateDisplayAreaDrawRect(const frac_t displayAspect, int originalWidth, int originalHeight, const Common::Rect &safeArea, Common::Rect &drawRect) const {
int mode = getStretchMode();
- int rotatedWindowWidth;
- int rotatedWindowHeight;
+
+ Common::Rect rotatedSafeArea(safeArea);
+ int rotatedWindowWidth = _windowWidth,
+ rotatedWindowHeight = _windowHeight;
if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
- rotatedWindowWidth = _windowHeight;
- rotatedWindowHeight = _windowWidth;
- } else {
- rotatedWindowWidth = _windowWidth;
- rotatedWindowHeight = _windowHeight;
+ SWAP(rotatedSafeArea.left, rotatedSafeArea.top);
+ SWAP(rotatedSafeArea.right, rotatedSafeArea.bottom);
+ SWAP(rotatedWindowWidth, rotatedWindowHeight);
}
+ const int rotatedSafeWidth = rotatedSafeArea.width(),
+ rotatedSafeHeight = rotatedSafeArea.height();
+
// Mode Center = use original size, or divide by an integral amount if window is smaller than game surface
// Mode Integral = scale by an integral amount.
// Mode Fit = scale to fit the window while respecting the aspect ratio
// Mode Stretch = scale and stretch to fit the window without respecting the aspect ratio
// Mode Fit Force Aspect = scale to fit the window while forcing a 4:3 aspect ratio
-
int width = 0, height = 0;
if (mode == STRETCH_CENTER || mode == STRETCH_INTEGRAL || mode == STRETCH_INTEGRAL_AR) {
width = originalWidth;
height = intToFrac(width) / displayAspect;
- if (width > rotatedWindowWidth || height > rotatedWindowHeight) {
- int fac = 1 + MAX((width - 1) / rotatedWindowWidth, (height - 1) / rotatedWindowHeight);
+ if (width > rotatedSafeWidth || height > rotatedSafeHeight) {
+ int fac = 1 + MAX((width - 1) / rotatedSafeWidth, (height - 1) / rotatedSafeHeight);
width /= fac;
height /= fac;
} else if (mode == STRETCH_INTEGRAL) {
- int fac = MIN(rotatedWindowWidth / width, rotatedWindowHeight / height);
+ int fac = MIN(rotatedSafeWidth / width, rotatedSafeHeight / height);
width *= fac;
height *= fac;
} else if (mode == STRETCH_INTEGRAL_AR) {
int targetHeight = height;
- int horizontalFac = rotatedWindowWidth / width;
+ int horizontalFac = rotatedSafeWidth / width;
do {
width = originalWidth * horizontalFac;
int verticalFac = (targetHeight * horizontalFac + originalHeight / 2) / originalHeight;
height = originalHeight * verticalFac;
--horizontalFac;
- } while (horizontalFac > 0 && height > rotatedWindowHeight);
- if (height > rotatedWindowHeight)
+ } while (horizontalFac > 0 && height > rotatedSafeHeight);
+ if (height > rotatedSafeHeight)
height = targetHeight;
}
} else {
- frac_t windowAspect = intToFrac(rotatedWindowWidth) / rotatedWindowHeight;
- width = rotatedWindowWidth;
- height = rotatedWindowHeight;
+ frac_t windowAspect = intToFrac(rotatedSafeWidth) / rotatedSafeHeight;
+ width = rotatedSafeWidth;
+ height = rotatedSafeHeight;
if (mode == STRETCH_FIT_FORCE_ASPECT) {
frac_t ratio = intToFrac(4) / 3;
if (windowAspect < ratio)
@@ -510,7 +614,7 @@ private:
}
}
- int alignX, alignY;
+ int16 alignX, alignY;
switch (_screenAlign & SCREEN_ALIGN_XMASK) {
default:
case SCREEN_ALIGN_CENTER:
@@ -520,7 +624,7 @@ private:
alignX = 0;
break;
case SCREEN_ALIGN_RIGHT:
- alignX = (rotatedWindowWidth - width);
+ alignX = (rotatedSafeArea.right - width);
break;
}
@@ -533,10 +637,12 @@ private:
alignY = 0;
break;
case SCREEN_ALIGN_BOTTOM:
- alignY = (rotatedWindowHeight - height);
+ alignY = (rotatedSafeArea.bottom - height);
break;
}
+ rotatedSafeArea.constrain(alignX, alignY, width, height);
+
alignX += _gameScreenShakeXOffset * width / getWidth();
alignY += _gameScreenShakeYOffset * height / getHeight();
Commit: 336aedaf3e17267ba612d36de6f9ec63f292dd83
https://github.com/scummvm/scummvm/commit/336aedaf3e17267ba612d36de6f9ec63f292dd83
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Take safe insets into account
Changed paths:
gui/ThemeLayout.cpp
gui/gui-manager.cpp
diff --git a/gui/ThemeLayout.cpp b/gui/ThemeLayout.cpp
index f8f1ab88936..12481ba5e8f 100644
--- a/gui/ThemeLayout.cpp
+++ b/gui/ThemeLayout.cpp
@@ -216,21 +216,47 @@ Widget *ThemeLayoutWidget::getWidget(Widget *widgetChain) const {
return Widget::findWidgetInChain(widgetChain, widgetName.c_str());
}
+enum SafeAreaType {
+ kSafeAreaNone,
+ kSafeAreaMove,
+ kSafeAreaExtend
+};
+
void ThemeLayoutMain::reflowLayout(Widget *widgetChain) {
assert(_children.size() <= 1);
resetLayout();
+ int16 screenW;
+ int16 screenH;
+
+ Common::Rect safeArea = g_system->getSafeOverlayArea(&screenW, &screenH);
+ SafeAreaType safeAreaType;
+
+ // With RTL, we just flip everything on the X axis, so do the same with the safeArea
+ if (g_gui.useRTL()) {
+ int16 tmp = safeArea.left;
+ safeArea.left = screenW - safeArea.right;
+ safeArea.right = screenW - tmp;
+ }
+
+ int inset = _inset * g_gui.getScaleFactor();
+
if (_overlays == "screen") {
- _x = 0;
- _y = 0;
- _w = g_gui.getGUIWidth() * g_gui.getScaleFactor();
- _h = g_gui.getGUIHeight() * g_gui.getScaleFactor();
+ _x = MAX(inset, (int)safeArea.left);
+ _y = MAX(inset, (int)safeArea.top);
+ int16 r = MIN(screenW - inset, (int)safeArea.right);
+ int16 b = MIN(screenH - inset, (int)safeArea.bottom);
+ _w = r - _x;
+ _h = b - _y;
+ // Extend the dialog background only if it is supposed to stick on the borders
+ safeAreaType = inset == 0 ? kSafeAreaExtend : kSafeAreaMove;
} else if (_overlays == "screen_center") {
_x = -1;
_y = -1;
- _w = _defaultW > 0 ? MIN(_defaultW, (int16)(g_gui.getGUIWidth() * g_gui.getScaleFactor())) : -1;
- _h = _defaultH > 0 ? MIN(_defaultH, (int16)(g_gui.getGUIHeight() * g_gui.getScaleFactor())) : -1;
+ _w = _defaultW > 0 ? MIN(_defaultW - 2*inset, (int)safeArea.width()) : -1;
+ _h = _defaultH > 0 ? MIN(_defaultH - 2*inset, (int)safeArea.height()) : -1;
+ safeAreaType = kSafeAreaMove;
} else {
if (!g_gui.xmlEval()->getWidgetData(_overlays, _x, _y, _w, _h)) {
warning("Unable to retrieve overlayed dialog position %s", _overlays.c_str());
@@ -238,24 +264,35 @@ void ThemeLayoutMain::reflowLayout(Widget *widgetChain) {
if (_w == -1 || _h == -1) {
warning("The overlayed dialog %s has not been sized, using a default size for %s", _overlays.c_str(), _name.c_str());
- _x = g_gui.getGUIWidth() / 10 * g_gui.getScaleFactor();
- _y = g_gui.getGUIHeight() / 10 * g_gui.getScaleFactor();
- _w = g_gui.getGUIWidth() * 8 / 10 * g_gui.getScaleFactor();
- _h = g_gui.getGUIHeight() * 8 / 10 * g_gui.getScaleFactor();
+ _x = MAX(safeArea.width() / 10 + inset, (int)safeArea.left);
+ _y = MAX(safeArea.height() / 10 + inset, (int)safeArea.top);
+ int16 r = MIN(screenW - safeArea.width() / 10 - inset, (int)safeArea.right);
+ int16 b = MIN(screenH - safeArea.height() / 10 - inset, (int)safeArea.bottom);
+ _w = r - _x;
+ _h = b - _y;
+ safeAreaType = kSafeAreaMove;
+ } else {
+ // We expect that the parent widget already takes the safe area into account
+ if (_x >= 0) _x += inset;
+ if (_y >= 0) _y += inset;
+ if (_w >= 0) _w -= 2 * inset;
+ if (_h >= 0) _h -= 2 * inset;
+ safeAreaType = kSafeAreaNone;
}
-
}
- if (_x >= 0) _x += _inset * g_gui.getScaleFactor();
- if (_y >= 0) _y += _inset * g_gui.getScaleFactor();
- if (_w >= 0) _w -= 2 * _inset * g_gui.getScaleFactor();
- if (_h >= 0) _h -= 2 * _inset * g_gui.getScaleFactor();
-
if (_children.size()) {
_children[0]->setWidth(_w);
_children[0]->setHeight(_h);
_children[0]->reflowLayout(widgetChain);
+ if (safeAreaType == kSafeAreaExtend) {
+ _x = 0;
+ _y = 0;
+ _w = screenW;
+ _h = screenH;
+ }
+
if (_w == -1)
_w = _children[0]->getWidth();
@@ -263,10 +300,24 @@ void ThemeLayoutMain::reflowLayout(Widget *widgetChain) {
_h = _children[0]->getHeight();
if (_y == -1)
- _y = (g_system->getOverlayHeight() >> 1) - (_h >> 1);
+ _y = (screenH >> 1) - (_h >> 1);
if (_x == -1)
- _x = (g_system->getOverlayWidth() >> 1) - (_w >> 1);
+ _x = (screenW >> 1) - (_w >> 1);
+
+
+ if (safeAreaType == kSafeAreaExtend) {
+ // Move the children to allow for background draw since the origin
+ _children[0]->offsetX(safeArea.left);
+ _children[0]->offsetY(safeArea.top);
+ } else if (safeAreaType == kSafeAreaMove) {
+ assert(safeArea.constrain(_x, _y, _w, _h));
+ }
+ } else if (safeAreaType == kSafeAreaExtend) {
+ _x = 0;
+ _y = 0;
+ _w = screenW;
+ _h = screenH;
}
}
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 2dcfb457418..02de69aa7c9 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -120,8 +120,9 @@ void GuiManager::initIconsSet() {
}
void GuiManager::computeScaleFactor() {
- uint16 w = g_system->getOverlayWidth();
- uint16 h = g_system->getOverlayHeight();
+ const Common::Rect safeArea = g_system->getSafeOverlayArea();
+ const uint16 w = safeArea.width();
+ const uint16 h = safeArea.height();
_scaleFactor = g_system->getHiDPIScreenFactor();
if (ConfMan.hasKey("gui_scale"))
Commit: 17085b9ad2c02eda23f0dc7a97eb50a10652fae5
https://github.com/scummvm/scummvm/commit/17085b9ad2c02eda23f0dc7a97eb50a10652fae5
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
IOS7: Implement getSafeAreaInsets
Changed paths:
backends/graphics/ios/ios-graphics.cpp
backends/graphics/ios/ios-graphics.h
backends/platform/ios7/ios7_common.h
backends/platform/ios7/ios7_osys_main.cpp
backends/platform/ios7/ios7_video.mm
diff --git a/backends/graphics/ios/ios-graphics.cpp b/backends/graphics/ios/ios-graphics.cpp
index ac470326d67..b31cf3484d4 100644
--- a/backends/graphics/ios/ios-graphics.cpp
+++ b/backends/graphics/ios/ios-graphics.cpp
@@ -25,7 +25,8 @@
#include "backends/graphics/opengl/pipelines/pipeline.h"
#include "backends/platform/ios7/ios7_osys_main.h"
-iOSGraphicsManager::iOSGraphicsManager() {
+iOSGraphicsManager::iOSGraphicsManager() :
+ _insets{0, 0, 0, 0} {
initSurface();
}
diff --git a/backends/graphics/ios/ios-graphics.h b/backends/graphics/ios/ios-graphics.h
index 91d96f01e19..2c7f6caf1ec 100644
--- a/backends/graphics/ios/ios-graphics.h
+++ b/backends/graphics/ios/ios-graphics.h
@@ -43,6 +43,9 @@ public:
float getHiDPIScreenFactor() const override;
+ void setSafeAreaInsets(int l, int r, int t, int b) { _insets.left = l; _insets.top = t; _insets.right = r; _insets.bottom = b; }
+ WindowedGraphicsManager::Insets getSafeAreaInsets() const override { return _insets; }
+
protected:
void setSystemMousePosition(const int x, const int y) override {}
@@ -53,6 +56,7 @@ protected:
void refreshScreen() override;
int _old_touch_mode;
+ WindowedGraphicsManager::Insets _insets;
};
#endif
diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h
index c7dcb42d06b..edc2c544206 100644
--- a/backends/platform/ios7/ios7_common.h
+++ b/backends/platform/ios7/ios7_common.h
@@ -107,5 +107,6 @@ void iOS7_main(int argc, char **argv);
Common::String iOS7_getDocumentsDir();
Common::String iOS7_getAppBundleDir();
TouchMode iOS7_getCurrentTouchMode();
+void iOS7_setSafeAreaInsets(int l, int r, int t, int b);
#endif
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index d82f596b9bb..f69eec2616d 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -408,6 +408,18 @@ void iOS7_buildSharedOSystemInstance() {
OSystem_iOS7::sharedInstance();
}
+void iOS7_setSafeAreaInsets(int l, int r, int t, int b) {
+ ModularGraphicsBackend *sys = dynamic_cast<ModularGraphicsBackend *>(g_system);
+ if (!sys) {
+ return;
+ }
+ iOSGraphicsManager *gfx = dynamic_cast<iOSGraphicsManager *>(sys->getGraphicsManager());
+ if (!gfx) {
+ return;
+ }
+ gfx->setSafeAreaInsets(l, r, t, b);
+}
+
TouchMode iOS7_getCurrentTouchMode() {
OSystem_iOS7 *sys = dynamic_cast<OSystem_iOS7 *>(g_system);
if (!sys) {
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 85dd916145c..9dedca12134 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -510,38 +510,17 @@ bool iOS7_fetchEvent(InternalEvent *event) {
// available when running on iOS 11+ if it has been compiled on iOS 11+
#ifdef __IPHONE_11_0
if ( @available(iOS 11, tvOS 11, *) ) {
- CGRect newFrame = self.frame;
#if TARGET_OS_IOS
- CGRect screenSize = self.window.bounds;
UIEdgeInsets inset = [[[UIApplication sharedApplication] keyWindow] safeAreaInsets];
- UIInterfaceOrientation orientation = [iOS7AppDelegate currentOrientation];
-
- // The code below adjust the screen size according to what Apple calls
- // the "safe area". It also cover the cases when the software keyboard
- // is visible and has changed the frame height so the keyboard doesn't
- // cover any part of the game screen.
- if (orientation != _currentOrientation) {
- // If the orientation is changed the keyboard will hide or show
- // depending on the current orientation. The frame size must be
- // "reset" again to "full" screen size dimension. The keyboard
- // will then calculate the approriate height when becoming visible.
- newFrame = screenSize;
- _currentOrientation = orientation;
- }
- // Make sure the frame height (either full screen or resized due to
- // visible keyboard) is within the safe area.
- CGFloat safeAreaHeight = screenSize.size.height - inset.top;
- CGFloat height = newFrame.size.height < safeAreaHeight ? newFrame.size.height : safeAreaHeight;
-
- if ( orientation == UIInterfaceOrientationPortrait ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y + inset.top, screenSize.size.width, height);
- } else if ( orientation == UIInterfaceOrientationPortraitUpsideDown ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width, height);
- } else if ( orientation == UIInterfaceOrientationLandscapeLeft ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width - inset.right, height);
- } else if ( orientation == UIInterfaceOrientationLandscapeRight ) {
- newFrame = CGRectMake(screenSize.origin.x + inset.left, screenSize.origin.y, screenSize.size.width - inset.left, height);
- }
+ // Skip the safe area inset at the bottom.
+ // We want to utilize as much screen area as possible and few
+ // games and launcher elements are put at the very bottom of
+ // the screen.
+ // The insets seem to be expressed in logical coordinate space
+ // (measured in points) while we expect the device coordinate
+ // space (measured in pixels), so we scale it using contentScaleFactor
+ CGFloat scale = [self contentScaleFactor];
+ iOS7_setSafeAreaInsets(inset.left * scale, inset.right * scale, inset.top * scale, 0);
// Add margins to respect the iPhone and iPad safe areas. Use the right
// safe area inset if available since the position of the buttons are
@@ -557,7 +536,6 @@ bool iOS7_fetchEvent(InternalEvent *event) {
// Burger menu button below
[_menuButton setFrame:CGRectMake(self.frame.size.width - _menuButton.imageView.image.size.width - margin, _toggleTouchModeButton.imageView.image.size.height + margin, _menuButton.imageView.image.size.width, _menuButton.imageView.image.size.height)];
#endif
- self.frame = newFrame;
}
#endif
}
Commit: 68c27f907a50e68cc8148955ca5a85542e78c797
https://github.com/scummvm/scummvm/commit/68c27f907a50e68cc8148955ca5a85542e78c797
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
ANDROID: Implement getSafeAreaInsets
Changed paths:
backends/graphics/android/android-graphics.cpp
backends/graphics/android/android-graphics.h
backends/platform/android/jni-android.cpp
backends/platform/android/jni-android.h
diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index 626d5197cef..c8bbfea8e86 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -308,3 +308,9 @@ bool AndroidGraphicsManager::notifyMousePosition(Common::Point &mouse) {
return true;
}
+
+WindowedGraphicsManager::Insets AndroidGraphicsManager::getSafeAreaInsets() const {
+ return WindowedGraphicsManager::Insets{
+ (int16)JNI::cutout_insets[0], (int16)JNI::cutout_insets[1],
+ (int16)JNI::cutout_insets[2], (int16)JNI::cutout_insets[3]};
+}
diff --git a/backends/graphics/android/android-graphics.h b/backends/graphics/android/android-graphics.h
index bcae3e33bba..607bdd36a29 100644
--- a/backends/graphics/android/android-graphics.h
+++ b/backends/graphics/android/android-graphics.h
@@ -37,6 +37,8 @@ public:
void deinitSurface();
void resizeSurface();
+ WindowedGraphicsManager::Insets getSafeAreaInsets() const override;
+
void updateScreen() override;
void displayMessageOnOSD(const Common::U32String &msg) override;
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index 40e06d58ba4..3477445309f 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -81,6 +81,7 @@ int JNI::egl_bits_per_pixel = 0;
bool JNI::_ready_for_events = 0;
bool JNI::virt_keyboard_state = false;
int32 JNI::gestures_insets[4] = { 0, 0, 0, 0 };
+int32 JNI::cutout_insets[4] = { 0, 0, 0, 0 };
jmethodID JNI::_MID_getDPI = 0;
jmethodID JNI::_MID_displayMessageOnOSD = 0;
@@ -980,8 +981,8 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
void JNI::systemInsetsUpdated(JNIEnv *env, jobject self, jintArray gestureInsets, jintArray systemInsets, jintArray cutoutInsets) {
assert(env->GetArrayLength(gestureInsets) == ARRAYSIZE(gestures_insets));
- // TODO: handle systemInsets and cutoutInsets
env->GetIntArrayRegion(gestureInsets, 0, ARRAYSIZE(gestures_insets), gestures_insets);
+ env->GetIntArrayRegion(cutoutInsets, 0, ARRAYSIZE(cutout_insets), cutout_insets);
}
jstring JNI::getNativeVersionInfo(JNIEnv *env, jobject self) {
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index b804c933d8f..7debf08874d 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -56,6 +56,7 @@ public:
static bool virt_keyboard_state;
static int32 gestures_insets[4];
+ static int32 cutout_insets[4];
static jint onLoad(JavaVM *vm);
Commit: 908c7f732612ae66847bd945f8c93b3c3fd732be
https://github.com/scummvm/scummvm/commit/908c7f732612ae66847bd945f8c93b3c3fd732be
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Remove useless sizing
The size is set by the theme engine
Changed paths:
gui/launcher.cpp
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 3d98d78edd1..6cbf4a91f15 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -912,9 +912,6 @@ void LauncherDialog::reflowLayout() {
addLayoutChooserButtons();
#endif
- _w = g_system->getOverlayWidth();
- _h = g_system->getOverlayHeight();
-
Dialog::reflowLayout();
}
Commit: 7ddb851e41afc45f005bca73c69d25c3ea06708c
https://github.com/scummvm/scummvm/commit/7ddb851e41afc45f005bca73c69d25c3ea06708c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in about dialog
Changed paths:
gui/about.cpp
diff --git a/gui/about.cpp b/gui/about.cpp
index 8d28c9b1314..c38f37db0e9 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -379,15 +379,16 @@ void AboutDialog::handleKeyUp(Common::KeyState state) {
void AboutDialog::reflowLayout() {
Dialog::reflowLayout();
int i;
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+
+ int16 screenW, screenH;
+ const Common::Rect screenArea = g_system->getSafeOverlayArea(&screenW, &screenH);
_xOff = g_gui.xmlEval()->getVar("Globals.About.XOffset", 5);
_yOff = g_gui.xmlEval()->getVar("Globals.About.YOffset", 5);
int outerBorder = g_gui.xmlEval()->getVar("Globals.About.OuterBorder");
- _w = screenW - 2 * outerBorder;
- _h = screenH - 2 * outerBorder;
+ _w = screenArea.width() - 2 * outerBorder;
+ _h = screenArea.height() - 2 * outerBorder;
_lineHeight = g_gui.getFontHeight() + 3;
@@ -402,9 +403,12 @@ void AboutDialog::reflowLayout() {
}
_w += 2*_xOff;
- // Center the dialog
+ // Center the dialog in the screen
_x = (screenW - _w) / 2;
_y = (screenH - _h) / 2;
+
+ // Make it fit in the safe area
+ screenArea.constrain(_x, _y, _w, _h);
}
Commit: dee1a773356a70b6b294dfeb91ed6e6e6b4680b0
https://github.com/scummvm/scummvm/commit/dee1a773356a70b6b294dfeb91ed6e6e6b4680b0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in console
Changed paths:
gui/console.cpp
diff --git a/gui/console.cpp b/gui/console.cpp
index d653e056fca..5901de0cc1e 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -98,23 +98,22 @@ ConsoleDialog::~ConsoleDialog() {
}
void ConsoleDialog::init() {
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+ const Common::Rect safeArea = g_system->getSafeOverlayArea();
_font = &g_gui.getFont(ThemeEngine::kFontStyleConsole);
_leftPadding = g_gui.xmlEval()->getVar("Globals.Console.Padding.Left", 0);
_rightPadding = g_gui.xmlEval()->getVar("Globals.Console.Padding.Right", 0);
- _topPadding = g_gui.xmlEval()->getVar("Globals.Console.Padding.Top", 0);
+ _topPadding = MAX(g_gui.xmlEval()->getVar("Globals.Console.Padding.Top", 0), (int)safeArea.top);
_bottomPadding = g_gui.xmlEval()->getVar("Globals.Console.Padding.Bottom", 0);
// Calculate the real width/height (rounded to char/line multiples)
- _w = (uint16)(_widthPercent * screenW);
- _h = (uint16)((_heightPercent * screenH - 2) / kConsoleLineHeight);
+ _w = (uint16)(_widthPercent * safeArea.width());
+ _h = (uint16)((_heightPercent * safeArea.height() - 2) / kConsoleLineHeight);
_w = _w - _w / 20;
- _h = _h * kConsoleLineHeight + 2;
- _x = _w / 40;
+ _h = _h * kConsoleLineHeight + 2 + safeArea.top;
+ _x = MAX(_w / 40, (int)safeArea.left);
// Set scrollbar dimensions
int scrollBarWidth = g_gui.xmlEval()->getVar("Globals.Scrollbar.Width", 0);
@@ -168,14 +167,13 @@ void ConsoleDialog::open() {
// visible screen area, then shift it down in handleTickle() over a
// certain period of time.
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+ const Common::Rect safeArea = g_system->getSafeOverlayArea();
// Calculate the real width/height (rounded to char/line multiples)
- uint16 w = (uint16)(_widthPercent * screenW);
- uint16 h = (uint16)((_heightPercent * screenH - 2) / kConsoleLineHeight);
+ uint16 w = (uint16)(_widthPercent * safeArea.width());
+ uint16 h = (uint16)((_heightPercent * safeArea.height() - 2) / kConsoleLineHeight);
- h = h * kConsoleLineHeight + 2;
+ h = h * kConsoleLineHeight + 2 + safeArea.top;
w = w - w / 20;
if (_w != w || _h != h)
Commit: 9a158af369d7057efd2f55b096a21d01b1a5de82
https://github.com/scummvm/scummvm/commit/9a158af369d7057efd2f55b096a21d01b1a5de82
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in message dialogs
Changed paths:
gui/message.cpp
diff --git a/gui/message.cpp b/gui/message.cpp
index ee798569f23..4af435ad8d0 100644
--- a/gui/message.cpp
+++ b/gui/message.cpp
@@ -71,8 +71,8 @@ void MessageDialog::reflowLayout() {
const int horizontalMargin = 10;
const int buttonSpacing = 10;
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+ int16 screenW, screenH;
+ const Common::Rect safeArea = g_system->getSafeOverlayArea(&screenW, &screenH);
int buttonWidth = g_gui.xmlEval()->getVar("Globals.Button.Width", 0);
int buttonHeight = g_gui.xmlEval()->getVar("Globals.Button.Height", 0);
@@ -84,7 +84,7 @@ void MessageDialog::reflowLayout() {
Common::Array<Common::U32String> lines;
size_t lineCount;
- int maxlineWidth = g_gui.getFont().wordWrapText(_message, screenW - 2 * horizontalMargin - 20, lines);
+ int maxlineWidth = g_gui.getFont().wordWrapText(_message, safeArea.width() - 2 * horizontalMargin - 20, lines);
const size_t buttonCount = _buttons.size();
const int buttonsTotalWidth = buttonCount * buttonWidth + (buttonCount - 1) * buttonSpacing;
@@ -97,28 +97,34 @@ void MessageDialog::reflowLayout() {
_h = 16;
if (buttonCount)
_h += buttonHeight + 8;
+ if (_extraMessage)
+ _h += kLineHeight;
// Limit the number of lines so that the dialog still fits on the screen.
- if (lineCount > size_t((screenH - 20 - _h) / kLineHeight)) {
- lineCount = (screenH - 20 - _h) / kLineHeight;
- }
+ lineCount = MIN(lineCount, (size_t)((safeArea.height() - 20 - _h) / kLineHeight));
_h += lineCount * kLineHeight;
// Center the dialog
_x = (screenW - _w) / 2;
_y = (screenH - _h) / 2;
+ safeArea.constrain(_x, _y, _w, _h);
+
+ int curY = 10;
+
// Each line is represented by one static text item.
// Update existing lines
size_t toUpdateLines = MIN<size_t>(lineCount, _lines.size());
for (size_t i = 0; i < toUpdateLines; i++) {
- _lines[i]->setPos(horizontalMargin, 10 + i * kLineHeight);
+ _lines[i]->setPos(horizontalMargin, curY);
_lines[i]->setSize(maxlineWidth, kLineHeight);
_lines[i]->setLabel(lines[i]);
+ curY += kLineHeight;
}
// Create missing lines
for (size_t i = toUpdateLines; i < lineCount; i++) {
- _lines.push_back(new StaticTextWidget(this, horizontalMargin, 10 + i * kLineHeight, maxlineWidth, kLineHeight, lines[i], _alignment));
+ _lines.push_back(new StaticTextWidget(this, horizontalMargin, curY, maxlineWidth, kLineHeight, lines[i], _alignment));
+ curY += kLineHeight;
}
// Cleanup old useless lines
for (size_t i = lineCount, total = _lines.size(); i < total; i++) {
@@ -127,17 +133,22 @@ void MessageDialog::reflowLayout() {
}
_lines.resize(lineCount);
- int buttonPos = (_w - buttonsTotalWidth) / 2;
- for (size_t i = 0; i < buttonCount; ++i) {
- _buttons[i]->setPos(buttonPos, _h - buttonHeight - 8);
- _buttons[i]->setSize(buttonWidth, buttonHeight);
- buttonPos += buttonWidth + buttonSpacing;
+ if (buttonCount) {
+ curY += 8;
+ int buttonPos = (_w - buttonsTotalWidth) / 2;
+ for (size_t i = 0; i < buttonCount; ++i) {
+ _buttons[i]->setPos(buttonPos, curY);
+ _buttons[i]->setSize(buttonWidth, buttonHeight);
+ buttonPos += buttonWidth + buttonSpacing;
+ }
+ curY += buttonHeight;
}
+ curY += 6;
+
if (_extraMessage) {
- _extraMessage->setPos(10, _h);
+ _extraMessage->setPos(10, curY);
_extraMessage->setSize(maxlineWidth, kLineHeight);
- _h += kLineHeight;
}
}
Commit: 5e2828b4ae9f6980d803b06a1120ef0167996b52
https://github.com/scummvm/scummvm/commit/5e2828b4ae9f6980d803b06a1120ef0167996b52
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in text viewer dialog
Changed paths:
gui/textviewer.cpp
diff --git a/gui/textviewer.cpp b/gui/textviewer.cpp
index a63d1e9d610..0a7b4404b27 100644
--- a/gui/textviewer.cpp
+++ b/gui/textviewer.cpp
@@ -105,13 +105,18 @@ void TextViewerDialog::destroy() {
}
void TextViewerDialog::reflowLayout() {
+ int16 screenW, screenH;
+ const Common::Rect safeArea = g_system->getSafeOverlayArea(&screenW, &screenH);
+
// Calculate the real width/height (rounded to char/line multiples)
- _w = (uint16)(kDialogWidthPercent * g_system->getOverlayWidth());
- _h = (uint16)((kDialogHeightPercent * g_system->getOverlayHeight() - 2) / _lineHeight);
+ _w = (uint16)(kDialogWidthPercent * safeArea.width());
+ _h = (uint16)((kDialogHeightPercent * safeArea.height() - 2) / _lineHeight);
_h = _h * _lineHeight + 2;
- _x = (g_system->getOverlayWidth() - _w) / 2;
- _y = (g_system->getOverlayHeight() - _h) / 2;
+ _x = (screenW - _w) / 2;
+ _y = (screenH - _h) / 2;
+
+ safeArea.constrain(_x, _y, _w, _h);
_padX = _w * kPadX;
_padY = _h * kPadY;
Commit: 0304c15ff66b0f5d44c9a3973dc8ba0f662bb08f
https://github.com/scummvm/scummvm/commit/0304c15ff66b0f5d44c9a3973dc8ba0f662bb08f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in updates dialog
Changed paths:
gui/updates-dialog.cpp
diff --git a/gui/updates-dialog.cpp b/gui/updates-dialog.cpp
index b63310e9b83..3f3430db7d7 100644
--- a/gui/updates-dialog.cpp
+++ b/gui/updates-dialog.cpp
@@ -37,9 +37,8 @@ enum {
UpdatesDialog::UpdatesDialog() : Dialog(30, 20, 260, 124) {
-
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+ int16 screenW, screenH;
+ const Common::Rect safeArea = g_system->getSafeOverlayArea(&screenW, &screenH);
int buttonWidth = g_gui.xmlEval()->getVar("Globals.Button.Width", 0);
int buttonHeight = g_gui.xmlEval()->getVar("Globals.Button.Height", 0);
@@ -56,8 +55,8 @@ UpdatesDialog::UpdatesDialog() : Dialog(30, 20, 260, 124) {
// Using this, and accounting for the space the button(s) need, we can set
// the real size of the dialog
Common::Array<Common::U32String> lines, lines2;
- int maxlineWidth = g_gui.getFont().wordWrapText(message, screenW - 2 * 20, lines);
- int maxlineWidth2 = g_gui.getFont().wordWrapText(message2, screenW - 2 * 20, lines2);
+ int maxlineWidth = g_gui.getFont().wordWrapText(message, safeArea.width() - 2 * 20, lines);
+ int maxlineWidth2 = g_gui.getFont().wordWrapText(message2, safeArea.width() - 2 * 20, lines2);
_w = MAX(MAX(maxlineWidth, maxlineWidth2), (2 * buttonWidth) + 10) + 20;
@@ -72,6 +71,9 @@ UpdatesDialog::UpdatesDialog() : Dialog(30, 20, 260, 124) {
_x = (screenW - _w) / 2;
_y = (screenH - _h) / 2;
+ // Make it fit inside the safe area
+ safeArea.constrain(_x, _y, _w, _h);
+
// Each line is represented by one static text item.
uint y = 10;
for (uint i = 0; i < lines.size(); i++) {
Commit: 4f14363146ad6c0ed1b1162fc52c730a3c06b140
https://github.com/scummvm/scummvm/commit/4f14363146ad6c0ed1b1162fc52c730a3c06b140
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
IOS7: Remove adjustment of virtual game controller
Since the safe area insets are now respected the whole game screen can
be utilized. Thankfully this means the adjustments moving the virtual
game controller overlay can be removed.
Changed paths:
backends/platform/ios7/ios7_gamepad_controller.mm
diff --git a/backends/platform/ios7/ios7_gamepad_controller.mm b/backends/platform/ios7/ios7_gamepad_controller.mm
index 15113b5f25e..3c20ae4d2f2 100644
--- a/backends/platform/ios7/ios7_gamepad_controller.mm
+++ b/backends/platform/ios7/ios7_gamepad_controller.mm
@@ -140,29 +140,6 @@
// Set the frame alpha to the user specified value
// to make the virtual controller more transparent
view.alpha = ((float)ConfMan.getInt("gamepad_controller_opacity") / 10.0);
-
- // Since the iOS7 view controller frame is adjusted for the safe area, the same
- // has to be done for the gamepad controller view. One could think that subviews
- // would adjust automatically but it seems that the gamepad controller buttons
- // can be positioned outside the device screen if not adjusting manually.
- if (@available(iOS 11.0, *)) {
- UIEdgeInsets insets = [[[UIApplication sharedApplication] keyWindow] safeAreaInsets];
- UIInterfaceOrientation orientation = [iOS7AppDelegate currentOrientation];
-
- // Set anchor point to lower right corner
- view.layer.anchorPoint = CGPointMake(1, 1);
-
- // Specify the position of the view layer from the anchor point
- if (orientation == UIInterfaceOrientationLandscapeLeft) {
- view.layer.position = CGPointMake(view.frame.size.width, view.layer.position.y);
- } else if (orientation == UIInterfaceOrientationLandscapeRight) {
- // When a device with e.g. a sensor bar is rotated so the sensor bar
- // is to the left, we can adjust the anchor point a bit more to the left
- // to make the left thumb buttons be at the same distance from the screen
- // border.
- view.layer.position = CGPointMake(view.frame.size.width - insets.left, view.layer.position.y);
- }
- }
stop = YES;
} else {
// Keep drilling
Commit: fd867964ab74fa324b8fce21e3611a786c90fc33
https://github.com/scummvm/scummvm/commit/fd867964ab74fa324b8fce21e3611a786c90fc33
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
IOS7: Increase the margin for on-screen control buttons
The buttons now come much closer to the top right corner. Increase the
margin and make it consistent for all devices.
Changed paths:
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 9dedca12134..a9c7efb0f17 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -522,15 +522,13 @@ bool iOS7_fetchEvent(InternalEvent *event) {
CGFloat scale = [self contentScaleFactor];
iOS7_setSafeAreaInsets(inset.left * scale, inset.right * scale, inset.top * scale, 0);
- // Add margins to respect the iPhone and iPad safe areas. Use the right
- // safe area inset if available since the position of the buttons are
- // on the right hand side. The iPhone corners on the later models have
- // the form of squircles rather than circles which cause button images
- // to become cropped if placed too close to the corner.
- // iPads has a more rectangular screen form. The inset margin on iPads
- // is 0, however due to the rounding of the corners images gets cropped
- // if placed too close to the corners. Use a constant margin for those.
- const CGFloat margin = inset.right > 0 ? inset.right/4 : 10;
+ // Add a margin to the on-screen control buttons. The shape of the iPhone
+ // screen corners on the later models have the shape of squircles rather
+ // than circles which cause button images to become cropped if placed too
+ // close to the corner. iPads have 90 degrees screen corners and does have
+ // the same problem with cropped images. However add the same margin for
+ // consistency.
+ const CGFloat margin = 20;
// Touch mode button on top
[_toggleTouchModeButton setFrame:CGRectMake(self.frame.size.width - _toggleTouchModeButton.imageView.image.size.width - margin, margin, _toggleTouchModeButton.imageView.image.size.width, _toggleTouchModeButton.imageView.image.size.height)];
// Burger menu button below
Commit: 110a7773bffd0d598d48ce712a5b59160172d092
https://github.com/scummvm/scummvm/commit/110a7773bffd0d598d48ce712a5b59160172d092
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-07-13T17:26:37+02:00
Commit Message:
GUI: Handle safe area in popup dialogs
Changed paths:
gui/widgets/popup.cpp
diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp
index 4e5d4f629cb..843287e303f 100644
--- a/gui/widgets/popup.cpp
+++ b/gui/widgets/popup.cpp
@@ -74,13 +74,12 @@ void PopUpDialog::open() {
// FIXME - OSystem should send out notification messages when the screen
// resolution changes... we could generalize CommandReceiver and CommandSender.
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
+ Common::Rect safeArea = g_system->getSafeOverlayArea();
// HACK: For now, we do not do scrolling. Instead, we draw the dialog
// in two columns if it's too tall.
- if (_h >= screenH) {
+ if (_h >= safeArea.height()) {
_twoColumns = true;
_entriesPerColumn = _entries.size() / 2;
@@ -104,19 +103,19 @@ void PopUpDialog::open() {
_w = MAX<uint16>(_boss->getWidth(), _w + 20);
}
- if (_w >= screenW)
- _w = screenW - 1;
- if (_x < 0)
- _x = 0;
- if (_x + _w >= screenW)
- _x = screenW - 1 - _w;
-
- if (_h >= screenH)
- _h = screenH - 1;
- if (_y < 0)
- _y = 0;
- else if (_y + _h >= screenH)
- _y = screenH - 1 - _h;
+ if (_w >= safeArea.width())
+ _w = safeArea.width() - 1;
+ if (_x < safeArea.left)
+ _x = safeArea.left;
+ if (_x + _w >= safeArea.right)
+ _x = safeArea.right - 1 - _w;
+
+ if (_h >= safeArea.height())
+ _h = safeArea.height() - 1;
+ if (_y < safeArea.top)
+ _y = safeArea.top;
+ else if (_y + _h >= safeArea.bottom)
+ _y = safeArea.bottom - 1 - _h;
// TODO - implement scrolling if we had to move the menu, or if there are too many entries
More information about the Scummvm-git-logs
mailing list