diff --git a/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs b/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs index cd1a6ce1a..9b6fd3f5d 100644 --- a/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs +++ b/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs @@ -12,6 +12,7 @@ public sealed class FakeSaveFile : SaveFile public override string ChecksumInfo => string.Empty; public override byte Generation => 3; public override string GetString(ReadOnlySpan data) => string.Empty; + public override int LoadString(ReadOnlySpan data, Span destBuffer) => 0; public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => 0; public override PersonalTable3 Personal => PersonalTable.RS; public override int MaxEV => 0; diff --git a/PKHeX.Core/PKM/BK4.cs b/PKHeX.Core/PKM/BK4.cs index a98ee838c..0f6977e2e 100644 --- a/PKHeX.Core/PKM/BK4.cs +++ b/PKHeX.Core/PKM/BK4.cs @@ -301,4 +301,11 @@ public PK4 ConvertToPK4() pk4.RefreshChecksum(); return pk4; } + + public override string GetString(ReadOnlySpan data) + => StringConverter4.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter4.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/CK3.cs b/PKHeX.Core/PKM/CK3.cs index 579d828a5..2386c1a21 100644 --- a/PKHeX.Core/PKM/CK3.cs +++ b/PKHeX.Core/PKM/CK3.cs @@ -228,4 +228,11 @@ public PK3 ConvertToPK3() pk.RefreshChecksum(); return pk; } + + public override string GetString(ReadOnlySpan data) + => StringConverter3GC.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3GC.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter3GC.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/HOME/PKH.cs b/PKHeX.Core/PKM/HOME/PKH.cs index 54fa84071..304ada15d 100644 --- a/PKHeX.Core/PKM/HOME/PKH.cs +++ b/PKHeX.Core/PKM/HOME/PKH.cs @@ -423,4 +423,11 @@ private void EnsureScaleSizeExists() WeightScalar = PokeSizeUtil.GetRandomScalar(rnd); } } + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PA8.cs b/PKHeX.Core/PKM/PA8.cs index a0766cbd9..9e22286f4 100644 --- a/PKHeX.Core/PKM/PA8.cs +++ b/PKHeX.Core/PKM/PA8.cs @@ -582,7 +582,6 @@ public bool BelongsTo(ITrainerInfo tr) return tr.OT == OriginalTrainerName; } - public void UpdateHandler(ITrainerInfo tr) { // Process to the HT if the OT of the Pokémon does not match the SAV's OT info. @@ -734,4 +733,11 @@ public void SetMasteryFlagMove(ushort move) if (permit.IsRecordPermitted(flagIndex)) SetMasteredRecordFlag(flagIndex, true); } + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PB7.cs b/PKHeX.Core/PKM/PB7.cs index a8d1eee74..5a49358ac 100644 --- a/PKHeX.Core/PKM/PB7.cs +++ b/PKHeX.Core/PKM/PB7.cs @@ -6,7 +6,7 @@ namespace PKHeX.Core; /// Generation 7 format used for . public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite, - IFormArgument, IAppliedMarkings7, IHandlerUpdate + IFormArgument, IAppliedMarkings7 { public override ReadOnlySpan ExtraBytes => [ @@ -581,4 +581,11 @@ public static int GetRandomIndex(int bits, int characterIndex, Nature nature) 5 => 4, _ => throw new ArgumentOutOfRangeException(nameof(characterIndex)), // never happens, characteristic is always 0-29 }; + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PB8.cs b/PKHeX.Core/PKM/PB8.cs index ece5561cc..1969aef21 100644 --- a/PKHeX.Core/PKM/PB8.cs +++ b/PKHeX.Core/PKM/PB8.cs @@ -146,4 +146,11 @@ private void TradeHT(ITrainerInfo tr) public override bool WasEgg => IsEgg || EggDay != 0; public override bool HasOriginalMetLocation => base.HasOriginalMetLocation && !(LA && MetLocation == LocationsHOME.SWLA); + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PK1.cs b/PKHeX.Core/PKM/PK1.cs index 13eb509c5..4f824c8d4 100644 --- a/PKHeX.Core/PKM/PK1.cs +++ b/PKHeX.Core/PKM/PK1.cs @@ -248,16 +248,12 @@ private string GetTransferTrainerName(int lang) return StringConverter12Transporter.GetString(OriginalTrainerTrash, Japanese); } - protected override string GetString(ReadOnlySpan data) - { - return StringConverter1.GetString(data, Japanese); - } - - protected override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, - StringConverterOption option = StringConverterOption.None) - { - return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); - } + public override string GetString(ReadOnlySpan data) + => StringConverter1.GetString(data, Japanese); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter1.LoadString(data, destBuffer, Japanese); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option = StringConverterOption.None) + => StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); /// /// Gets a checksum over all the entity's data using a single list to wrap all components. diff --git a/PKHeX.Core/PKM/PK2.cs b/PKHeX.Core/PKM/PK2.cs index 0b907bad1..7afd9e0fd 100644 --- a/PKHeX.Core/PKM/PK2.cs +++ b/PKHeX.Core/PKM/PK2.cs @@ -259,15 +259,21 @@ public SK2 ConvertToSK2() => new(Japanese) OriginalTrainerName = OriginalTrainerName, }; - protected override string GetString(ReadOnlySpan data) + public override string GetString(ReadOnlySpan data) { if (Korean) return StringConverter2KOR.GetString(data); return StringConverter2.GetString(data, Language); } - protected override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, - StringConverterOption option = StringConverterOption.None) + public override int LoadString(ReadOnlySpan data, Span destBuffer) + { + if (Korean) + return StringConverter2KOR.LoadString(data, destBuffer); + return StringConverter2.LoadString(data, destBuffer, Language); + } + + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) { if (Korean) return StringConverter2KOR.SetString(destBuffer, value, maxLength, option); diff --git a/PKHeX.Core/PKM/PK3.cs b/PKHeX.Core/PKM/PK3.cs index 9d7d2e7e7..18298a153 100644 --- a/PKHeX.Core/PKM/PK3.cs +++ b/PKHeX.Core/PKM/PK3.cs @@ -353,4 +353,11 @@ public CK3 ConvertToCK3() pk.ResetPartyStats(); return pk; } + + public override string GetString(ReadOnlySpan data) + => StringConverter3.GetString(data, Language); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3.LoadString(data, destBuffer, Language); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter3.SetString(destBuffer, value, maxLength, Language, option); } diff --git a/PKHeX.Core/PKM/PK4.cs b/PKHeX.Core/PKM/PK4.cs index ec9e098e6..4b2e54fd6 100644 --- a/PKHeX.Core/PKM/PK4.cs +++ b/PKHeX.Core/PKM/PK4.cs @@ -383,4 +383,11 @@ public static void TransferTrash(ReadOnlySpan src, Span dest) StringConverter345.TransferGlyphs45(temp[..len]); StringConverter5.SetString(dest, temp[..len], len); } + + public override string GetString(ReadOnlySpan data) + => StringConverter4.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter4.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PK5.cs b/PKHeX.Core/PKM/PK5.cs index c72408631..c957c924c 100644 --- a/PKHeX.Core/PKM/PK5.cs +++ b/PKHeX.Core/PKM/PK5.cs @@ -552,4 +552,11 @@ internal static ushort GetTransferMetLocation4(PKM pk) _ => Locations.Transfer4, }; } + + public override string GetString(ReadOnlySpan data) + => StringConverter5.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter5.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter5.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PK6.cs b/PKHeX.Core/PKM/PK6.cs index 68c406e98..fee9bb976 100644 --- a/PKHeX.Core/PKM/PK6.cs +++ b/PKHeX.Core/PKM/PK6.cs @@ -523,4 +523,11 @@ public PK7 ConvertToPK7() return pk7; // Done! } + + public override string GetString(ReadOnlySpan data) + => StringConverter6.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter6.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter6.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PK7.cs b/PKHeX.Core/PKM/PK7.cs index d792afd97..ffada70e2 100644 --- a/PKHeX.Core/PKM/PK7.cs +++ b/PKHeX.Core/PKM/PK7.cs @@ -547,6 +547,13 @@ internal void SetTransferPID(bool isShiny) break; } } + + public override string GetString(ReadOnlySpan data) + => StringConverter7.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter7.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter7.SetString(destBuffer, value, maxLength, Language); } public enum ResortEventState : byte diff --git a/PKHeX.Core/PKM/PK8.cs b/PKHeX.Core/PKM/PK8.cs index e58e4b189..a74c69034 100644 --- a/PKHeX.Core/PKM/PK8.cs +++ b/PKHeX.Core/PKM/PK8.cs @@ -129,4 +129,11 @@ private void TradeHT(ITrainerInfo tr) public override bool BDSP => MetLocation is LocationsHOME.SWBD or LocationsHOME.SHSP; public override bool LA => MetLocation is LocationsHOME.SWLA; public override bool HasOriginalMetLocation => base.HasOriginalMetLocation && !(BDSP || LA); + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PK9.cs b/PKHeX.Core/PKM/PK9.cs index c555686ad..3e4ce5175 100644 --- a/PKHeX.Core/PKM/PK9.cs +++ b/PKHeX.Core/PKM/PK9.cs @@ -681,4 +681,11 @@ private void TradeHT(ITrainerInfo tr) public override int MaxItemID => Legal.MaxItemID_9; public override int MaxBallID => Legal.MaxBallID_9; public override GameVersion MaxGameID => Legal.MaxGameID_HOME; + + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index 0f3837615..12538ae26 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -11,7 +11,7 @@ namespace PKHeX.Core; /// Object representing a 's data and derived properties. /// [DynamicallyAccessedMembers(PublicProperties | NonPublicProperties | PublicParameterlessConstructor)] -public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter +public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter, IStringConverter { /// /// Valid file extensions that represent data, without the leading '.' @@ -148,6 +148,10 @@ private byte[] Write() public virtual byte Fullness { get => 0; set { } } public virtual int AbilityNumber { get => 0; set { } } + public abstract string GetString(ReadOnlySpan data); + public abstract int LoadString(ReadOnlySpan data, Span text); + public abstract int SetString(Span data, ReadOnlySpan text, int length, StringConverterOption option); + /// /// The date the Pokémon was met. /// diff --git a/PKHeX.Core/PKM/RK4.cs b/PKHeX.Core/PKM/RK4.cs index 5e601f138..24052bac0 100644 --- a/PKHeX.Core/PKM/RK4.cs +++ b/PKHeX.Core/PKM/RK4.cs @@ -345,4 +345,11 @@ public PK4 ConvertToPK4() pk4.RefreshChecksum(); return pk4; } + + public override string GetString(ReadOnlySpan data) + => StringConverter4.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter4.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/PKM/SK2.cs b/PKHeX.Core/PKM/SK2.cs index 7e169ec7e..0b9cbfb24 100644 --- a/PKHeX.Core/PKM/SK2.cs +++ b/PKHeX.Core/PKM/SK2.cs @@ -212,4 +212,11 @@ private static bool IsEnglish(ReadOnlySpan data) public bool IsPossible(bool japanese) => japanese ? IsJapanese(Data) : IsEnglish(Data); public void SwapLanguage() => IsEncodingJapanese ^= true; + + public override string GetString(ReadOnlySpan data) + => StringConverter2.GetString(data, Language); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter2.LoadString(data, destBuffer, Language); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter2.SetString(destBuffer, value, maxLength, Language, option); } diff --git a/PKHeX.Core/PKM/Shared/GBPKML.cs b/PKHeX.Core/PKM/Shared/GBPKML.cs index 6a4cd8187..470541d18 100644 --- a/PKHeX.Core/PKM/Shared/GBPKML.cs +++ b/PKHeX.Core/PKM/Shared/GBPKML.cs @@ -61,11 +61,6 @@ protected override void GetNonNickname(int language, Span data) } } - protected abstract string GetString(ReadOnlySpan data); - - protected abstract int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, - StringConverterOption option = StringConverterOption.None); - public sealed override string Nickname { get => GetString(NicknameTrash); diff --git a/PKHeX.Core/PKM/Strings/IStringConverter.cs b/PKHeX.Core/PKM/Strings/IStringConverter.cs new file mode 100644 index 000000000..f0affee29 --- /dev/null +++ b/PKHeX.Core/PKM/Strings/IStringConverter.cs @@ -0,0 +1,10 @@ +using System; + +namespace PKHeX.Core; + +public interface IStringConverter +{ + string GetString(ReadOnlySpan data); + int LoadString(ReadOnlySpan data, Span text); + int SetString(Span data, ReadOnlySpan text, int length, StringConverterOption option); +} diff --git a/PKHeX.Core/PKM/XK3.cs b/PKHeX.Core/PKM/XK3.cs index 2bf6dde42..3fef88788 100644 --- a/PKHeX.Core/PKM/XK3.cs +++ b/PKHeX.Core/PKM/XK3.cs @@ -232,4 +232,11 @@ public PK3 ConvertToPK3() 90 or 91 or 92 => true, // Pokespot: Rock / Oasis / Cave _ => false, }; + + public override string GetString(ReadOnlySpan data) + => StringConverter3GC.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3GC.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter3GC.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/Saves/SAV1.cs b/PKHeX.Core/Saves/SAV1.cs index 3cad08301..56b154b5d 100644 --- a/PKHeX.Core/Saves/SAV1.cs +++ b/PKHeX.Core/Saves/SAV1.cs @@ -547,10 +547,10 @@ public bool[] EventSpawnFlags } } - public override string GetString(ReadOnlySpan data) => StringConverter1.GetString(data, Japanese); - + public override string GetString(ReadOnlySpan data) + => StringConverter1.GetString(data, Japanese); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter1.LoadString(data, destBuffer, Japanese); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); - } + => StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); } diff --git a/PKHeX.Core/Saves/SAV2.cs b/PKHeX.Core/Saves/SAV2.cs index e6ab9b708..a81e88b75 100644 --- a/PKHeX.Core/Saves/SAV2.cs +++ b/PKHeX.Core/Saves/SAV2.cs @@ -580,15 +580,8 @@ public override int PartyCount get => Data[Offsets.Party]; protected set => Data[Offsets.Party] = (byte)value; } - public override int GetBoxOffset(int box) - { - return (box * SIZE_BOX_AS_SINGLES); - } - - public override int GetPartyOffset(int slot) - { - return (BoxCount * SIZE_BOX_AS_SINGLES) + (slot * SIZE_STORED); - } + public override int GetBoxOffset(int box) => box * SIZE_BOX_AS_SINGLES; + public override int GetPartyOffset(int slot) => (BoxCount * SIZE_BOX_AS_SINGLES) + (slot * SIZE_STORED); public override int CurrentBox { @@ -801,6 +794,13 @@ public override string GetString(ReadOnlySpan data) return StringConverter2.GetString(data, Language); } + public override int LoadString(ReadOnlySpan data, Span text) + { + if (Korean) + return StringConverter2KOR.LoadString(data, text); + return StringConverter2.LoadString(data, text, Language); + } + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) { if (Korean) diff --git a/PKHeX.Core/Saves/SAV3.cs b/PKHeX.Core/Saves/SAV3.cs index 4e94078e9..c68004b54 100644 --- a/PKHeX.Core/Saves/SAV3.cs +++ b/PKHeX.Core/Saves/SAV3.cs @@ -600,12 +600,12 @@ public byte PokedexNationalMagicFRLG public abstract bool NationalDex { get; set; } #endregion - public sealed override string GetString(ReadOnlySpan data) => StringConverter3.GetString(data, Japanese); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter3.GetString(data, Japanese); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3.LoadString(data, destBuffer, Japanese); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option); - } + => StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option); protected abstract int MailOffset { get; } public int GetMailOffset(int index) => (index * Mail3.SIZE) + MailOffset; diff --git a/PKHeX.Core/Saves/SAV3Colosseum.cs b/PKHeX.Core/Saves/SAV3Colosseum.cs index 3584b143f..babf933ae 100644 --- a/PKHeX.Core/Saves/SAV3Colosseum.cs +++ b/PKHeX.Core/Saves/SAV3Colosseum.cs @@ -288,10 +288,10 @@ public override IReadOnlyList Inventory public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data[(DaycareOffset + 4)..], value); public Memory GetDaycareSlot(int slot) => Raw.Slice(DaycareOffset + 8, PokeCrypto.SIZE_3CSTORED); - public override string GetString(ReadOnlySpan data) => StringConverter3GC.GetString(data); - + public override string GetString(ReadOnlySpan data) + => StringConverter3GC.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3GC.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter3GC.SetString(destBuffer, value, maxLength, option); - } + => StringConverter3GC.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/Saves/SAV3RSBox.cs b/PKHeX.Core/Saves/SAV3RSBox.cs index 3a3b34d93..da4e7f990 100644 --- a/PKHeX.Core/Saves/SAV3RSBox.cs +++ b/PKHeX.Core/Saves/SAV3RSBox.cs @@ -207,10 +207,10 @@ public override void WriteBoxSlot(PKM pk, Span data) WriteUInt16LittleEndian(data[(PokeCrypto.SIZE_3STORED + 2)..], pk.SID16); } - public override string GetString(ReadOnlySpan data) => StringConverter3.GetString(data, Japanese); - + public override string GetString(ReadOnlySpan data) + => StringConverter3.GetString(data, Japanese); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3.LoadString(data, destBuffer, Japanese); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option); - } + => StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option); } diff --git a/PKHeX.Core/Saves/SAV3XD.cs b/PKHeX.Core/Saves/SAV3XD.cs index efd715a91..036aefd3d 100644 --- a/PKHeX.Core/Saves/SAV3XD.cs +++ b/PKHeX.Core/Saves/SAV3XD.cs @@ -452,10 +452,10 @@ public override IReadOnlyList Inventory public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data.AsSpan(DaycareOffset + 4), value); public Memory GetDaycareSlot(int slot) => Data.AsMemory(DaycareOffset + 8, PokeCrypto.SIZE_3XSTORED); - public override string GetString(ReadOnlySpan data) => StringConverter3GC.GetString(data); - + public override string GetString(ReadOnlySpan data) + => StringConverter3GC.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter3GC.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter3GC.SetString(destBuffer, value, maxLength, option); - } + => StringConverter3GC.SetString(destBuffer, value, maxLength, option); } diff --git a/PKHeX.Core/Saves/SAV4.cs b/PKHeX.Core/Saves/SAV4.cs index 626514ef7..c15356832 100644 --- a/PKHeX.Core/Saves/SAV4.cs +++ b/PKHeX.Core/Saves/SAV4.cs @@ -478,12 +478,12 @@ public int DexUpgraded } } - public sealed override string GetString(ReadOnlySpan data) => StringConverter4.GetString(data); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter4.GetString(data); + public sealed override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4.LoadString(data, destBuffer); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter4.SetString(destBuffer, value, maxLength, option); - } + => StringConverter4.SetString(destBuffer, value, maxLength, option); #region Event Flag/Event Work public bool GetEventFlag(int flagNumber) diff --git a/PKHeX.Core/Saves/SAV4BR.cs b/PKHeX.Core/Saves/SAV4BR.cs index 6c5c3a169..08c1efd01 100644 --- a/PKHeX.Core/Saves/SAV4BR.cs +++ b/PKHeX.Core/Saves/SAV4BR.cs @@ -367,7 +367,10 @@ private static void ComputeChecksums(Span span, Span checksums) } } - public override string GetString(ReadOnlySpan data) => StringConverter4GC.GetStringUnicode(data); - - public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option); + public override string GetString(ReadOnlySpan data) + => StringConverter4GC.GetStringUnicode(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4GC.LoadStringUnicode(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option); } diff --git a/PKHeX.Core/Saves/SAV5.cs b/PKHeX.Core/Saves/SAV5.cs index 1a06a8eb0..45e20a323 100644 --- a/PKHeX.Core/Saves/SAV5.cs +++ b/PKHeX.Core/Saves/SAV5.cs @@ -117,12 +117,12 @@ protected override void SetPKM(PKM pk, bool isParty = false) public override bool GetCaught(ushort species) => Zukan.GetCaught(species); public override bool GetSeen(ushort species) => Zukan.GetSeen(species); - public sealed override string GetString(ReadOnlySpan data) => StringConverter5.GetString(data); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter5.GetString(data); + public sealed override int LoadString(ReadOnlySpan data, Span result) + => StringConverter5.LoadString(data, result); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter5.SetString(destBuffer, value, maxLength, option); - } + => StringConverter5.SetString(destBuffer, value, maxLength, option); // DLC private int CGearSkinInfoOffset => CGearInfoOffset + (this is SAV5B2W2 ? 0x10 : 0) + 0x24; diff --git a/PKHeX.Core/Saves/SAV6.cs b/PKHeX.Core/Saves/SAV6.cs index bce6f046f..ac75f7eef 100644 --- a/PKHeX.Core/Saves/SAV6.cs +++ b/PKHeX.Core/Saves/SAV6.cs @@ -138,12 +138,12 @@ public override int PartyCount protected set => Data[Party + (6 * SIZE_PARTY)] = (byte)value; } - public sealed override string GetString(ReadOnlySpan data) => StringConverter6.GetString(data); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter6.GetString(data); + public sealed override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter6.LoadString(data, destBuffer); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter6.SetString(destBuffer, value, maxLength, option); - } + => StringConverter6.SetString(destBuffer, value, maxLength, option); public int GetRecord(int recordID) => Records.GetRecord(recordID); public int GetRecordOffset(int recordID) => Records.GetRecordOffset(recordID); diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs index b9f75ac36..e297d6ece 100644 --- a/PKHeX.Core/Saves/SAV7.cs +++ b/PKHeX.Core/Saves/SAV7.cs @@ -109,12 +109,12 @@ protected override byte[] GetFinalData() public override bool IsVersionValid() => Version is GameVersion.SN or GameVersion.MN or GameVersion.US or GameVersion.UM; - public sealed override string GetString(ReadOnlySpan data) => StringConverter7.GetString(data); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter7.GetString(data); + public sealed override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter7.LoadString(data, destBuffer); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter7.SetString(destBuffer, value, maxLength, Language, option); - } + => StringConverter7.SetString(destBuffer, value, maxLength, Language, option); // Player Information public override uint ID32 { get => MyStatus.ID32; set => MyStatus.ID32 = value; } diff --git a/PKHeX.Core/Saves/SAV7b.cs b/PKHeX.Core/Saves/SAV7b.cs index 42bce2c5c..fcd61d183 100644 --- a/PKHeX.Core/Saves/SAV7b.cs +++ b/PKHeX.Core/Saves/SAV7b.cs @@ -124,12 +124,12 @@ public override StorageSlotSource GetSlotFlags(int index) return result; } - public override string GetString(ReadOnlySpan data) => StringConverter8.GetString(data); - + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter8.SetString(destBuffer, value, maxLength); - } + => StringConverter8.SetString(destBuffer, value, maxLength); public override bool IsVersionValid() => Version is GameVersion.GP or GameVersion.GE; diff --git a/PKHeX.Core/Saves/SAV8BS.cs b/PKHeX.Core/Saves/SAV8BS.cs index f83db7e4c..62e9f9285 100644 --- a/PKHeX.Core/Saves/SAV8BS.cs +++ b/PKHeX.Core/Saves/SAV8BS.cs @@ -244,12 +244,12 @@ public static bool GetIsHashValid(ReadOnlySpan data, ReadOnlySpan cu public override bool IsVersionValid() => Version is GameVersion.BD or GameVersion.SP; - public override string GetString(ReadOnlySpan data) => StringConverter8.GetString(data); - + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter8.SetString(destBuffer, value, maxLength, option); - } + => StringConverter8.SetString(destBuffer, value, maxLength, option); // Player Information public override uint ID32 { get => MyStatus.ID32; set => MyStatus.ID32 = value; } diff --git a/PKHeX.Core/Saves/SAV8LA.cs b/PKHeX.Core/Saves/SAV8LA.cs index afae78206..9281bff35 100644 --- a/PKHeX.Core/Saves/SAV8LA.cs +++ b/PKHeX.Core/Saves/SAV8LA.cs @@ -38,8 +38,12 @@ public SAV8LA() _ => throw new ArgumentOutOfRangeException(nameof(SaveRevision)), }; - public override string GetString(ReadOnlySpan data) => StringConverter8.GetString(data); - public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => StringConverter8.SetString(destBuffer, value, maxLength, option); + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); + public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) + => StringConverter8.SetString(destBuffer, value, maxLength, option); public override void CopyChangesFrom(SaveFile sav) { diff --git a/PKHeX.Core/Saves/SAV8SWSH.cs b/PKHeX.Core/Saves/SAV8SWSH.cs index 009f72906..c352c8858 100644 --- a/PKHeX.Core/Saves/SAV8SWSH.cs +++ b/PKHeX.Core/Saves/SAV8SWSH.cs @@ -158,7 +158,10 @@ private void Initialize() public override bool IsVersionValid() => Version is GameVersion.SW or GameVersion.SH; - public override string GetString(ReadOnlySpan data) => StringConverter8.GetString(data); + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => StringConverter8.SetString(destBuffer, value, maxLength, option); diff --git a/PKHeX.Core/Saves/SAV9SV.cs b/PKHeX.Core/Saves/SAV9SV.cs index e9e4ca27f..230c4d112 100644 --- a/PKHeX.Core/Saves/SAV9SV.cs +++ b/PKHeX.Core/Saves/SAV9SV.cs @@ -164,7 +164,10 @@ private void Initialize() public override bool IsVersionValid() => Version is GameVersion.SL or GameVersion.VL; - public override string GetString(ReadOnlySpan data) => StringConverter8.GetString(data); + public override string GetString(ReadOnlySpan data) + => StringConverter8.GetString(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter8.LoadString(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => StringConverter8.SetString(destBuffer, value, maxLength, option); diff --git a/PKHeX.Core/Saves/SAV_STADIUM.cs b/PKHeX.Core/Saves/SAV_STADIUM.cs index fda26a424..ff30281ac 100644 --- a/PKHeX.Core/Saves/SAV_STADIUM.cs +++ b/PKHeX.Core/Saves/SAV_STADIUM.cs @@ -93,12 +93,12 @@ public virtual SlotGroup[] GetRegisteredTeams() return result; } - public sealed override string GetString(ReadOnlySpan data) => StringConverter1.GetString(data, Japanese); - + public sealed override string GetString(ReadOnlySpan data) + => StringConverter1.GetString(data, Japanese); + public sealed override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter1.LoadString(data, destBuffer, Japanese); public sealed override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); - } + => StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option); /// /// Some emulators emit with system architecture endianness (Little Endian) instead of the original Big Endian ordering. diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs index c2373c6d5..15aa4b6d4 100644 --- a/PKHeX.Core/Saves/SaveFile.cs +++ b/PKHeX.Core/Saves/SaveFile.cs @@ -8,7 +8,7 @@ namespace PKHeX.Core; /// /// Base Class for Save Files /// -public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVersion +public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVersion, IStringConverter { // General Object Properties public byte[] Data; @@ -78,6 +78,7 @@ public void SetData(Span dest, ReadOnlySpan input) } public abstract string GetString(ReadOnlySpan data); + public abstract int LoadString(ReadOnlySpan data, Span text); public abstract int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option); #endregion diff --git a/PKHeX.Core/Saves/Storage/BulkStorage.cs b/PKHeX.Core/Saves/Storage/BulkStorage.cs index 77b572d4e..7e6440879 100644 --- a/PKHeX.Core/Saves/Storage/BulkStorage.cs +++ b/PKHeX.Core/Saves/Storage/BulkStorage.cs @@ -54,7 +54,8 @@ protected BulkStorage(byte[] data, Type t, int start, int slotsPerBox = 30) : ba public override string GetString(ReadOnlySpan data) => StringConverter.GetString(data, Generation, blank.Japanese, IsBigEndian, Language); - + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter.LoadString(data, destBuffer, Generation, blank.Japanese, IsBigEndian, Language); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) => StringConverter.SetString(destBuffer, value, maxLength, option: option, generation: Generation, jp: blank.Japanese, isBigEndian: IsBigEndian, language: Language); } diff --git a/PKHeX.Core/Saves/Storage/SAV4Ranch.cs b/PKHeX.Core/Saves/Storage/SAV4Ranch.cs index 2d66c7165..79b1d1570 100644 --- a/PKHeX.Core/Saves/Storage/SAV4Ranch.cs +++ b/PKHeX.Core/Saves/Storage/SAV4Ranch.cs @@ -45,7 +45,6 @@ public sealed class SAV4Ranch : BulkStorage, ISaveFileRevision protected override bool IsSlotSwapProtected(int box, int slot) => IsSlotOverwriteProtected(box, slot); public override bool IsPKMPresent(ReadOnlySpan data) => EntityDetection.IsPresentSAV4Ranch(data); - private readonly GameVersion _version; public override GameVersion Version { get => _version; set { } } public SAV4Ranch(byte[] data) : base(data, typeof(RK4), 0) @@ -251,10 +250,10 @@ public override int PlayedSeconds set { var time = PlayedSpan; PlayedSpan = time - TimeSpan.FromSeconds(time.Seconds) + TimeSpan.FromSeconds(value); } } - public override string GetString(ReadOnlySpan data) => StringConverter4GC.GetStringUnicode(data); - + public override string GetString(ReadOnlySpan data) + => StringConverter4GC.GetStringUnicode(data); + public override int LoadString(ReadOnlySpan data, Span destBuffer) + => StringConverter4GC.LoadStringUnicode(data, destBuffer); public override int SetString(Span destBuffer, ReadOnlySpan value, int maxLength, StringConverterOption option) - { - return StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option); - } + => StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option); } diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs index 0cb391096..a3a241fb0 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs @@ -1408,8 +1408,7 @@ private void UpdateNicknameClick(object sender, MouseEventArgs e) return; } - var sav = RequestSaveFile; - using var d = new TrashEditor(tb, trash, sav); + using var d = new TrashEditor(tb, trash, Entity, Entity.Format); d.ShowDialog(); tb.Text = d.FinalString; d.FinalBytes.CopyTo(trash); diff --git a/PKHeX.WinForms/Subforms/PKM Editors/Text.cs b/PKHeX.WinForms/Subforms/PKM Editors/Text.cs index a045309f1..cfed6275a 100644 --- a/PKHeX.WinForms/Subforms/PKM Editors/Text.cs +++ b/PKHeX.WinForms/Subforms/PKM Editors/Text.cs @@ -9,15 +9,15 @@ namespace PKHeX.WinForms; public partial class TrashEditor : Form { - private readonly SaveFile SAV; + private readonly IStringConverter Converter; - public TrashEditor(TextBoxBase TB_NN, SaveFile sav) : this(TB_NN, [], sav) { } + public TrashEditor(TextBoxBase TB_NN, SaveFile sav) : this(TB_NN, [], sav, sav.Generation) { } - public TrashEditor(TextBoxBase TB_NN, Span raw, SaveFile sav) + public TrashEditor(TextBoxBase TB_NN, Span raw, IStringConverter converter, byte generation) { InitializeComponent(); WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage); - SAV = sav; + Converter = converter; FinalString = TB_NN.Text; @@ -25,7 +25,7 @@ public TrashEditor(TextBoxBase TB_NN, Span raw, SaveFile sav) if (raw.Length != 0) { Raw = FinalBytes = raw.ToArray(); - AddTrashEditing(raw.Length); + AddTrashEditing(raw.Length, generation); } else { @@ -33,7 +33,7 @@ public TrashEditor(TextBoxBase TB_NN, Span raw, SaveFile sav) } var f = FontUtil.GetPKXFont(); - AddCharEditing(f); + AddCharEditing(f, generation); TB_Text.MaxLength = TB_NN.MaxLength; TB_Text.Text = TB_NN.Text; TB_Text.Font = f; @@ -76,9 +76,9 @@ private void B_Save_Click(object sender, EventArgs e) Close(); } - private void AddCharEditing(Font f) + private void AddCharEditing(Font f, byte generation) { - var chars = GetChars(SAV.Generation); + var chars = GetChars(generation); if (chars.Length == 0) return; @@ -94,11 +94,11 @@ private void AddCharEditing(Font f) } } - private void AddTrashEditing(int count) + private void AddTrashEditing(int count, byte generation) { FLP_Hex.Visible = true; GB_Trash.Visible = true; - NUD_Generation.Value = SAV.Generation; + NUD_Generation.Value = generation; for (int i = 0; i < count; i++) { var l = GetLabel($"${i:X2}"); @@ -127,7 +127,7 @@ private void AddTrashEditing(int count) CB_Species.DataSource = new BindingSource(GameInfo.SpeciesDataSource, null); CB_Language.InitializeBinding(); - CB_Language.DataSource = GameInfo.LanguageDataSource(SAV.Generation); + CB_Language.DataSource = GameInfo.LanguageDataSource(generation); } private void UpdateNUD(object sender, EventArgs e) @@ -200,11 +200,11 @@ private void B_ClearTrash_Click(object sender, EventArgs e) private byte[] SetString(ReadOnlySpan text) { Span temp = stackalloc byte[Raw.Length]; - var written = SAV.SetString(temp, text, text.Length, StringConverterOption.None); + var written = Converter.SetString(temp, text, text.Length, StringConverterOption.None); return temp[..written].ToArray(); } - private string GetString() => SAV.GetString(Raw); + private string GetString() => Converter.GetString(Raw); // Helpers private static Label GetLabel(string str) => new() { Text = str, AutoSize = false, Size = new Size(40, 24), TextAlign = ContentAlignment.MiddleRight }; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_HallOfFame.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_HallOfFame.cs index b8c92a5a2..080d84870 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_HallOfFame.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_HallOfFame.cs @@ -399,7 +399,7 @@ private void ChangeNickname(object sender, MouseEventArgs e) var nicktrash = Data.Slice(0x18 + offset, 26); var text = tb.Text; SAV.SetString(nicktrash, text, 12, StringConverterOption.ClearZero); - var d = new TrashEditor(tb, nicktrash, SAV); + var d = new TrashEditor(tb, nicktrash, SAV, SAV.Generation); d.ShowDialog(); tb.Text = d.FinalString; d.FinalBytes.CopyTo(nicktrash);