public static string GetText(int offset, int length, TextType texttype, bool ignorecc)
        {
            string ret = string.Empty;

            switch (texttype)
            {
            case TextType.Japanese:
                List <byte> stringBytes = new List <byte>();

                for (int i = 0; i < length; i++)
                {
                    ushort ch = Rom.ReadUShort(offset);

                    if (ch == 0xFFFF)
                    {
                        if (!ignorecc)
                        {
                            stringBytes.AppendString("[FFFF]");
                        }
                        break;
                    }

                    offset += 2;

                    if (ch >= 0xEF00)
                    {
                        if (!ignorecc)
                        {
                            stringBytes.AppendString("[" + ch.ToString("X4"));
                            if (ch == 0xff22)
                            {
                            }
                            if (M3CC.CCLookup.ContainsKey(ch))
                            {
                                CC c = M3CC.CCLookup[ch];
                                for (int j = 0; j < c.args; j++)
                                {
                                    stringBytes.AppendString(" " + Rom.ReadUShort(offset).ToString("X4"));
                                    offset += 2;
                                }
                            }
                            stringBytes.AppendString("]");
                        }

                        if ((ch == 0xFF01) || (ch == 0xFF32) || (ch == 0xFF03))
                        {
                            // Newline
                            stringBytes.AppendString(Environment.NewLine);
                        }

                        continue;
                    }

                    ch = (ushort)(ch % JapaneseMap.Length);
                    ushort code = JapaneseMap[ch];
                    stringBytes.Add((byte)((code >> 8) & 0xFF));
                    stringBytes.Add((byte)(code & 0xFF));
                }

                byte[] converted = Encoding.Convert(SJIS, Unicode, stringBytes.ToArray());
                ret = Unicode.GetString(converted);
                break;

            case TextType.EnglishWide:
                for (int i = 0; i < length; i++)
                {
                    ushort ch = Rom.ReadUShort(offset);

                    if (ch == 0xFFFF)
                    {
                        break;
                    }

                    offset += 2;

                    if (ch >= 0xEF00)
                    {
                        if (ignorecc)
                        {
                            if ((ch == 0xFF01) || (ch == 0xFF32) || (ch == 0xFF03))
                            {
                                // Newline
                                ret += Environment.NewLine;
                            }
                        }

                        else
                        {
                            ret += "[" + ch.ToString("X4") + "]";
                        }

                        continue;
                    }

                    ch  &= 0xFF;
                    ret += EnglishMap[ch];
                }
                break;

            case TextType.EnglishShort:
            case TextType.EnglishShortRaw:

                bool obfuscated = texttype == TextType.EnglishShort;

                for (int i = 0; i < length; i++)
                {
                    byte ch = Rom.DecodeByte(offset, obfuscated);

                    // Check for control codes
                    if (ch == 0xEF)
                    {
                        // EF is a custom control code
                        ret += "[EF";
                        ret += Rom.DecodeByte(offset + 1, obfuscated).ToString("X2") + "]";
                        offset++;
                    }

                    else if (ch >= 0xF0)
                    {
                        // Special case: 0xFF = end
                        if (ch == 0xFF)
                        {
                            ret += "[FFFF]";
                            break;
                        }

                        // Else: get the cc length
                        int cclen = ch & 0xF;

                        // Get the control byte
                        byte ccbyte    = Rom.DecodeByte(offset + 1, obfuscated);
                        bool doNewLine = ((ccbyte == 0x01) || (ccbyte == 0x32) || (ccbyte == 0x03));

                        // Print the result
                        ret += "[FF" + ccbyte.ToString("X2");

                        // Get the arguments
                        ushort[] args = new ushort[cclen];
                        for (int j = 0; j < cclen; j++)
                        {
                            ret += " " + Rom.DecodeUShort(offset + 2 + (j << 1), obfuscated).ToString("X4");
                        }

                        ret += "]";

                        if (doNewLine)
                        {
                            ret += Environment.NewLine;
                        }

                        offset += 1 + (cclen << 1);
                    }

                    else
                    {
                        ret += EnglishMap[ch];
                    }

                    offset++;
                }
                break;
            }

            return(ret);
        }