diff --git a/pk3DS.Core/Game/GameConfig.cs b/pk3DS.Core/Game/GameConfig.cs
index db79bd1..5b0d0f3 100644
--- a/pk3DS.Core/Game/GameConfig.cs
+++ b/pk3DS.Core/Game/GameConfig.cs
@@ -21,6 +21,14 @@ public class GameConfig
public TextReference[] GameText { get; private set; }
public GameInfo Info { get; private set; }
+ ///
+ /// Whether or not to remap characters in text files to proper unicode. Defaults to false.
+ ///
+ ///
+ /// This will enable the display of ♂ and ♀, but may interfere with text editing. Set this to true if you're not going to change any text, otherwise set it to false.
+ ///
+ public bool RemapCharacters { get; set; } = false;
+
public GameConfig(int fileCount)
{
GameVersion game = GameVersion.Invalid;
@@ -134,7 +142,7 @@ public void InitializeLearnset()
public void InitializeGameText()
{
GARCGameText = getGARCData("gametext");
- GameTextStrings = GARCGameText.Files.Select(file => new TextFile(this, file).Lines).ToArray();
+ GameTextStrings = GARCGameText.Files.Select(file => new TextFile(this, file, RemapCharacters).Lines).ToArray();
}
public void InitializeMoves()
{
diff --git a/pk3DS.Core/TextFile.cs b/pk3DS.Core/TextFile.cs
index 481dfeb..1a8b56e 100644
--- a/pk3DS.Core/TextFile.cs
+++ b/pk3DS.Core/TextFile.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text;
namespace pk3DS.Core
{
@@ -16,11 +17,10 @@ public class TextFile
private const ushort KEY_TEXTCLEAR = 0xBE01;
private const ushort KEY_TEXTWAIT = 0xBE02;
private const ushort KEY_TEXTNULL = 0xBDFF;
- private const bool SETEMPTYTEXT = false;
- private static bool REMAPCHARS = false;
+ private const bool SETEMPTYTEXT = false;
private static readonly byte[] emptyTextFile = { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
- public TextFile(GameConfig config, byte[] data = null)
+ public TextFile(GameConfig config, byte[] data = null, bool remapChars = false)
{
Data = (byte[])(data ?? emptyTextFile).Clone();
@@ -32,8 +32,10 @@ public TextFile(GameConfig config, byte[] data = null)
throw new Exception("Section size and overall size do not match.");
Config = config;
+ RemapChars = remapChars;
}
private GameConfig Config { get; set; }
+ private bool RemapChars = true;
private ushort TextSections { get { return BitConverter.ToUInt16(Data, 0x0); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x0); } } // Always 0x0001
private ushort LineCount { get { return BitConverter.ToUInt16(Data, 0x2); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x2); } }
private uint TotalLength { get { return BitConverter.ToUInt32(Data, 0x4); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x4); } }
@@ -172,9 +174,9 @@ private byte[] getLineData(GameConfig config, string line)
}
}
- private static ushort TryRemapChar(ushort val)
+ private ushort TryRemapChar(ushort val)
{
- if (!REMAPCHARS)
+ if (!RemapChars)
return val;
switch (val)
{
@@ -185,9 +187,9 @@ private static ushort TryRemapChar(ushort val)
default: return val;
}
}
- private static ushort TryUnmapChar(ushort val)
+ private ushort TryUnmapChar(ushort val)
{
- if (!REMAPCHARS)
+ if (!RemapChars)
return val;
switch (val)
{
@@ -204,7 +206,7 @@ private string getLineString(GameConfig config, byte[] data)
if (data == null)
return null;
- string s = "";
+ var s = new StringBuilder();
int i = 0;
while (i < data.Length)
{
@@ -214,19 +216,19 @@ private string getLineString(GameConfig config, byte[] data)
switch (val)
{
- case KEY_TERMINATOR: return s;
- case KEY_VARIABLE: s += getVariableString(config, data, ref i); break;
- case '\n': s += @"\n"; break;
- case '\\': s += @"\\"; break;
- case '[': s += @"\["; break;
- default: s += (char)TryUnmapChar(val); break;
+ case KEY_TERMINATOR: return s.ToString();
+ case KEY_VARIABLE: s.Append(getVariableString(config, data, ref i)); break;
+ case '\n': s.Append(@"\n"); break;
+ case '\\': s.Append(@"\\"); break;
+ case '[': s.Append(@"\["); break;
+ default: s.Append((char)TryUnmapChar(val)); break;
}
}
- return s; // Shouldn't get hit if the string is properly terminated.
+ return s.ToString(); // Shouldn't get hit if the string is properly terminated.
}
private string getVariableString(GameConfig config, byte[] data, ref int i)
{
- string s = "";
+ var s = new StringBuilder();
ushort count = BitConverter.ToUInt16(data, i); i += 2;
ushort variable = BitConverter.ToUInt16(data, i); i += 2;
@@ -246,21 +248,21 @@ private string getVariableString(GameConfig config, byte[] data, ref int i)
string varName = getVariableString(config, variable);
- s += "[VAR" + " " + varName;
+ s.Append("[VAR" + " " + varName);
if (count > 1)
{
- s += '(';
+ s.Append('(');
while (count > 1)
{
ushort arg = BitConverter.ToUInt16(data, i); i += 2;
- s += arg.ToString("X4");
+ s.Append(arg.ToString("X4"));
if (--count == 1) break;
- s += ",";
+ s.Append(",");
}
- s += ')';
+ s.Append(')');
}
- s += "]";
- return s;
+ s.Append("]");
+ return s.ToString();
}
private IEnumerable getEscapeValues(char esc)
{
@@ -342,15 +344,15 @@ private string getVariableString(GameConfig config, ushort variable)
}
// Exposed Methods
- public static string[] getStrings(GameConfig config, byte[] data)
+ public static string[] getStrings(GameConfig config, byte[] data, bool remapChars = false)
{
TextFile t;
- try { t = new TextFile(config, data); } catch { return null; }
+ try { t = new TextFile(config, data, remapChars); } catch { return null; }
return t.Lines;
}
- public static byte[] getBytes(GameConfig config, string[] lines)
+ public static byte[] getBytes(GameConfig config, string[] lines, bool remapChars = false)
{
- return new TextFile (config) { Lines = lines }.Data;
+ return new TextFile (config, remapChars: remapChars) { Lines = lines }.Data;
}
}
}