Inheritance: System.Windows.Forms.Form
Example #1
0
 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();
 }