diff --git a/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs b/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs index 0e50efe8f..2c166fb78 100644 --- a/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs +++ b/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs @@ -38,7 +38,8 @@ public static class QRMessageUtil { if (pk is PK7 pk7) { - byte[] payload = QR7.GenerateQRData(pk7); + Span payload = stackalloc byte[QR7.SIZE]; + QR7.SetQRData(pk7, payload); return GetMessage(payload); } diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8U.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8U.cs index b52b264b0..c3dc1fff4 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8U.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8U.cs @@ -75,7 +75,7 @@ public sealed record EncounterStatic8U : EncounterStatic8Nest return StringConverter8.GetTrashState(pk.OriginalTrainerTrash, name); } - private static ReadOnlySpan GetScientistName(int language) => language switch + public static ReadOnlySpan GetScientistName(int language) => language switch { (int)LanguageID.Japanese => "けんきゅういん", (int)LanguageID.English => "Scientist", diff --git a/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs b/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs index 341a4843f..0f1d1b128 100644 --- a/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs +++ b/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs @@ -53,7 +53,8 @@ public ref struct XorShift128 public readonly (uint x, uint y, uint z, uint w) GetState32() => (x, y, z, w); public readonly (ulong s0, ulong s1) GetState64() => (s0, s1); - public readonly string FullState => $"{State:X32}"; + public readonly UInt128 FullState() => State; + public readonly bool Equals(ulong state0, ulong state1) => s0 == state0 && s1 == state1; /// /// Gets the next random . diff --git a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus.cs b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus.cs index 63b9873ae..f66757484 100644 --- a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus.cs +++ b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus.cs @@ -1,6 +1,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace PKHeX.Core; @@ -8,17 +9,21 @@ namespace PKHeX.Core; /// Self-modifying RNG structure that implements xoroshiro128+ /// /// https://en.wikipedia.org/wiki/Xoroshiro128%2B +[StructLayout(LayoutKind.Explicit)] public ref struct Xoroshiro128Plus { public const ulong XOROSHIRO_CONST0= 0x0F4B17A579F18960; public const ulong XOROSHIRO_CONST = 0x82A2B175229D6A5B; - private ulong s0; - private ulong s1; + [FieldOffset(0x0)] private ulong s0; + [FieldOffset(0x8)] private ulong s1; + [FieldOffset(0x0)] public readonly UInt128 State; public Xoroshiro128Plus(ulong s0 = XOROSHIRO_CONST0, ulong s1 = XOROSHIRO_CONST) => (this.s0, this.s1) = (s0, s1); + public Xoroshiro128Plus(UInt128 state) => State = state; public readonly (ulong s0, ulong s1) GetState() => (s0, s1); public readonly UInt128 FullState() => new(s1, s0); + public readonly bool Equals(ulong state0, ulong state1) => s0 == state0 && s1 == state1; /// /// Gets the next random . diff --git a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs index a0159c252..27c103314 100644 --- a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs +++ b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs @@ -1,6 +1,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace PKHeX.Core; @@ -10,14 +11,17 @@ namespace PKHeX.Core; /// https://en.wikipedia.org/wiki/Xoroshiro128%2B /// /// Used by the Brilliant Diamond & Shining Pearl games; differs in how values are yielded by Next calls. +[StructLayout(LayoutKind.Explicit)] public ref struct Xoroshiro128Plus8b { - private ulong s0; - private ulong s1; + [FieldOffset(0x0)] private ulong s0; + [FieldOffset(0x8)] private ulong s1; + [FieldOffset(0x0)] public readonly UInt128 State; public Xoroshiro128Plus8b(ulong s0, ulong s1) => (this.s0, this.s1) = (s0, s1); + public Xoroshiro128Plus8b(UInt128 state) => State = state; public readonly (ulong s0, ulong s1) GetState() => (s0, s1); - public readonly UInt128 FullState() => new(s1, s0); + public readonly bool Equals(ulong state0, ulong state1) => s0 == state0 && s1 == state1; public Xoroshiro128Plus8b(ulong seed) { diff --git a/PKHeX.Core/Legality/Structures/CheckIdentifier.cs b/PKHeX.Core/Legality/Structures/CheckIdentifier.cs index ee9945a5e..bdca02bbe 100644 --- a/PKHeX.Core/Legality/Structures/CheckIdentifier.cs +++ b/PKHeX.Core/Legality/Structures/CheckIdentifier.cs @@ -158,4 +158,9 @@ public enum CheckIdentifier : byte /// The pertains to the values. /// AVs, + + /// + /// The pertains to string . + /// + TrashBytes, } diff --git a/PKHeX.Core/Saves/SAV3E.cs b/PKHeX.Core/Saves/SAV3E.cs index 0a7f5cbfa..feff41d84 100644 --- a/PKHeX.Core/Saves/SAV3E.cs +++ b/PKHeX.Core/Saves/SAV3E.cs @@ -140,10 +140,12 @@ public sealed class SAV3E : SAV3, IGen3Hoenn, IGen3Joyful, IGen3Wonder, IDaycare ]; } + private Span PokeBlockData => Large.AsSpan(0x848, PokeBlock3Case.SIZE); + public PokeBlock3Case PokeBlocks { - get => new(Large, 0x848); - set => SetData(Large.AsSpan(0x848), value.Write()); + get => new(PokeBlockData); + set => value.Write(PokeBlockData); } protected override int SeenOffset2 => 0x988; diff --git a/PKHeX.Core/Saves/SAV3RS.cs b/PKHeX.Core/Saves/SAV3RS.cs index 67ca7c73a..0e3d19d68 100644 --- a/PKHeX.Core/Saves/SAV3RS.cs +++ b/PKHeX.Core/Saves/SAV3RS.cs @@ -99,10 +99,12 @@ public sealed class SAV3RS : SAV3, IGen3Hoenn, IDaycareRandomState ]; } + private Span PokeBlockData => Large.AsSpan(0x7F8, PokeBlock3Case.SIZE); + public PokeBlock3Case PokeBlocks { - get => new(Large, 0x7F8); - set => SetData(Large.AsSpan(0x7F8), value.Write()); + get => new(PokeBlockData); + set => value.Write(PokeBlockData); } protected override int SeenOffset2 => 0x938; diff --git a/PKHeX.Core/Saves/Substructures/Gen3/DecorationInventory3.cs b/PKHeX.Core/Saves/Substructures/Gen3/DecorationInventory3.cs index 2290b7b56..fa245b911 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/DecorationInventory3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/DecorationInventory3.cs @@ -3,7 +3,6 @@ using System.Runtime.InteropServices; namespace PKHeX.Core; -[StructLayout(LayoutKind.Sequential)] public readonly ref struct DecorationInventory3 { public const int SIZE = 150; diff --git a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs index f4569001f..6127c0db1 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs @@ -5,18 +5,19 @@ namespace PKHeX.Core; public sealed class PokeBlock3Case { private const int Count = 40; + public const int SIZE = Count * PokeBlock3.SIZE; public readonly PokeBlock3[] Blocks; - public PokeBlock3Case(ReadOnlySpan data, int offset) + public PokeBlock3Case(ReadOnlySpan data) { Blocks = new PokeBlock3[Count]; for (int i = 0; i < Blocks.Length; i++) - Blocks[i] = PokeBlock3.GetBlock(data, offset + (i * PokeBlock3.SIZE)); + Blocks[i] = PokeBlock3.GetBlock(data, (i * PokeBlock3.SIZE)); } public byte[] Write() { - byte[] result = new byte[Count*PokeBlock3.SIZE]; + byte[] result = new byte[SIZE]; Write(result); return result; } diff --git a/PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs b/PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs index 628743e00..c0d710acd 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs @@ -1,12 +1,10 @@ using System; -using System.Runtime.InteropServices; using static PKHeX.Core.Move; using static PKHeX.Core.Species; using static System.Buffers.Binary.BinaryPrimitives; namespace PKHeX.Core; -[StructLayout(LayoutKind.Sequential, Pack = 4, Size = SIZE)] public sealed class Swarm3(byte[] Data) { public const int SIZE = 0x14; diff --git a/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs b/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs index 36350168c..576dd1ee3 100644 --- a/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs +++ b/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs @@ -28,7 +28,7 @@ public static class Xoroshiro128Tests for (int i = 0; i < loop; i++) { _ = rand.Prev(); - if (rand.GetState() == (s0, s1)) + if (rand.Equals(s0, s1)) return i; } return -1; diff --git a/Tests/PKHeX.Core.Tests/General/Xoroshiro128bTests.cs b/Tests/PKHeX.Core.Tests/General/Xoroshiro128bTests.cs index b3dd5cd79..b3c694a9c 100644 --- a/Tests/PKHeX.Core.Tests/General/Xoroshiro128bTests.cs +++ b/Tests/PKHeX.Core.Tests/General/Xoroshiro128bTests.cs @@ -27,7 +27,7 @@ public static class Xoroshiro128bTests for (int i = 0; i < loop; i++) { _ = rand.Prev(); - if (rand.GetState() == (s0, s1)) + if (rand.Equals(s0, s1)) return i; } return -1; @@ -39,7 +39,7 @@ public static class Xoroshiro128bTests for (int i = 0; i < loop; i++) { _ = rand.Next(); - if (rand.GetState() == (n0, n1)) + if (rand.Equals(n0, n1)) return i; } return -1;