mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-16 13:28:35 +00:00
Update how symbols are handled for Bank -> HOME transfers (#4276)
This maps the remaining (legal) symbols in the private use area that are modified on transfer from Bank -> HOME. If any of these replacements are made, any leading or trailing halfwidth spaces are trimmed. This can result in nicknames/OT names that are the empty string or consist entirely of fullwidth spaces, even though these can't normally entered.
This commit is contained in:
parent
4d6ce53bce
commit
417231a67c
2 changed files with 89 additions and 21 deletions
|
@ -113,10 +113,10 @@ public sealed class GameDataPK8 : HomeOptional1, IGameDataSide<PK8>, IGigantamax
|
|||
Ability = (ushort)pk.Ability;
|
||||
|
||||
pkh.MarkingValue &= 0b1111_1111_1111;
|
||||
StringConverter8.NormalizeHalfWidth(pkh.OriginalTrainerTrash);
|
||||
StringConverter8.TransferGlyphs78(pkh.OriginalTrainerTrash);
|
||||
if (pk.IsNicknamed)
|
||||
{
|
||||
StringConverter8.NormalizeHalfWidth(pkh.NicknameTrash);
|
||||
StringConverter8.TransferGlyphs78(pkh.NicknameTrash);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -141,29 +141,97 @@ public static class StringConverter8
|
|||
/// <summary>
|
||||
/// Used when importing a 3DS string into HOME.
|
||||
/// </summary>
|
||||
public static void NormalizeHalfWidth(Span<byte> str)
|
||||
public static void TransferGlyphs78(Span<byte> str)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
bool modified = false;
|
||||
var u16 = MemoryMarshal.Cast<byte, char>(str);
|
||||
foreach (ref var c in u16)
|
||||
{
|
||||
var u16 = MemoryMarshal.Cast<byte, char>(str);
|
||||
foreach (ref var c in u16)
|
||||
{
|
||||
if (c == TerminatorNull)
|
||||
return;
|
||||
c = NormalizeHalfWidth(c);
|
||||
}
|
||||
var x = c;
|
||||
if (x == TerminatorNull)
|
||||
break;
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
x = (char)ReverseEndianness(x);
|
||||
|
||||
var t = TransferGlyphs78(x);
|
||||
if (t == x)
|
||||
continue;
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
t = (char)ReverseEndianness(t);
|
||||
c = t;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// Slower path for Big-Endian runtimes.
|
||||
for (int i = 0; i < str.Length; i += 2)
|
||||
{
|
||||
var data = str[i..];
|
||||
var c = ReadUInt16LittleEndian(data);
|
||||
if (c == TerminatorNull)
|
||||
return;
|
||||
WriteUInt16LittleEndian(data, NormalizeHalfWidth((char)c));
|
||||
}
|
||||
if (modified)
|
||||
TrimHalfSpaces(u16);
|
||||
}
|
||||
|
||||
private static char NormalizeHalfWidth(char str) => StringConverter.NormalizeGenderSymbol(str);
|
||||
private static void TrimHalfSpaces(Span<char> u16)
|
||||
{
|
||||
// If a replacement is made, any leading or trailing halfwidth spaces are trimmed.
|
||||
// This allows nicknames/OT names that are the empty string or consist entirely of fullwidth spaces.
|
||||
var region = u16[..u16.IndexOf((char)TerminatorNull)];
|
||||
char seek = ' ';
|
||||
if (BitConverter.IsLittleEndian)
|
||||
seek = (char)ReverseEndianness(' ');
|
||||
|
||||
var trim = region.Trim(seek);
|
||||
if (region.Length == trim.Length)
|
||||
return;
|
||||
|
||||
trim.CopyTo(u16);
|
||||
u16[trim.Length..].Clear();
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<char> Glyphs78 =>
|
||||
[
|
||||
' ', // '\uE081' -> '\u3000'
|
||||
' ', // '\uE082' -> '\u3000'
|
||||
' ', // '\uE083' -> '\u3000'
|
||||
' ', // '\uE084' -> '\u3000'
|
||||
' ', // '\uE085' -> '\u3000'
|
||||
' ', // '\uE086' -> '\u3000'
|
||||
' ', // '\uE087' -> '\u3000'
|
||||
'', // '\uE088' -> '\uE088'
|
||||
'', // '\uE089' -> '\uE089'
|
||||
'', // '\uE08A' -> '\uE08A'
|
||||
'', // '\uE08B' -> '\uE08B'
|
||||
'', // '\uE08C' -> '\uE08C'
|
||||
'…', // '\uE08D' -> '\u2026'
|
||||
'♂', // '\uE08E' -> '\u2642'
|
||||
'♀', // '\uE08F' -> '\u2640'
|
||||
'♠', // '\uE090' -> '\u2660'
|
||||
'♣', // '\uE091' -> '\u2663'
|
||||
'♥', // '\uE092' -> '\u2665'
|
||||
'♦', // '\uE093' -> '\u2666'
|
||||
'★', // '\uE094' -> '\u2605'
|
||||
'◎', // '\uE095' -> '\u25CE'
|
||||
'○', // '\uE096' -> '\u25CB'
|
||||
'□', // '\uE097' -> '\u25A1'
|
||||
'△', // '\uE098' -> '\u25B3'
|
||||
'◇', // '\uE099' -> '\u25C7'
|
||||
'♪', // '\uE09A' -> '\u266A'
|
||||
'☀', // '\uE09B' -> '\u2600'
|
||||
'☁', // '\uE09C' -> '\u2601'
|
||||
'☂', // '\uE09D' -> '\u2602'
|
||||
'☃', // '\uE09E' -> '\u2603'
|
||||
' ', // '\uE09F' -> '\u0020'
|
||||
' ', // '\uE0A0' -> '\u0020'
|
||||
' ', // '\uE0A1' -> '\u0020'
|
||||
' ', // '\uE0A2' -> '\u0020'
|
||||
' ', // '\uE0A3' -> '\u0020'
|
||||
' ', // '\uE0A4' -> '\u0020'
|
||||
' ', // '\uE0A5' -> '\u0020'
|
||||
];
|
||||
|
||||
private const int Glyphs78Start = 0xE081;
|
||||
|
||||
private static char TransferGlyphs78(char chr)
|
||||
{
|
||||
int index = chr - Glyphs78Start;
|
||||
if ((uint)index >= Glyphs78.Length)
|
||||
return chr;
|
||||
return Glyphs78[index];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue