Files
P2SinNext/Assets/Code/TextUtils.cs
2025-10-19 19:04:50 +05:00

146 lines
4.1 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
public static class TextUtils
{
public static List<TextToken> ParseText(byte[] textData, int startOffset)
{
List<TextToken> tokens = new List<TextToken>();
int offset = startOffset;
while (offset < textData.Length && textData[offset] != 0)
{
ushort code = ReadUInt16(textData, ref offset);
if ((code & 0x1000) != 0) // Ýòî êîìàíäà
{
ParseCommand(code, textData, ref offset, tokens);
if (tokens.Last().Value == "end") return tokens; //If end of window
}
else if ((code & 0x2000) != 0) // My russian text
{
offset += 2;
ParseText(code, textData, ref offset, tokens);
}
else
{
// Japanese and other char
offset += 2;
string chr = (code <= 255 && code >= 32) ? "" + (char)code : $"[{code:X4}]";
tokens.Add(new TextToken { Key = "text", Value = chr });
}
}
return tokens;
}
private static void ParseCommand(ushort code, byte[] data, ref int offset, List<TextToken> tokens)
{
ushort commandType = (ushort)(code & 0x00FF);
TextToken token = new TextToken();
offset += 2;
switch (commandType)
{
case 0x1D: // color
token.Key = "color";
token.Value = ReadUInt16(data, ref offset).ToString();
break;
case 0x12: // name
token.Key = "text";
token.Value = "Ñóîóîóîâ"; //TODO: take from global vars
break;
case 0x13: // surname
token.Key = "text";
token.Value = "Âàñÿ"; //TODO: take from global vars
break;
case 0x20: // tab
token.Key = "cmd";
token.Value = "tab";
break;
case 0x02: // wipe text & reset coords
token.Key = "cmd";
token.Value = "wipe";
break;
case 0x03: // end
token.Key = "cmd";
token.Value = "end";
break;
case 0x05: // pause
token.Key = "pause";
token.Value = ReadUInt16(data, ref offset).ToString();
break;
case 0x06: // wait input
token.Key = "cmd";
token.Value = "wait_input";
break;
case 0x08: // wait input
token.Key = "user_selection";
token.Value = ReadUInt16(data, ref offset).ToString();
break;
case 0x09: // wait input
token.Key = "cmd";
token.Value = "wait_selection";
break;
case 0x01: // newline
token.Key = "cmd";
token.Value = "newline";
break;
default:
token.Key = "unknown";
token.Value = commandType.ToString("X4");
break;
}
offset += (((code & 0x0F00) >> 8) - 1) * 2; //Original offset after command
tokens.Add(token);
}
private static void ParseText(ushort code, byte[] data, ref int offset, List<TextToken> tokens)
{
int length = code & 0x00FF;
TextToken token = new TextToken
{
Key = "text",
Value = Encoding.GetEncoding(1251).GetString(data, offset, length).Replace("~", "...")
};
offset += length;
// Âûðàâíèâàíèå ïî 2 áàéòà
offset += length & 1;
tokens.Add(token);
}
private static ushort ReadUInt16(byte[] data, ref int offset)
{
ushort value = (ushort)(data[offset] | (data[offset + 1] << 8));
return value;
}
}
public class TextToken
{
public string Key { get; set; }
public string Value { get; set; }
public override string ToString() => $"{Key}: {Value}";
}