diff --git a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs index 4a65834..a2616b5 100644 --- a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs @@ -4033,7 +4033,7 @@ public static partial class KernelMemoryCompatExports _ => unchecked((int)argumentSource.NextGpArg()) }; - var formatted = value.ToString(); + var formatted = value.ToString(CultureInfo.InvariantCulture); if (showSign && value >= 0) formatted = "+" + formatted; else if (spaceForSign && value >= 0) @@ -4053,7 +4053,7 @@ public static partial class KernelMemoryCompatExports _ => (uint)argumentSource.NextGpArg() }; - var formatted = value.ToString(); + var formatted = value.ToString(CultureInfo.InvariantCulture); sb.Append(PadString(formatted, width, leftAlign, padWithZero && !leftAlign)); } break; @@ -4070,8 +4070,8 @@ public static partial class KernelMemoryCompatExports }; var formatted = specifier == 'x' - ? value.ToString("x") - : value.ToString("X"); + ? value.ToString("x", CultureInfo.InvariantCulture) + : value.ToString("X", CultureInfo.InvariantCulture); if (alternateForm && value != 0) formatted = specifier == 'x' ? "0x" + formatted : "0X" + formatted; @@ -4175,7 +4175,10 @@ public static partial class KernelMemoryCompatExports var formatStr = precision >= 0 ? $"{{0:{specifier}{precision}}}" : $"{{0:{specifier}}}"; - var formatted = string.Format(formatStr, value); + var formatted = string.Format( + CultureInfo.InvariantCulture, + formatStr, + value); if (showSign && value >= 0) formatted = "+" + formatted; diff --git a/tests/SharpEmu.Libs.Tests/Kernel/KernelMemoryCompatExportsTests.cs b/tests/SharpEmu.Libs.Tests/Kernel/KernelMemoryCompatExportsTests.cs index 3d0ac43..9fbd33f 100644 --- a/tests/SharpEmu.Libs.Tests/Kernel/KernelMemoryCompatExportsTests.cs +++ b/tests/SharpEmu.Libs.Tests/Kernel/KernelMemoryCompatExportsTests.cs @@ -3,6 +3,7 @@ using SharpEmu.HLE; using SharpEmu.Libs.Kernel; +using System.Globalization; using System.Text; using Xunit; @@ -52,4 +53,38 @@ public sealed class KernelMemoryCompatExportsTests Assert.True(memory.TryRead(destinationAddress, output)); Assert.Equal("0.5576\0", Encoding.UTF8.GetString(output)); } + + [Fact] + public void Sprintf_UsesCLocaleForFloatingPoint() + { + var previousCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR"); + + const ulong memoryBase = 0x1_0000_0000; + const ulong destinationAddress = memoryBase + 0x100; + const ulong formatAddress = memoryBase + 0x200; + var memory = new FakeCpuMemory(memoryBase, 0x1000); + var context = new CpuContext(memory, Generation.Gen5); + memory.WriteCString(formatAddress, "%.4f"); + context[CpuRegister.Rdi] = destinationAddress; + context[CpuRegister.Rsi] = formatAddress; + context.SetXmmRegister( + 0, + unchecked((ulong)BitConverter.DoubleToInt64Bits(0.5576)), + 0); + + var result = KernelMemoryCompatExports.Sprintf(context); + + Assert.Equal(0, result); + Span output = stackalloc byte[7]; + Assert.True(memory.TryRead(destinationAddress, output)); + Assert.Equal("0.5576\0", Encoding.UTF8.GetString(output)); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + } }