From dbc6a2cea733faa9ca3a459bfc8e517c7fe21d40 Mon Sep 17 00:00:00 2001 From: Pierre Etchemaite Date: Sat, 17 Aug 2024 01:02:54 +0200 Subject: [PATCH 1/5] Fix game UI too low on narrow (<16:9) resolutions All the UI expect NativePanel to be aligned on the top of the screen, which is not the case for resolutions narrower than 16:10 (the ratio of 320:200). Explicitly align it to the top. --- Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs index 510b415541..a7c25af28e 100644 --- a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs +++ b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs @@ -140,6 +140,7 @@ public Panel DebugPanel public DaggerfallHUD(IUserInterfaceManager uiManager) :base(uiManager) { + NativePanel.VerticalAlignment = VerticalAlignment.Top; interactionModeIcon = new HUDInteractionModeIcon(crosshair); parentPanel.BackgroundColor = Color.clear; ShowPopupText = true; From 61e22df6684932bf4b3a45037808c9a427fc56fc Mon Sep 17 00:00:00 2001 From: Pierre Etchemaite Date: Sat, 17 Aug 2024 01:06:58 +0200 Subject: [PATCH 2/5] Fix and improve icons layouts One small issue found after fixing UI positioning, is that in 4:3 resolution the first debuff icon and the action mode icon overlap. Going back to classic Daggerfall, the first debuff icon is actually to the right of the first buff icon (in fact it's aligned with the 2nd buff icon). Matching classic actually fixes that small issue. What I was at it, improved the way icons adjust to the HUD by specifying whether they're anchored to the top, bottom, left or right of the screen. --- .../Game/UserInterface/HUDActiveSpells.cs | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs index 066b717c0f..ddcf27f2e5 100644 --- a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs +++ b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs @@ -189,49 +189,52 @@ bool ShowIcon(LiveEffectBundle bundle) return false; } + // For positions, negative X means "relative to right margin" (starting with -1) + // and negative Y means "relative to bottom margin" (starting with -1) void InitIcons() { switch (DaggerfallUnity.Settings.IconsPositioningScheme.ToLower()) { case "classic": // row of big buff icons at the top, wrapping downward, row of debuffs at the bottom, wrapping upward + // Debuffs start slightly to the right of buffs, which is a nice coincidence because it prevents overlap with action mode icon selfIconsPositioning = new IconsPositioning(new Vector2(16, 16), new Vector2(27, 16), new Vector2(24, 0), new Vector2(0, 24), 12); - otherIconsPositioning = new IconsPositioning(new Vector2(16, 16), new Vector2(27, 177), new Vector2(24, 0), new Vector2(0, -24), 12); + otherIconsPositioning = new IconsPositioning(new Vector2(16, 16), new Vector2(51, -8), new Vector2(24, 0), new Vector2(0, -24), 8); break; case "medium": // same as classic, slightly smaller icons selfIconsPositioning = new IconsPositioning(new Vector2(12, 12), new Vector2(27, 16), new Vector2(16, 0), new Vector2(0, 16), 16); - otherIconsPositioning = new IconsPositioning(new Vector2(12, 12), new Vector2(27, 177), new Vector2(16, 0), new Vector2(0, -16), 16); + otherIconsPositioning = new IconsPositioning(new Vector2(12, 12), new Vector2(51, -8), new Vector2(16, 0), new Vector2(0, -16), 12); break; case "small": // same as classic, even smaller icons, wrapped to stays on left side of screen selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 16), new Vector2(10, 0), new Vector2(0, 10), 6); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 177), new Vector2(10, 0), new Vector2(0, -10), 6); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(51, -8), new Vector2(10, 0), new Vector2(0, -10), 6); break; case "smalldeckleft": // same as small, but slightly slanted toward the center of the screen selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 28), new Vector2(10, -2), new Vector2(0, 10), 6); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 165), new Vector2(10, 2), new Vector2(0, -10), 6); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(51, -28), new Vector2(10, 2), new Vector2(0, -10), 6); break; case "smalldeckright": // same as smalldeckleft, but on the right side of screen - selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(296, 28), new Vector2(-10, -2), new Vector2(0, 10), 6); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(296, 165), new Vector2(-10, 2), new Vector2(0, -10), 6); + selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(-25, 28), new Vector2(-10, -2), new Vector2(0, 10), 6); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(-25, -28), new Vector2(-10, 2), new Vector2(0, -10), 6); break; case "smallvertleft": // Two aligned columns on the left, buffs going downward, debuffs going upward selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 16), new Vector2(0, 10), new Vector2(10, 0), 10); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 177), new Vector2(0, -10), new Vector2(10, 0), 4); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(51, -16), new Vector2(0, -10), new Vector2(10, 0), 4); break; case "smallvertright": // Two aligned columns on the right, buffs going downward, debuffs going upward - selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(296, 16), new Vector2(0, 10), new Vector2(-10, 0), 10); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(296, 177), new Vector2(0, -10), new Vector2(-10, 0), 4); + selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(-25, 16), new Vector2(0, 10), new Vector2(-10, 0), 10); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(-25, -28), new Vector2(0, -10), new Vector2(-10, 0), 4); break; case "smallhorzbottom": // No wrapping, two rows at the bottom of screen, debuffs above buffs - selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 177), new Vector2(10, 0), new Vector2(0, 0), 0); - otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(27, 167), new Vector2(10, 0), new Vector2(0, 0), 0); + selfIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(51, -18), new Vector2(10, 0), new Vector2(0, 0), 0); + otherIconsPositioning = new IconsPositioning(new Vector2(8, 8), new Vector2(51, -8), new Vector2(10, 0), new Vector2(0, 0), 0); break; } @@ -292,7 +295,7 @@ public void UpdateIcons() { LiveEffectBundle bundle = effectBundles[i]; - // Don't add effect icon for instant spells, must have at least 1 round remaining or be from an equipped item + // Don't add effect icon for instant spells, must have non-negative round remaining or be from an equipped item if (!ShowIcon(bundle)) continue; @@ -322,6 +325,14 @@ void AlignIcons(List icons, IconsPositioning iconsPositioning) { Vector2 rowOrigin = iconsPositioning.origin; Vector2 position = rowOrigin; + + float effectiveScreenRightX = Screen.width / LocalScale.x + 1; // + 1 so that -1 means right margin + float effectiveScreenBottomY = Screen.height; + if (DaggerfallUI.Instance.DaggerfallHUD != null && DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Enabled) + { + effectiveScreenBottomY -= (int)DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.ScreenHeight; + } + effectiveScreenBottomY = effectiveScreenBottomY / LocalScale.y + 1; // + 1 so that -1 means bottom margin int column = 0; foreach (ActiveSpellIcon spell in icons) { @@ -330,9 +341,13 @@ void AlignIcons(List icons, IconsPositioning iconsPositioning) Panel icon = iconPool[spell.poolIndex]; icon.Enabled = true; icon.BackgroundTexture = DaggerfallUI.Instance.SpellIconCollection.GetSpellIcon(spell.icon); - icon.Position = position; - AdjustIconPositionForLargeHUD(icon); + Vector2 positionEffective = position; icon.Size = iconsPositioning.iconSize; + if (positionEffective.x < 0) + positionEffective.x += effectiveScreenRightX - icon.Size.x; + if (positionEffective.y < 0) + positionEffective.y += effectiveScreenBottomY - icon.Size.y; + icon.Position = positionEffective; icon.ToolTipText = spell.displayName; if (++column == iconsPositioning.iconColumns) { @@ -348,20 +363,6 @@ void AlignIcons(List icons, IconsPositioning iconsPositioning) } } - void AdjustIconPositionForLargeHUD(Panel icon) - { - // Adjust position for variable sized large HUD - // Icon will remain in default position unless it needs to avoid being drawn under HUD - if (DaggerfallUI.Instance.DaggerfallHUD != null && DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Enabled) - { - float startY = icon.Position.y; - float offset = Screen.height - (int)DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Rectangle.height; - float localY = (offset / LocalScale.y) - 18; - if (localY < startY) - icon.Position = new Vector2(icon.Position.x, (int)localY); - } - } - private void SaveLoadManager_OnLoad(SaveData_v1 saveData) { UpdateIcons(); From 6e0b204887b33f8c93a72f90c94dc6dc4a2b2556 Mon Sep 17 00:00:00 2001 From: Pierre Etchemaite Date: Fri, 27 Dec 2024 00:39:39 +0100 Subject: [PATCH 3/5] Revert use LargeHUD.Rectangle.height LargeHUD.ScreenHeight can be 0 right after you enable the large HUD, so use LargeHUD.Rectangle.height instead, as before. --- Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs index ddcf27f2e5..105ff4612f 100644 --- a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs +++ b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs @@ -330,7 +330,7 @@ void AlignIcons(List icons, IconsPositioning iconsPositioning) float effectiveScreenBottomY = Screen.height; if (DaggerfallUI.Instance.DaggerfallHUD != null && DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Enabled) { - effectiveScreenBottomY -= (int)DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.ScreenHeight; + effectiveScreenBottomY -= (int)DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Rectangle.height; } effectiveScreenBottomY = effectiveScreenBottomY / LocalScale.y + 1; // + 1 so that -1 means bottom margin int column = 0; From b2f387a22900d3b9fd6ba82515357ab79fdd5bc2 Mon Sep 17 00:00:00 2001 From: Pierre Etchemaite Date: Fri, 27 Dec 2024 00:43:56 +0100 Subject: [PATCH 4/5] DaggerfallHUD: Use 320x240 NativePanel With 320x200 activeSpells panel, icons can fall below the panel and bad things occur (say missing tooltips). Given LocalScale, activeSpells, like the NativePanel, need to be 320x240 to cover the whole screen in narrow resolutions, but it's unclear for me if that's intended, or if they're supposed to be 320x200 but stretched, or even something else. --- Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs index a7c25af28e..a72bb310cc 100644 --- a/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs +++ b/Assets/Scripts/Game/UserInterfaceWindows/DaggerfallHUD.cs @@ -138,7 +138,7 @@ public Panel DebugPanel } public DaggerfallHUD(IUserInterfaceManager uiManager) - :base(uiManager) + :base(uiManager, 320, 240) { NativePanel.VerticalAlignment = VerticalAlignment.Top; interactionModeIcon = new HUDInteractionModeIcon(crosshair); From 1f81fc8ffa5de09fa308dad89e1dede41f78c15d Mon Sep 17 00:00:00 2001 From: Pierre Etchemaite Date: Fri, 27 Dec 2024 01:29:21 +0100 Subject: [PATCH 5/5] Remove useless rounding --- Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs index 105ff4612f..b66047d9d9 100644 --- a/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs +++ b/Assets/Scripts/Game/UserInterface/HUDActiveSpells.cs @@ -330,7 +330,7 @@ void AlignIcons(List icons, IconsPositioning iconsPositioning) float effectiveScreenBottomY = Screen.height; if (DaggerfallUI.Instance.DaggerfallHUD != null && DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Enabled) { - effectiveScreenBottomY -= (int)DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Rectangle.height; + effectiveScreenBottomY -= DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.Rectangle.height; } effectiveScreenBottomY = effectiveScreenBottomY / LocalScale.y + 1; // + 1 so that -1 means bottom margin int column = 0;