146 lines
4.1 KiB
C#
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}";
|
|
} |