static private List <ScriptEntry> ReadScriptData(Script s, Game game = Game.Base)
        {
            Program.PrintLine("[read] reading script data...");
            List <ScriptEntry> ScriptData = new List <ScriptEntry>();

            for (int i = s.HeaderSize; i < s.TextBlockPos; i++)
            {
                if (s.File[i] == 0x70)
                {
                    i++;
                    ScriptEntry e = new ScriptEntry();
                    e.Opcode = s.File[i];

                    int ArgCount = Opcode.GetOpcodeArgCount(e.Opcode, game);
                    if (ArgCount == -1)
                    {
                        // Vararg
                        List <byte> Args = new List <byte>();
                        while (s.File[i + 1] != 0x70)
                        {
                            Args.Add(s.File[i + 1]);
                            i++;
                        }
                        e.Args = Args.ToArray();
                        ScriptData.Add(e);
                        continue;
                    }
                    else
                    {
                        e.Args = new byte[ArgCount];
                        for (int a = 0; a < e.Args.Length; a++)
                        {
                            e.Args[a] = s.File[i + 1];
                            i++;
                        }
                        ScriptData.Add(e);
                    }
                }
                else
                {
                    // EOF?
                    while (i < s.TextBlockPos)
                    {
                        if (s.File[i] != 0x00)
                        {
                            throw new Exception("[read] error: expected 0x70, got 0x" + s.File[i].ToString("X2") + ".");
                        }
                        i++;
                    }
                    return(ScriptData);
                }
            }
            return(ScriptData);
        }
        static public bool ReadSource(Script s, string Filename, Game game = Game.Base)
        {
            // Default script type is textless
            s.Type = ScriptType.Textless;
            Program.PrintLine("[read] reading source file...");
            System.IO.StreamReader File       = new System.IO.StreamReader(Filename, Encoding.Unicode);
            List <ScriptEntry>     ScriptData = new List <ScriptEntry>();
            StringBuilder          sb         = new StringBuilder();

            while (File.Peek() != -1)
            {
                char        c = (char)File.Read();
                ScriptEntry e = new ScriptEntry();

                // Get opcode
                sb.Clear();
                while (char.IsWhiteSpace(c))
                {
                    c = (char)File.Read();
                }
                if (File.Peek() == -1)
                {
                    break;
                }
                while (c != '(' && File.Peek() != -1)
                {
                    sb.Append(c);
                    c = (char)File.Read();
                }
                if (File.Peek() != -1)
                {
                    c = (char)File.Read();
                }
                e.Opcode = Opcode.GetOpcodeByName(sb.ToString().Trim(), game);

                // Get args
                sb.Clear();
                while (char.IsWhiteSpace(c))
                {
                    c = (char)File.Read();
                }
                if (File.Peek() == -1)
                {
                    break;
                }
                if (e.Opcode == 0x02)
                {
                    while (c != '"' && File.Peek() != -1)
                    {
                        c = (char)File.Read();
                    }
                    if (File.Peek() != -1)
                    {
                        c = (char)File.Read();
                    }
                    while (c != '"' && File.Peek() != -1)
                    {
                        if (c == '\\')
                        {
                            char peek = (char)File.Peek();
                            switch (peek)
                            {
                            case '\\':
                                sb.Append('\\');
                                c = (char)File.Read();
                                break;

                            case '"':
                                sb.Append('"');
                                c = (char)File.Read();
                                break;

                            case 'n':
                                sb.Append('\n');
                                c = (char)File.Read();
                                break;

                            case 'r':
                                sb.Append('\r');
                                c = (char)File.Read();
                                break;

                            default:
                                sb.Append(c);
                                break;
                            }
                        }
                        else
                        {
                            sb.Append(c);
                        }
                        c = (char)File.Read();
                    }
                    while (c != ')' && File.Peek() != -1)
                    {
                        c = (char)File.Read();
                    }

                    s.Type = ScriptType.Text;
                    s.TextEntries++;
                    e.Text = sb.ToString();
                    e.Args = new byte[2];
                }
                else
                {
                    while (c != ')' && File.Peek() != -1)
                    {
                        sb.Append(c);
                        c = (char)File.Read();
                    }

                    List <byte> Args = new List <byte>();
                    if (sb.ToString().Trim().Length > 0)
                    {
                        foreach (string a in sb.ToString().Trim().Split(','))
                        {
                            Args.Add(byte.Parse(a.Trim()));
                        }
                    }
                    e.Args = Args.ToArray();
                }

                ScriptData.Add(e);
            }
            s.ScriptData = ScriptData;

            return(true);
        }