Add IStringConverter, impl on PKM & SaveFile

use in trash editor to translate strings, from PKM instead of SAV.
Closes #4222
This commit is contained in:
Kurt 2024-04-23 00:57:17 -05:00
parent 394f5ed707
commit 093264bc24
45 changed files with 257 additions and 121 deletions

View file

@ -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<byte> data) => string.Empty;
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer) => 0;
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => 0;
public override PersonalTable3 Personal => PersonalTable.RS;
public override int MaxEV => 0;

View file

@ -301,4 +301,11 @@ public sealed class BK4 : G4PKM
pk4.RefreshChecksum();
return pk4;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View file

@ -228,4 +228,11 @@ public sealed class CK3(byte[] Data) : G3PKM(Data), IShadowCapture
pk.RefreshChecksum();
return pk;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View file

@ -423,4 +423,11 @@ public sealed class PKH : PKM, IHandlerLanguage, IFormArgument, IHomeTrack, IBat
WeightScalar = PokeSizeUtil.GetRandomScalar(rnd);
}
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -582,7 +582,6 @@ public sealed class PA8 : PKM, ISanityChecksum,
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 sealed class PA8 : PKM, ISanityChecksum,
if (permit.IsRecordPermitted(flagIndex))
SetMasteredRecordFlag(flagIndex, true);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// <summary> Generation 7 <see cref="PKM"/> format used for <see cref="GameVersion.GG"/>. </summary>
public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite,
IFormArgument, IAppliedMarkings7, IHandlerUpdate
IFormArgument, IAppliedMarkings7
{
public override ReadOnlySpan<ushort> ExtraBytes =>
[
@ -581,4 +581,11 @@ public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, IComb
5 => 4,
_ => throw new ArgumentOutOfRangeException(nameof(characterIndex)), // never happens, characteristic is always 0-29
};
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -146,4 +146,11 @@ public sealed class PB8 : G8PKM
public override bool WasEgg => IsEgg || EggDay != 0;
public override bool HasOriginalMetLocation => base.HasOriginalMetLocation && !(LA && MetLocation == LocationsHOME.SWLA);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -248,16 +248,12 @@ public sealed class PK1 : GBPKML, IPersonalType
return StringConverter12Transporter.GetString(OriginalTrainerTrash, Japanese);
}
protected override string GetString(ReadOnlySpan<byte> data)
{
return StringConverter1.GetString(data, Japanese);
}
protected override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option = StringConverterOption.None)
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
/// <summary>
/// Gets a checksum over all the entity's data using a single list to wrap all components.

View file

@ -259,15 +259,21 @@ public sealed class PK2 : GBPKML, ICaughtData2
OriginalTrainerName = OriginalTrainerName,
};
protected override string GetString(ReadOnlySpan<byte> data)
public override string GetString(ReadOnlySpan<byte> data)
{
if (Korean)
return StringConverter2KOR.GetString(data);
return StringConverter2.GetString(data, Language);
}
protected override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None)
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
{
if (Korean)
return StringConverter2KOR.LoadString(data, destBuffer);
return StringConverter2.LoadString(data, destBuffer, Language);
}
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
if (Korean)
return StringConverter2KOR.SetString(destBuffer, value, maxLength, option);

View file

@ -353,4 +353,11 @@ public sealed class PK3 : G3PKM, ISanityChecksum
pk.ResetPartyStats();
return pk;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3.SetString(destBuffer, value, maxLength, Language, option);
}

View file

@ -383,4 +383,11 @@ public sealed class PK4 : G4PKM
StringConverter345.TransferGlyphs45(temp[..len]);
StringConverter5.SetString(dest, temp[..len], len);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View file

@ -552,4 +552,11 @@ public sealed class PK5 : PKM, ISanityChecksum,
_ => Locations.Transfer4,
};
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter5.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter5.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter5.SetString(destBuffer, value, maxLength, option);
}

View file

@ -523,4 +523,11 @@ public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
return pk7; // Done!
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter6.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter6.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter6.SetString(destBuffer, value, maxLength, option);
}

View file

@ -547,6 +547,13 @@ public sealed class PK7 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
break;
}
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter7.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter7.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter7.SetString(destBuffer, value, maxLength, Language);
}
public enum ResortEventState : byte

View file

@ -129,4 +129,11 @@ public sealed class PK8 : G8PKM, IHandlerUpdate
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<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -681,4 +681,11 @@ public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedien
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<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View file

@ -11,7 +11,7 @@ namespace PKHeX.Core;
/// Object representing a <see cref="PKM"/>'s data and derived properties.
/// </summary>
[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
{
/// <summary>
/// Valid file extensions that represent <see cref="PKM"/> data, without the leading '.'
@ -148,6 +148,10 @@ public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILa
public virtual byte Fullness { get => 0; set { } }
public virtual int AbilityNumber { get => 0; set { } }
public abstract string GetString(ReadOnlySpan<byte> data);
public abstract int LoadString(ReadOnlySpan<byte> data, Span<char> text);
public abstract int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
/// <summary>
/// The date the Pokémon was met.
/// </summary>

View file

@ -345,4 +345,11 @@ public sealed class RK4 : G4PKM
pk4.RefreshChecksum();
return pk4;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View file

@ -212,4 +212,11 @@ public sealed class SK2 : GBPKM, ICaughtData2
public bool IsPossible(bool japanese) => japanese ? IsJapanese(Data) : IsEnglish(Data);
public void SwapLanguage() => IsEncodingJapanese ^= true;
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter2.GetString(data, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter2.LoadString(data, destBuffer, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter2.SetString(destBuffer, value, maxLength, Language, option);
}

View file

@ -61,11 +61,6 @@ public abstract class GBPKML : GBPKM
}
}
protected abstract string GetString(ReadOnlySpan<byte> data);
protected abstract int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None);
public sealed override string Nickname
{
get => GetString(NicknameTrash);

View file

@ -0,0 +1,10 @@
using System;
namespace PKHeX.Core;
public interface IStringConverter
{
string GetString(ReadOnlySpan<byte> data);
int LoadString(ReadOnlySpan<byte> data, Span<char> text);
int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
}

View file

@ -232,4 +232,11 @@ public sealed class XK3 : G3PKM, IShadowCapture
90 or 91 or 92 => true, // Pokespot: Rock / Oasis / Cave
_ => false,
};
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View file

@ -547,10 +547,10 @@ public sealed class SAV1 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
}
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter1.GetString(data, Japanese);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}

View file

@ -580,15 +580,8 @@ public sealed class SAV2 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
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 sealed class SAV2 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
return StringConverter2.GetString(data, Language);
}
public override int LoadString(ReadOnlySpan<byte> data, Span<char> text)
{
if (Korean)
return StringConverter2KOR.LoadString(data, text);
return StringConverter2.LoadString(data, text, Language);
}
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
if (Korean)

View file

@ -600,12 +600,12 @@ public abstract class SAV3 : SaveFile, ILangDeviantSave, IEventFlag37, IBoxDetai
public abstract bool NationalDex { get; set; }
#endregion
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter3.GetString(data, Japanese);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Japanese);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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;

View file

@ -288,10 +288,10 @@ public sealed class SAV3Colosseum : SaveFile, IGCSaveFile, IBoxDetailName, IDayc
public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data[(DaycareOffset + 4)..], value);
public Memory<byte> GetDaycareSlot(int slot) => Raw.Slice(DaycareOffset + 8, PokeCrypto.SIZE_3CSTORED);
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3GC.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View file

@ -207,10 +207,10 @@ public sealed class SAV3RSBox : SaveFile, IGCSaveFile, IBoxDetailName, IBoxDetai
WriteUInt16LittleEndian(data[(PokeCrypto.SIZE_3STORED + 2)..], pk.SID16);
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3.GetString(data, Japanese);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
}

View file

@ -452,10 +452,10 @@ public sealed class SAV3XD : SaveFile, IGCSaveFile, IBoxDetailName, IDaycareStor
public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data.AsSpan(DaycareOffset + 4), value);
public Memory<byte> GetDaycareSlot(int slot) => Data.AsMemory(DaycareOffset + 8, PokeCrypto.SIZE_3XSTORED);
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3GC.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View file

@ -478,12 +478,12 @@ public abstract class SAV4 : SaveFile, IEventFlag37, IDaycareStorage, IDaycareRa
}
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter4.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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)

View file

@ -367,7 +367,10 @@ public sealed class SAV4BR : SaveFile, IBoxDetailName
}
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter4GC.GetStringUnicode(data);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4GC.GetStringUnicode(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4GC.LoadStringUnicode(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}

View file

@ -117,12 +117,12 @@ public abstract class SAV5 : SaveFile, ISaveBlock5BW, IEventFlagProvider37, IBox
public override bool GetCaught(ushort species) => Zukan.GetCaught(species);
public override bool GetSeen(ushort species) => Zukan.GetSeen(species);
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter5.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter5.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> result)
=> StringConverter5.LoadString(data, result);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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;

View file

@ -138,12 +138,12 @@ public abstract class SAV6 : SAV_BEEF, ITrainerStatRecord, ISaveBlock6Core, IReg
protected set => Data[Party + (6 * SIZE_PARTY)] = (byte)value;
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter6.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter6.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter6.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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);

View file

@ -109,12 +109,12 @@ public abstract class SAV7 : SAV_BEEF, ITrainerStatRecord, ISaveBlock7Main, IReg
public override bool IsVersionValid() =>
Version is GameVersion.SN or GameVersion.MN or GameVersion.US or GameVersion.UM;
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter7.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter7.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter7.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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; }

View file

@ -124,12 +124,12 @@ public sealed class SAV7b : SAV_BEEF, ISaveBlock7b, IGameSync, IMysteryGiftStora
return result;
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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;

View file

@ -244,12 +244,12 @@ public sealed class SAV8BS : SaveFile, ISaveFileRevision, ITrainerStatRecord, IE
public override bool IsVersionValid() => Version is GameVersion.BD or GameVersion.SP;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> 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; }

View file

@ -38,8 +38,12 @@ public sealed class SAV8LA : SaveFile, ISaveBlock8LA, ISCBlockArray, ISaveFileRe
_ => throw new ArgumentOutOfRangeException(nameof(SaveRevision)),
};
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => StringConverter8.SetString(destBuffer, value, maxLength, option);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
public override void CopyChangesFrom(SaveFile sav)
{

View file

@ -158,7 +158,10 @@ public sealed class SAV8SWSH : SaveFile, ISaveBlock8SWSH, ITrainerStatRecord, IS
public override bool IsVersionValid() => Version is GameVersion.SW or GameVersion.SH;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);

View file

@ -164,7 +164,10 @@ public sealed class SAV9SV : SaveFile, ISaveBlock9Main, ISCBlockArray, ISaveFile
public override bool IsVersionValid() => Version is GameVersion.SL or GameVersion.VL;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);

View file

@ -93,12 +93,12 @@ public abstract class SAV_STADIUM : SaveFile, ILangDeviantSave
return result;
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter1.GetString(data, Japanese);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
/// <summary>
/// Some emulators emit with system architecture endianness (Little Endian) instead of the original Big Endian ordering.

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core;
/// <summary>
/// Base Class for Save Files
/// </summary>
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 abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVe
}
public abstract string GetString(ReadOnlySpan<byte> data);
public abstract int LoadString(ReadOnlySpan<byte> data, Span<char> text);
public abstract int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option);
#endregion

View file

@ -54,7 +54,8 @@ public abstract class BulkStorage : SaveFile
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter.GetString(data, Generation, blank.Japanese, IsBigEndian, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter.LoadString(data, destBuffer, Generation, blank.Japanese, IsBigEndian, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter.SetString(destBuffer, value, maxLength, option: option, generation: Generation, jp: blank.Japanese, isBigEndian: IsBigEndian, language: Language);
}

View file

@ -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<byte> 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 sealed class SAV4Ranch : BulkStorage, ISaveFileRevision
set { var time = PlayedSpan; PlayedSpan = time - TimeSpan.FromSeconds(time.Seconds) + TimeSpan.FromSeconds(value); }
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter4GC.GetStringUnicode(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4GC.GetStringUnicode(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4GC.LoadStringUnicode(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}
=> StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}

View file

@ -1408,8 +1408,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
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);

View file

@ -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<byte> raw, SaveFile sav)
public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, IStringConverter converter, byte generation)
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = sav;
Converter = converter;
FinalString = TB_NN.Text;
@ -25,7 +25,7 @@ public partial class TrashEditor : Form
if (raw.Length != 0)
{
Raw = FinalBytes = raw.ToArray();
AddTrashEditing(raw.Length);
AddTrashEditing(raw.Length, generation);
}
else
{
@ -33,7 +33,7 @@ public partial class TrashEditor : Form
}
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 @@ public partial class TrashEditor : Form
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 @@ public partial class TrashEditor : Form
}
}
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 @@ public partial class TrashEditor : Form
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 @@ public partial class TrashEditor : Form
private byte[] SetString(ReadOnlySpan<char> text)
{
Span<byte> 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 };

View file

@ -399,7 +399,7 @@ public partial class SAV_HallOfFame : Form
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);