mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-16 21:38:40 +00:00
Modify G1/G2 character mappings (#4154)
### Treat 'ヘ' as katakana - For consistency with ベ/ペ/リ which are treated as katakana here and in StringConverter12Transporter.cs, map 0xCD to katakana ヘ instead of hiragana へ. - Allow input of hiragana べ/ぺ/へ/り, mapping them to katakana ベ/ペ/ヘ/リ. Previously, they would be treated as invalid and mapped to the string terminator. ### Swap mappings for 0xE8/0xF2 - Previously, 0xE8 was mapped to U+002E `.` FULL STOP, while 0xF2 was mapped to the special character U+2024 `․` ONE DOT LEADER. Since 0xF2 is used in user input while 0xE8 is only used in `MR.MIME`, swap these mappings so that normal keyboard input maps to the user-enterable character. - Modifies SpeciesName.cs to produce U+2024 for Mr. Mime in G1/G2.
This commit is contained in:
parent
018694b84f
commit
01131e59f0
3 changed files with 74 additions and 15 deletions
|
@ -157,11 +157,9 @@ public static class StringConverter12
|
|||
int i = 0;
|
||||
for (; i < value.Length; i++)
|
||||
{
|
||||
char c = value[i];
|
||||
var index = dict.IndexOf(c);
|
||||
if (index is -1 or G1TerminatorCode)
|
||||
if (!TryGetIndex(dict, value[i], out var index))
|
||||
break;
|
||||
destBuffer[i] = (byte)index;
|
||||
destBuffer[i] = index;
|
||||
}
|
||||
|
||||
int count = i;
|
||||
|
@ -171,6 +169,34 @@ public static class StringConverter12
|
|||
return count + 1;
|
||||
}
|
||||
|
||||
private static bool TryGetIndex(in ReadOnlySpan<char> dict, char c, out byte result)
|
||||
{
|
||||
var index = dict.IndexOf(c);
|
||||
if (index == -1)
|
||||
return TryGetUserFriendlyRemap(dict, c, out result);
|
||||
// \0 shouldn't really be user-entered, but just in case
|
||||
result = (byte)index;
|
||||
return index != default;
|
||||
}
|
||||
|
||||
// べ (U+3079), ぺ (U+307A), へ (U+3078), and り (U+308A)
|
||||
private const string Hiragana = "べぺへり";
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remap the user input to a valid character.
|
||||
/// </summary>
|
||||
private static bool TryGetUserFriendlyRemap(in ReadOnlySpan<char> dict, char c, out byte result)
|
||||
{
|
||||
if (Hiragana.Contains(c))
|
||||
{
|
||||
int index = dict.IndexOf((char)(c + (char)0x60));
|
||||
result = (byte)index;
|
||||
return true; // Valid Hiragana will always be found if it's in the table
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Gen 1/2 Character Tables
|
||||
|
||||
private const char NUL = G1Terminator;
|
||||
|
@ -181,7 +207,9 @@ public static class StringConverter12
|
|||
private const char LPO = '@'; // Po
|
||||
private const char LKE = '#'; // Ke
|
||||
private const char LEA = '%'; // é for Box
|
||||
private const char DOT = '․'; // Not .
|
||||
public const char DOT = '․'; // . for MR.MIME (U+2024, not U+002E)
|
||||
private const char SPF = ' '; // Full-width space (U+3000)
|
||||
public const char SPH = ' '; // Half-width space
|
||||
|
||||
public static ReadOnlySpan<char> TableEN =>
|
||||
[
|
||||
|
@ -192,15 +220,15 @@ public static class StringConverter12
|
|||
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 40-4F
|
||||
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, TOT, NUL, NUL, // 50-5F
|
||||
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 60-6F
|
||||
LPO, LKE, '“', '”', NUL, '…', NUL, NUL, NUL, '┌', '─', '┐', '│', '└', '┘', ' ', // 70-7F
|
||||
LPO, LKE, '“', '”', NUL, '…', NUL, NUL, NUL, '┌', '─', '┐', '│', '└', '┘', SPH, // 70-7F
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 80-8F
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '(', ')', ':', ';', '[', ']', // 90-9F
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', // A0-AF
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'à', 'è', 'é', 'ù', 'À', 'Á', // B0-BF
|
||||
'Ä', 'Ö', 'Ü', 'ä', 'ö', 'ü', 'È', 'É', 'Ì', 'Í', 'Ñ', 'Ò', 'Ó', 'Ù', 'Ú', 'á', // C0-CF
|
||||
'ì', 'í', 'ñ', 'ò', 'ó', 'ú', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, '←', '\'', // D0-DF
|
||||
'’', LPK, LMN, '-', NUL, NUL, '?', '!', '.', '&', LEA, '→', '▷', '▶', '▼', '♂', // E0-EF
|
||||
MNY, '×', DOT, '/', ',', '♀', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // F0-FF
|
||||
'’', LPK, LMN, '-', NUL, NUL, '?', '!', DOT, '&', LEA, '→', '▷', '▶', '▼', '♂', // E0-EF
|
||||
MNY, '×', '.', '/', ',', '♀', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // F0-FF
|
||||
];
|
||||
|
||||
public static ReadOnlySpan<char> TableJP =>
|
||||
|
@ -212,12 +240,12 @@ public static class StringConverter12
|
|||
'パ', 'ピ', 'プ', 'ポ', 'ぱ', 'ぴ', 'ぷ', 'ペ', 'ぽ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 40-4F
|
||||
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, TOT, NUL, NUL, // 50-5F
|
||||
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, // 60-6F
|
||||
'「', '」', '『', '』', '・', '⋯', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, ' ', // 70-7F
|
||||
'「', '」', '『', '』', '・', '⋯', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, SPF, // 70-7F
|
||||
'ア', 'イ', 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ', 'シ', 'ス', 'セ', 'ソ', 'タ', // 80-8F
|
||||
'チ', 'ツ', 'テ', 'ト', 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ホ', 'マ', 'ミ', 'ム', // 90-9F
|
||||
'メ', 'モ', 'ヤ', 'ユ', 'ヨ', 'ラ', 'ル', 'レ', 'ロ', 'ワ', 'ヲ', 'ン', 'ッ', 'ャ', 'ュ', 'ョ', // A0-AF
|
||||
'ィ', 'あ', 'い', 'う', 'え', 'お', 'か', 'き', 'く', 'け', 'こ', 'さ', 'し', 'す', 'せ', 'そ', // B0-BF
|
||||
'た', 'ち', 'つ', 'て', 'と', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ひ', 'ふ', 'へ', 'ほ', 'ま', // C0-CF
|
||||
'た', 'ち', 'つ', 'て', 'と', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ひ', 'ふ', 'ヘ', 'ほ', 'ま', // C0-CF
|
||||
'み', 'む', 'め', 'も', 'や', 'ゆ', 'よ', 'ら', 'リ', 'る', 'れ', 'ろ', 'わ', 'を', 'ん', 'っ', // D0-DF
|
||||
'ゃ', 'ゅ', 'ょ', 'ー', '゚', '゙', '?', '!', '。', 'ァ', 'ゥ', 'ェ', NUL, NUL, NUL, '♂', // E0-EF
|
||||
MNY, NUL, '.', '/', 'ォ', '♀', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // F0-FF
|
||||
|
|
|
@ -151,13 +151,21 @@ public static class SpeciesName
|
|||
if (generation >= 3)
|
||||
return new string(result);
|
||||
|
||||
int indexSpace = result.IndexOf(' ');
|
||||
if (indexSpace != -1)
|
||||
// The only Gen1/2 species with a space is Mr. Mime; different period and no space.
|
||||
if (species == (int)Species.MrMime)
|
||||
{
|
||||
// Shift down. Strings have at most 1 occurrence of a space.
|
||||
result[(indexSpace+1)..].CopyTo(result[indexSpace..]);
|
||||
result = result[..^1];
|
||||
int indexSpace = result.IndexOf(StringConverter12.SPH);
|
||||
if (indexSpace > 0)
|
||||
{
|
||||
// Gen1/2 uses a different period for MR.MIME than user input.
|
||||
result[indexSpace - 1] = StringConverter12.DOT;
|
||||
|
||||
// Shift down. Strings have at most 1 occurrence of a space.
|
||||
result[(indexSpace + 1)..].CopyTo(result[indexSpace..]);
|
||||
result = result[..^1];
|
||||
}
|
||||
}
|
||||
|
||||
return new string(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,4 +83,27 @@ public class StringTests
|
|||
var result = StringConverter12Transporter.GetString(b12[..len], true);
|
||||
result.Should().Be(g7);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(Species.MrMime, "MR․MIME")]
|
||||
public static void ConvertStringG1(Species species, string expect)
|
||||
{
|
||||
const bool jp = false;
|
||||
const int lang = (int)LanguageID.English;
|
||||
// Ensure the API returns the correct Generation 1 name string.
|
||||
var name = SpeciesName.GetSpeciesNameGeneration((ushort)species, lang, 1);
|
||||
name.Should().Be(expect);
|
||||
|
||||
// Ensure the API converts it back and forth correctly.
|
||||
Span<byte> convert = stackalloc byte[expect.Length + 1];
|
||||
var len = StringConverter12.SetString(convert, name, name.Length, jp);
|
||||
len.Should().Be(expect.Length + 1);
|
||||
var gen1Name = StringConverter12.GetString(convert, jp);
|
||||
gen1Name.Should().Be(expect);
|
||||
|
||||
// Truncated name transferred with Virtual Console rules isn't the same as the Generation 7 name.
|
||||
var vcName = StringConverter12Transporter.GetString(convert[..len], jp);
|
||||
var gen7Name = SpeciesName.GetSpeciesNameGeneration((ushort)species, lang, 7);
|
||||
vcName.Should().NotBe(gen7Name);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue