diff --git a/installer/core/Interface/Translations/SoulsyHUD_czech.txt b/installer/core/Interface/Translations/SoulsyHUD_czech.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_czech.txt and b/installer/core/Interface/Translations/SoulsyHUD_czech.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_english.txt b/installer/core/Interface/Translations/SoulsyHUD_english.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_english.txt and b/installer/core/Interface/Translations/SoulsyHUD_english.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_french.txt b/installer/core/Interface/Translations/SoulsyHUD_french.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_french.txt and b/installer/core/Interface/Translations/SoulsyHUD_french.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_german.txt b/installer/core/Interface/Translations/SoulsyHUD_german.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_german.txt and b/installer/core/Interface/Translations/SoulsyHUD_german.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_italian.txt b/installer/core/Interface/Translations/SoulsyHUD_italian.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_italian.txt and b/installer/core/Interface/Translations/SoulsyHUD_italian.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_japanese.txt b/installer/core/Interface/Translations/SoulsyHUD_japanese.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_japanese.txt and b/installer/core/Interface/Translations/SoulsyHUD_japanese.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_polish.txt b/installer/core/Interface/Translations/SoulsyHUD_polish.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_polish.txt and b/installer/core/Interface/Translations/SoulsyHUD_polish.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_russian.txt b/installer/core/Interface/Translations/SoulsyHUD_russian.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_russian.txt and b/installer/core/Interface/Translations/SoulsyHUD_russian.txt differ diff --git a/installer/core/Interface/Translations/SoulsyHUD_spanish.txt b/installer/core/Interface/Translations/SoulsyHUD_spanish.txt index 612a180d..a15f034b 100644 Binary files a/installer/core/Interface/Translations/SoulsyHUD_spanish.txt and b/installer/core/Interface/Translations/SoulsyHUD_spanish.txt differ diff --git a/installer/core/mcm/config/SoulsyHUD/config.json b/installer/core/mcm/config/SoulsyHUD/config.json index eaa02b26..4a549614 100644 --- a/installer/core/mcm/config/SoulsyHUD/config.json +++ b/installer/core/mcm/config/SoulsyHUD/config.json @@ -368,6 +368,19 @@ "defaultValue": 0 } }, + { + "id": "fHudScale:Options", + "text": "$SoulsyHUD_Options_HudScale_Text", + "help": "$SoulsyHUD_Options_HudScale_Help", + "type": "slider", + "valueOptions": { + "min": 0.0, + "max": 1.0, + "step": 0.01, + "sourceType": "ModSettingFloat", + "formatString": "{2}" + } + }, { "id": "bAutoFade:Options", "text": "$SoulsyHUD_Options_Fade_Text", diff --git a/installer/core/mcm/config/SoulsyHUD/settings.ini b/installer/core/mcm/config/SoulsyHUD/settings.ini index 37d80d47..2b00576d 100644 --- a/installer/core/mcm/config/SoulsyHUD/settings.ini +++ b/installer/core/mcm/config/SoulsyHUD/settings.ini @@ -35,6 +35,7 @@ bCycleAmmo = 1 bColorizeIcons = 1 bEquipSetsUnequip = 1 uAnchorLocation = none +fHudScale = 0.0 sSKSEIdentifier = SOLS bDebugMode = 0 sLogLevel = info diff --git a/src/controller/settings.rs b/src/controller/settings.rs index a2b2ed3d..d97e7c4a 100644 --- a/src/controller/settings.rs +++ b/src/controller/settings.rs @@ -102,6 +102,8 @@ pub struct UserSettings { refresh_layout: u32, /// Layout anchor override. uAnchorLocation anchor_loc: NamedAnchor, + /// HUD scale override. fHudScale + scale_override: f32, /// The number of milliseconds to delay before equipping a selection. Max 2500, min 0. equip_delay_ms: u32, @@ -149,6 +151,7 @@ impl Default for UserSettings { equipset: 9, refresh_layout: 8, anchor_loc: NamedAnchor::None, + scale_override: 0.0, how_to_activate: ActivationMethod::Hotkey, activate: 4, activate_modifier: -1, @@ -249,6 +252,7 @@ impl UserSettings { self.showhide = read_from_ini(self.showhide, "uShowHideKey", controls); self.refresh_layout = read_from_ini(self.refresh_layout, "uRefreshKey", controls); self.anchor_loc = read_from_ini(self.anchor_loc.clone(), "uAnchorLocation", options); + self.scale_override = read_from_ini(self.scale_override, "fHudScale", options); self.unarmed_handling = read_from_ini(self.unarmed_handling, "uHowToUnequip", controls); self.unequip_modifier = @@ -484,6 +488,25 @@ impl UserSettings { pub fn resolution_scale(&self) -> f64 { self.display_tweaks.scale() } + + pub fn scale_override(&self) -> f32 { + self.scale_override + } + + /// Get the user-config aware, display-tweaks-aware scaling factor to use on all layouts. + pub fn hud_scale(&self) -> f32 { + let reso = self.resolution_scale(); + let display_scale = if self.is_upscaling() { + (reso * reso) as f32 + } else { + reso as f32 + }; + if self.scale_override() > 0.0 { + self.scale_override() * display_scale + } else { + display_scale + } + } } /// Generic for reading a typed value from the ini structure. @@ -679,6 +702,7 @@ impl std::fmt::Display for UserSettings { equipset cycle key: {} refresh layout key: {} layout anchor override: {} + layout scale override: {} how_to_activate: {} activate consumables: {} activate_modifier: {} @@ -688,7 +712,7 @@ impl std::fmt::Display for UserSettings { dual-wield on long press: {} how_to_toggle: {} menu_modifier: {} - link_to_favorites: {} + favorites in cycles: {} unarmed_handling: {} unequip_modifier: {} unequip_hotkey: {} @@ -714,6 +738,7 @@ impl std::fmt::Display for UserSettings { self.equipset, self.refresh_layout, self.anchor_loc, + self.scale_override, self.how_to_activate, self.activate, self.activate_modifier, diff --git a/src/layouts/layout_v1.rs b/src/layouts/layout_v1.rs index 1a375c83..9251cbe5 100644 --- a/src/layouts/layout_v1.rs +++ b/src/layouts/layout_v1.rs @@ -144,6 +144,10 @@ impl HudLayout1 { ) } + pub fn size(&self) -> Point { + self.size.clone() + } + fn flatten(&self, slot: &SlotLayout) -> SlotFlattened { let factor = self.scale_for_display(); let anchor = self.anchor_point(); @@ -213,15 +217,9 @@ impl HudLayout1 { } } - fn scale_for_display(&self) -> f32 { + pub fn scale_for_display(&self) -> f32 { let config = settings(); - let reso = config.resolution_scale(); - let display_scale = if config.is_upscaling() { - (reso * reso) as f32 - } else { - reso as f32 - }; - self.global_scale * display_scale + self.global_scale * config.hud_scale() } } diff --git a/src/layouts/layout_v2.rs b/src/layouts/layout_v2.rs index aec70310..d8a76a0c 100644 --- a/src/layouts/layout_v2.rs +++ b/src/layouts/layout_v2.rs @@ -108,6 +108,10 @@ impl HudLayout2 { Ok(parsed) } + pub fn size(&self) -> Point { + self.size.clone() + } + pub fn anchor_point(&self) -> Point { super::anchor_point( self.scale_for_display(), @@ -200,15 +204,9 @@ impl HudLayout2 { } } - fn scale_for_display(&self) -> f32 { + pub fn scale_for_display(&self) -> f32 { let config = settings(); - let reso = config.resolution_scale(); - let display_scale = if config.is_upscaling() { - (reso * reso) as f32 - } else { - reso as f32 - }; - self.global_scale * display_scale + self.global_scale * config.hud_scale() } } diff --git a/src/layouts/mod.rs b/src/layouts/mod.rs index f8737d35..aed62142 100644 --- a/src/layouts/mod.rs +++ b/src/layouts/mod.rs @@ -133,6 +133,21 @@ impl Layout { Layout::Version2(v) => v.anchor_point(), } } + + pub fn size(&self) -> Point { + match self { + Layout::Version1(v) => v.size(), + Layout::Version2(v) => v.size(), + } + } + + /// Get the settings-aware scale to use for this layout. + pub fn scale_for_display(&self) -> f32 { + match self { + Layout::Version1(v) => v.scale_for_display(), + Layout::Version2(v) => v.scale_for_display(), + } + } } /// An implementation detail of the anchor point calculation, used by both @@ -366,4 +381,31 @@ mod tests { let flattened = named.flatten(); assert_eq!(flattened.anchor, relocated); } + + #[test] + fn scaling_respects_settings() { + // override the defaults with what we need for this test + let _ = crate::controller::UserSettings::refresh_with("tests/fixtures/scale-settings.ini"); + let config = *user_settings(); + assert_eq!(config.scale_override(), 0.5); // this is the user setting + assert_eq!(config.hud_scale(), 0.5); // this is display-tweaks-aware + + let squarev1 = Layout::read_from_file("tests/fixtures/layout-v1.toml") + .expect("the original square layout can be loaded"); + let squarev2 = Layout::read_from_file( + "installer/core/SKSE/plugins/soulsy_layouts/SoulsyHUD_square.toml", + ) + .expect("the square layout has been ported"); + + assert_eq!(squarev2.scale_for_display(), 0.5); + assert_eq!(squarev1.scale_for_display(), squarev2.scale_for_display()); + + let flat1 = squarev1.flatten(); + let flat2 = squarev2.flatten(); + assert_eq!(flat2.global_scale, 0.5); + assert_eq!(flat1.global_scale, flat2.global_scale); + + assert_eq!(squarev1.size(), squarev2.size()); + assert_eq!(flat2.bg_size, squarev2.size().scale(0.5)); + } } diff --git a/tests/fixtures/scale-settings.ini b/tests/fixtures/scale-settings.ini new file mode 100644 index 00000000..f4b9c1ce --- /dev/null +++ b/tests/fixtures/scale-settings.ini @@ -0,0 +1,2 @@ +[Options] +fHudScale = 0.5 diff --git a/tests/fixtures/test-settings.ini b/tests/fixtures/test-settings.ini index b21707c3..84cf4df3 100644 --- a/tests/fixtures/test-settings.ini +++ b/tests/fixtures/test-settings.ini @@ -28,7 +28,6 @@ uHowToggleInMenus = 0 iMenuModifierKey = 42 iUtilityActivateModifier = 274 - [Equipsets] sLastEditedSetName = Mossy sLastUsedSetName = Spiky