Battle_Script_Pro.Form1.btnCompile_Click C# (CSharp) Method

btnCompile_Click() private method

private btnCompile_Click ( object sender, EventArgs e ) : void
sender object
e EventArgs
return void
        private void btnCompile_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            freeSpaceByte = 0xFF;
            decompiledOffsets.Clear();
            Dictionary<string, int> compiledHashOrgLocations = new Dictionary<string, int>();
            firstTime = true;
            DialogResult dialogResult = DialogResult.OK;
            if (selectedROMPath == null || selectedROMPath.Equals(""))
            {
                dialogResult = openFileDialog1.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    selectedROMPath = openFileDialog1.FileName;
                    numericUpDown1_ValueChanged(sender, e);
                    btnDecompile.Enabled = true;
                    txtDecompileOffset.Enabled = true;
                }
            }
            if (File.Exists(selectedROMPath))
            {
                string romCode = GetROMCode();
                string iniPath = System.Windows.Forms.Application.StartupPath + @"\Data\BattleScriptPro.ini";
                if (File.Exists(iniPath))
                {
                    string[] iniFile = File.ReadAllLines(iniPath);
                    ParseINI(iniFile, romCode);
                }
                iniPath = System.Windows.Forms.Application.StartupPath + @"\Data\std.bsh";
                if (File.Exists(iniPath))
                {
                    string[] iniFile = File.ReadAllLines(iniPath);
                    ParseHeaderFile(iniFile);
                }
                else
                {
                    MessageBox.Show("The Ini file could not be parsed. The script can still be compiled, but keywords may not be used.");
                }
                bool result = DebugWrittenScript();
                iniPath = System.Windows.Forms.Application.StartupPath + @"\Data\std.bsh";
                if (File.Exists(iniPath))
                {
                    string[] iniFile = File.ReadAllLines(iniPath);
                    ParseHeaderFile(iniFile);
                }
                if (result)
                {
                    int lineNumber = 1;
                    FindStrings();
                    string[] hashOrgs = FindHashOrgs();
                    CompiledStrings x = CompileStrings(selectedROMPath);
                    List<byte> compiledScript = new List<byte>();
                    List<byte> compiledHashOrg;
                    Dictionary<string, int> dynamicGotos = new Dictionary<string, int>();
                    Dictionary<string, int> lengths = new Dictionary<string, int>();
                    foreach (string hashOrgName in hashOrgs)
                    {
                        lengths.Add(hashOrgName, DryRunForLength(hashOrgName));
                    }
                    foreach (string hashOrgName in hashOrgs)
                    {
                        compiledHashOrg = new List<byte>();
                        bool compile = false;
                        int scriptLength = lengths[hashOrgName];
                        int location2 = 0;
                        foreach (string line in scripts[tabControl1.SelectedIndex].Lines)
                        {
                            if (compile)
                            {
                                if (!line.Equals("") && !line.StartsWith("#"))
                                {
                                    string newLine = line;
                                    if (line.Contains(commentString))
                                    {
                                        newLine = Regex.Split(newLine, commentString)[0].TrimEnd();
                                    }
                                    string[] info = newLine.Split(' ');
                                    Command c;
                                    bool success = commands.TryGetValue(info[0].ToUpper(), out c);
                                    if (success)
                                    {
                                        HashOrgAddCommand(compiledHashOrg, compiledHashOrgLocations, c, compile, info, lengths, lineNumber, out compile);
                                    }
                                    else
                                    {
                                        SuperCommand sc;
                                        success = superCommands.TryGetValue(info[0].ToUpper(), out sc);
                                        if (success)
                                        {
                                            switch (info[0].ToUpper())
                                            {
                                                case "FORCETYPE":
                                                    {
                                                        byte parameter = ParseByteParameter(info[1], 0, 1).Byte;
                                                        byte[] stuff = ForceTypeSuperCommand(parameter);
                                                        foreach (byte b in stuff)
                                                        {
                                                            compiledHashOrg.Add(b);
                                                        }
                                                        break;
                                                    }
                                                case "PRINTMESSAGE":
                                                    {
                                                        byte position = 0;
                                                        uint locationNew = 0;
                                                        foreach (string s in dynamicStrings.Keys)
                                                        {
                                                            if (s.Equals(info[1]))
                                                            {
                                                                if (s.StartsWith("@"))
                                                                {
                                                                    locationNew = 0x7FFEFEFE;
                                                                }
                                                                else
                                                                {
                                                                    bool succeeded = UInt32.TryParse(s, out locationNew);
                                                                    if (!succeeded)
                                                                    {
                                                                        UInt32.TryParse(ToDecimal(s), out locationNew);
                                                                    }
                                                                }
                                                                break;
                                                            }
                                                            position++;
                                                        }
                                                        ushort parameter2 = ParseHalfWordParameter(info[2], 0, 2).HalfWord;
                                                        byte[] stuff = PrintMessageSuperCommand(position, locationNew, parameter2);
                                                        foreach (byte b in stuff)
                                                        {
                                                            compiledHashOrg.Add(b);
                                                        }
                                                        break;
                                                    }
                                                case "SETHALFWORD":
                                                    {
                                                        uint ramLocation = ParseWordParameter(info[1], 0, 1, false).Word;
                                                        ushort value = ParseHalfWordParameter(info[2], 0, 2).HalfWord;
                                                        byte[] stuff = SetHalfWordSuperCommand(value, ramLocation);
                                                        foreach (byte b in stuff)
                                                        {
                                                            compiledHashOrg.Add(b);
                                                        }
                                                    }
                                                    break;
                                                case "SETWORD":
                                                    {
                                                        uint ramLocation = ParseWordParameter(info[1], 0, 1, false).Word;
                                                        uint value = ParseWordParameter(info[2], 0, 2, false).Word;
                                                        byte[] stuff = SetWordSuperCommand(value, ramLocation);
                                                        foreach (byte b in stuff)
                                                        {
                                                            compiledHashOrg.Add(b);
                                                        }
                                                    }
                                                    break;
                                                case "CALCULATEDAMAGE":
                                                    {
                                                        byte[] stuff = CalculateDamageSuperCommand();
                                                        foreach (byte b in stuff)
                                                        {
                                                            compiledHashOrg.Add(b);
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            SQLiteConnection con = new SQLiteConnection("Data Source=" + System.Windows.Forms.Application.StartupPath + @"\Data\Commands.sqlite;Version=3;");
                                            con.Open();
                                            SQLiteCommand com = new SQLiteCommand("select * from commands where name = '" + info[0].ToUpper() + "'", con);
                                            SQLiteDataReader reader = com.ExecuteReader();
                                            if (reader != null)
                                            {
                                                c = GetCommand(reader, con);
                                                HashOrgAddCommand(compiledHashOrg, compiledHashOrgLocations, c, compile, info, lengths, lineNumber, out compile);
                                            }
                                        }
                                    }
                                }
                            }
                            if (line.StartsWith("#"))
                            {
                                string[] theLine = line.Split(' ');
                                switch (theLine[0])
                                {
                                    case "#define":
                                        {
                                            int temp = 0;
                                            bool success = Int32.TryParse(theLine[2], out temp);
                                            if (success)
                                            {
                                                try
                                                {
                                                    userDefinitions.Add(theLine[1].ToUpper(), UInt32.Parse(theLine[2]));
                                                }
                                                catch (FormatException)
                                                {
                                                    MessageBox.Show("A number was expected for parameter 2 of the definition");
                                                }
                                                catch
                                                {
                                                    MessageBox.Show("There was an unknown error with the custom definition");
                                                }
                                            }
                                            else
                                            {
                                                try
                                                {
                                                    userDefinitions.Add(theLine[1].ToUpper(), UInt32.Parse(ToDecimal(theLine[2])));
                                                }
                                                catch (FormatException)
                                                {
                                                    MessageBox.Show("A number was expected for parameter 2 of the definition");
                                                }
                                                catch
                                                {
                                                    MessageBox.Show("There was an unknown error with the custom definition");
                                                }
                                            }
                                            break;
                                        }
                                    case "#dynamic":
                                        {
                                            freeSpaceLocation = 0;
                                            bool success = Int32.TryParse(theLine[1], out freeSpaceLocation);
                                            if (!success)
                                            {
                                                success = Int32.TryParse(ToDecimal(theLine[1]), out freeSpaceLocation);
                                                if (!success)
                                                {
                                                    MessageBox.Show("Error. Dynamic offset could not be parsed from script. Dynamic offset set to 0. WARNING: SLOW!");
                                                }
                                            }
                                            if (success)
                                            {
                                                dynamicLocationSet = true;
                                            }
                                            break;
                                        }
                                    case "#include":
                                        string filePath = System.Windows.Forms.Application.StartupPath + @"\Data\" + theLine[1];
                                        if (!filePath.EndsWith(".bsh"))
                                        {
                                            filePath += ".bsh";
                                        }
                                        if (!File.Exists(filePath))
                                        {
                                            MessageBox.Show("The included header file could not be found.");
                                            break;
                                        }
                                        else
                                        {
                                            if (!theLine[1].Equals("std"))
                                            {
                                                string[] rbhFile = File.ReadAllLines(filePath);
                                                ParseHeaderFile(rbhFile);
                                            }
                                        }
                                        break;
                                    case "#clean":
                                        {
                                            if (scriptInserted)
                                            {
                                                byte[] romFile = File.ReadAllBytes(selectedROMPath);
                                                for (int i = 0; i < lastInsertedScriptLength; i++)
                                                {
                                                    romFile[lastInsertedScriptLocation + i] = 0xFF;
                                                }
                                                try
                                                {
                                                    File.WriteAllBytes(selectedROMPath, romFile);
                                                    scriptInserted = false;
                                                }
                                                catch
                                                {
                                                    MessageBox.Show("There was an error writing the compiled script to the ROM. Try closing any tools that the ROM is already open in. If the ROM is not open in any tools, contact Jambo51 on the tool's page.");
                                                }
                                            }
                                        }
                                        break;
                                    case "#org":
                                        if (hashOrgs.Contains(theLine[1]))
                                        {
                                            if (theLine[1].StartsWith("@"))
                                            {
                                                if (theLine[1].Equals(hashOrgName))
                                                {
                                                    location2 = FindFreeSpace(scriptLength, freeSpaceLocation, File.ReadAllBytes(selectedROMPath));
                                                    compile = true;
                                                }
                                                else
                                                {
                                                    if (compile)
                                                    {
                                                        compile = false;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (theLine[1].Equals(hashOrgName))
                                                {
                                                    compile = true;
                                                }
                                                else
                                                {
                                                    if (compile)
                                                    {
                                                        compile = false;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (theLine[1].Equals(hashOrgName))
                                            {
                                                compile = true;
                                            }
                                            else
                                            {
                                                if (compile)
                                                {
                                                    compile = false;
                                                }
                                            }
                                        }
                                        break;
                                    case "#freespacebyte":
                                        {
                                            bool success = Byte.TryParse(theLine[1], out freeSpaceByte);
                                            if (!success)
                                            {
                                                success = Byte.TryParse(ToDecimal(theLine[1]), out freeSpaceByte);
                                                if (!success)
                                                {
                                                    MessageBox.Show("Error. Free space byte could not be parsed from script. Free Space Byte set to 0xFF.");
                                                }
                                            }
                                        }
                                        break;
                                    default:
                                        break;
                                }
                            }
                            lineNumber++;
                        }
                        byte[] rom = File.ReadAllBytes(selectedROMPath);
                        if (firstTime)
                        {
                            firstTime = false;
                            location = FindFreeSpace(lengths[hashOrgName], freeSpaceLocation, rom);
                        }
                        if (hashOrgName.StartsWith("@"))
                        {
                            location2 = FindFreeSpace(lengths[hashOrgName], freeSpaceLocation, rom);
                        }
                        else
                        {
                            bool succeeded = Int32.TryParse(hashOrgName, out location2);
                            if (!succeeded)
                            {
                                succeeded = Int32.TryParse(ToDecimal(hashOrgName), out location2);
                            }
                        }
                        compiledHashOrgLocations.Add(hashOrgName, location2);
                        int index = 0;
                        foreach (byte b in compiledHashOrg)
                        {
                            compiledScript.Add(b);
                            rom[location2 + index] = b;
                            index++;
                        }
                        File.WriteAllBytes(selectedROMPath, rom);
                        userDefinitions.Clear();
                    }
                    byte[] romNew = File.ReadAllBytes(selectedROMPath);
                    int searchLocation = freeSpaceLocation;
                    int tableLocation = 1;
                    while (tableLocation % 4 != 0)
                    {
                        tableLocation = FindFreeSpace(x.Table.Length * 4, searchLocation, romNew);
                        searchLocation++;
                    }
                    lastInsertedScriptLength = tableLocation - (location + compiledScript.Count);
                    int searchLocation2 = tableLocation + (x.Table.Length * 4);
                    searchLocation2 = FindFreeSpace(x.CompiledStringsArray.Length, searchLocation2, romNew);
                    int indexNew = 0;
                    foreach (byte b in x.CompiledStringsArray)
                    {
                        romNew[searchLocation2 + indexNew] = b;
                        indexNew++;
                    }
                    indexNew = 0;
                    foreach (int k in x.Table)
                    {
                        if (k < 0x8000000)
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                romNew[tableLocation + j + (indexNew * 4)] = (Byte.Parse(ToDecimal("0x" + (k + 0x08000000 + searchLocation2).ToString("X8").Substring((k + 0x08000000 + searchLocation2).ToString("X8").Length - ((j * 2) + 2), 2))));
                            }
                        }
                        else
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                romNew[tableLocation + j + (indexNew * 4)] = (Byte.Parse(ToDecimal("0x" + k.ToString("X8").Substring(k.ToString("X8").Length - ((j * 2) + 2), 2))));
                            }
                        }
                        indexNew++;
                    }
                    indexNew = 0;
                    int ignoreCounter = 0;
                    for (int i = 0; i < compiledScript.Count; i++)
                    {
                        byte b = romNew[location + i];
                        if (ignoreCounter == 0)
                        {
                            if (b == 0x13)
                            {
                                if (romNew[location + i + 1] == 0xFE && romNew[location + i + 2] == 0xFE && romNew[location + i + 3] == 0xFE && romNew[location + i + 4] == 0x7F)
                                {
                                    romNew[location + i] = b;
                                    for (int j = 0; j < 4; j++)
                                    {
                                        romNew[location + j + 1 + i] = (Byte.Parse(ToDecimal("0x" + (tableLocation + 0x08000000).ToString("X8").Substring((tableLocation + 0x08000000).ToString("X8").Length - ((j * 2) + 2), 2))));
                                    }
                                    indexNew += 4;
                                    ignoreCounter = 4;
                                }
                            }
                            else
                            {
                                romNew[location + i] = b;
                            }
                        }
                        else
                        {
                            ignoreCounter--;
                        }
                    }
                    File.WriteAllBytes(selectedROMPath, romNew);
                    foreach (string s in hashOrgs)
                    {
                        lastInsertedScriptLength += lengths[s];
                    }
                    lastInsertedScriptLength += x.CompiledStringsArray.Length + 4 * x.Table.Length;
                    lastInsertedScriptLocation = location;
                    scriptInserted = true;
                    keywords.Clear();
                    dynamicStrings.Clear();
                    List<string> left = new List<string>();
                    List<string> right = new List<string>();
                    for (int i = 0; i < compiledHashOrgLocations.Count; i++)
                    {
                        left.Add(hashOrgs[i]);
                        right.Add("0x" + compiledHashOrgLocations[hashOrgs[i]].ToString("X6"));
                    }
                    toolStripStatusLabel1.Text = "Compilation Complete!";
                    Form8 fr = new Form8(left, right);
                    fr.Show();
                }
                else
                {
                    MessageBox.Show("Compilation cancelled.");
                }
            }
            this.Cursor = Cursors.Default;
            keywords.Clear();
            userDefinitions.Clear();
        }
Form1