From 44a3c3a1eecb51e551c83c894ca8a98a14b65750 Mon Sep 17 00:00:00 2001 From: Infi Date: Sat, 4 May 2024 06:22:53 +0200 Subject: [PATCH] Fix RGB returning wrong color and change it to RGBA (#1793) * FIx RGB returning wrong color and change it to RGBA * Don't use the old RGB variable * Fix UIGlowPayload too * Add RGBA to ABGR helper and new method for glow/foreground to expose it directly * Move from Utils to ColorHelpers * Rename the function --- .../Payloads/UIForegroundPayload.cs | 12 +++++++--- .../Payloads/UIGlowPayload.cs | 12 +++++++--- Dalamud/Interface/ColorHelpers.cs | 17 ++++++++++--- Dalamud/Utility/Util.cs | 24 +++++++++---------- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs index 0586089f8..1cd96a81a 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/UIForegroundPayload.cs @@ -77,15 +77,21 @@ public class UIForegroundPayload : Payload } /// - /// Gets the Red/Green/Blue values for this foreground color, encoded as a typical hex color. + /// Gets the Red/Green/Blue/Alpha values for this foreground color, encoded as a typical hex color. /// [JsonIgnore] - public uint RGB => this.UIColor.UIForeground & 0xFFFFFF; + public uint RGBA => this.UIColor.UIForeground; + + /// + /// Gets the ABGR value for this foreground color, as ImGui requires it in PushColor. + /// + [JsonIgnore] + public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIForeground); /// public override string ToString() { - return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGB : 0)}"; + return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGBA : 0)}"; } /// diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs index 0d9081c08..68ed983ff 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/UIGlowPayload.cs @@ -68,10 +68,16 @@ public class UIGlowPayload : Payload public bool IsEnabled => this.ColorKey != 0; /// - /// Gets the Red/Green/Blue values for this glow color, encoded as a typical hex color. + /// Gets the Red/Green/Blue/Alpha values for this glow color, encoded as a typical hex color. /// [JsonIgnore] - public uint RGB => this.UIColor.UIGlow & 0xFFFFFF; + public uint RGBA => this.UIColor.UIGlow; + + /// + /// Gets the ABGR value for this glow color, as ImGui requires it in PushColor. + /// + [JsonIgnore] + public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIGlow); /// /// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIGlow. @@ -85,7 +91,7 @@ public class UIGlowPayload : Payload /// public override string ToString() { - return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGB : 0)}"; + return $"{this.Type} - UIColor: {this.colorKey} color: {(this.IsEnabled ? this.RGBA : 0)}"; } /// diff --git a/Dalamud/Interface/ColorHelpers.cs b/Dalamud/Interface/ColorHelpers.cs index 74561f9ef..971e546bc 100644 --- a/Dalamud/Interface/ColorHelpers.cs +++ b/Dalamud/Interface/ColorHelpers.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Numerics; @@ -159,6 +160,16 @@ public static class ColorHelpers return new Vector4(r, g, b, hsv.A); } + /// + /// Performs a swap of endianness + /// Exmaple: + /// (FFXIV) RGBA to ABGR (ImGui) + /// + /// Color value in byte order X Y Z W. + /// Endian swapped color value with new byte order W Z Y X. + public static uint SwapEndianness(uint rgba) + => BinaryPrimitives.ReverseEndianness(rgba); + /// /// Lighten a color. /// @@ -259,7 +270,7 @@ public static class ColorHelpers hsv.A -= amount; return HsvToRgb(hsv); } - + /// /// Set alpha of a color. /// @@ -299,10 +310,10 @@ public static class ColorHelpers { // If any components are out of range, return original value. { W: > 255.0f or < 0.0f } or { X: > 255.0f or < 0.0f } or { Y: > 255.0f or < 0.0f } or { Z: > 255.0f or < 0.0f } => color, - + // If all components are already unit range, return original value. { W: >= 0.0f and <= 1.0f, X: >= 0.0f and <= 1.0f, Y: >= 0.0f and <= 1.0f, Z: >= 0.0f and <= 1.0f } => color, - + _ => color / 255.0f, }; } diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index 3c3efada4..a7812bec3 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -476,12 +476,12 @@ public static class Util case "MacOS": return OSPlatform.OSX; case "Linux": return OSPlatform.Linux; } - + // n.b. we had some fancy code here to check if the Wine host version returned "Darwin" but apparently // *all* our Wines report Darwin if exports aren't hidden. As such, it is effectively impossible (without some // (very cursed and inaccurate heuristics) to determine if we're on macOS or Linux unless we're explicitly told // by our launcher. See commit a7aacb15e4603a367e2f980578271a9a639d8852 for the old check. - + return IsWine() ? OSPlatform.Linux : OSPlatform.Windows; } @@ -544,7 +544,7 @@ public static class Util } } } - } + } finally { foreach (var enumerator in enumerators) @@ -585,7 +585,7 @@ public static class Util { WriteAllTextSafe(path, text, Encoding.UTF8); } - + /// /// Overwrite text in a file by first writing it to a temporary file, and then /// moving that file to the path specified. @@ -597,7 +597,7 @@ public static class Util { WriteAllBytesSafe(path, encoding.GetBytes(text)); } - + /// /// Overwrite data in a file by first writing it to a temporary file, and then /// moving that file to the path specified. @@ -607,13 +607,13 @@ public static class Util public static unsafe void WriteAllBytesSafe(string path, byte[] bytes) { ArgumentException.ThrowIfNullOrEmpty(path); - + // Open the temp file var tempPath = path + ".tmp"; using var tempFile = Windows.Win32.PInvoke.CreateFile( - tempPath, - (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), + tempPath, + (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), FILE_SHARE_MODE.FILE_SHARE_NONE, null, FILE_CREATION_DISPOSITION.CREATE_ALWAYS, @@ -622,7 +622,7 @@ public static class Util if (tempFile.IsInvalid) throw new Win32Exception(); - + // Write the data uint bytesWritten = 0; if (!Windows.Win32.PInvoke.WriteFile(tempFile, new ReadOnlySpan(bytes), &bytesWritten, null)) @@ -633,7 +633,7 @@ public static class Util if (!Windows.Win32.PInvoke.FlushFileBuffers(tempFile)) throw new Win32Exception(); - + tempFile.Close(); if (!Windows.Win32.PInvoke.MoveFileEx(tempPath, path, MOVE_FILE_FLAGS.MOVEFILE_REPLACE_EXISTING | MOVE_FILE_FLAGS.MOVEFILE_WRITE_THROUGH)) @@ -750,7 +750,7 @@ public static class Util "-", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, - null, + null, new[] { typeof(object), typeof(IList), typeof(ulong) }, obj.GetType(), true); @@ -907,7 +907,7 @@ public static class Util } } } - + /// /// Show a structure in an ImGui context. ///