private string[] DecompileScript(int offset, byte[] rom)
{
if (decompileMode == 2)
{
pokemonExport = new Dictionary<uint,string>();
stdExport = new Dictionary<uint, string>();
typeExport = new Dictionary<uint, string>();
movesExport = new Dictionary<uint, string>();
itemsExport = new Dictionary<uint, string>();
abilitiesExport = new Dictionary<uint, string>();
bankExport = new Dictionary<uint, string>();
ParseHeaderFileToDecompileDictionaries(File.ReadAllLines(System.Windows.Forms.Application.StartupPath + @"\Data\std.bsh"), stdExport, typeExport, bankExport);
ParseHeaderFileToDecompileDictionaries(File.ReadAllLines(System.Windows.Forms.Application.StartupPath + @"\Data\moves.bsh"), movesExport);
ParseHeaderFileToDecompileDictionaries(File.ReadAllLines(System.Windows.Forms.Application.StartupPath + @"\Data\abilities.bsh"), abilitiesExport);
ParseHeaderFileToDecompileDictionaries(File.ReadAllLines(System.Windows.Forms.Application.StartupPath + @"\Data\items.bsh"), itemsExport);
ParseHeaderFileToDecompileDictionaries(File.ReadAllLines(System.Windows.Forms.Application.StartupPath + @"\Data\pokemon.bsh"), pokemonExport);
}
List<string> toReturn = new List<string>();
string theNumber = CalculateNumberInNumberSystem(offset);
toReturn.Add("#org " + theNumber);
List<int> alternateDebugLocations = new List<int>();
bool decompile = true;
int startingOffset = offset;
while (decompile)
{
if (alternateDebugLocations.Contains(offset) && !decompiledOffsets.Contains(offset))
{
toReturn.Add("");
string theNumber2 = CalculateNumberInNumberSystem(offset);
toReturn.Add("#org " + theNumber2);
for (int i = 0; i < alternateDebugLocations.Count; i++)
{
if (alternateDebugLocations[i] == offset)
{
alternateDebugLocations.RemoveAt(i);
i--;
}
}
startingOffset = offset;
}
byte theValue = rom[offset];
int commandOffset = offset;
string superCommand = "";
bool success = false;
if (decompileMode != 0)
{
success = TryGetSuperCommand(offset, rom, out superCommand, out offset);
}
if (success)
{
if (decompileCommandOffsetsToolStripMenuItem.Checked)
{
superCommand += "\t\t" + commentString + " " + CalculateNumberInNumberSystem(commandOffset + 0x08000000);
}
toReturn.Add(superCommand);
continue;
}
string line = "";
Command c = null;
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 id = " + theValue, con);
SQLiteDataReader reader = com.ExecuteReader();
if (reader.HasRows)
{
line += reader["name"].ToString().ToLower();
c = GetCommand(reader, con);
}
else if (theValue == 0xFF)
{
int tempOffset = offset + 1;
ushort val = (ushort)((0xFF00) + (rom[tempOffset]));
foreach (string s in commands.Keys)
{
if (commands[s].HexID == val)
{
line += s.ToLower();
c = commands[s];
offset++;
}
}
}
else
{
foreach (string s in commands.Keys)
{
if (commands[s].HexID == theValue)
{
line += s.ToLower();
c = commands[s];
break;
}
}
}
con.Close();
if (c == null)
{
MessageBox.Show("Error with command at offset " + CalculateNumberInNumberSystem(offset) + ". Unknown command.");
break;
}
else
{
for (int i = 0; i < c.NumberOfParameters; i++)
{
if (c.HexID == 0x89 && i == 0)
{
if (decompileMode == 2)
{
line += " " + CalculateNumberInNumberSystem(rom[offset + 1] & 0xBF);
if ((rom[offset + 1] & 0x40) != 0)
{
line += " true";
}
else
{
line += " false";
}
}
else
{
line += " " + CalculateNumberInNumberSystem(rom[offset + 1]);
}
offset++;
i++;
}
else
{
switch (c.ParameterLengths[i])
{
case 4:
{
int value = DecompileWordParameter(offset + 1, rom);
if (c.ParameterNames[i].Contains("ROM Address") && c.HexID != 0x7A)
{
if (!alternateDebugLocations.Contains(value - 0x08000000) && !decompiledOffsets.Contains(value - 0x08000000))
{
alternateDebugLocations.Add(value - 0x08000000);
}
}
else if (decompileMode == 2)
{
con.Open();
com = new SQLiteCommand("select type from commanddecompiletypes where commandid = " + c.HexID + " AND parameterid = " + i, con);
reader = com.ExecuteReader();
if (reader.HasRows)
{
string type = reader["type"].ToString();
GetStringFromType(type, Convert.ToUInt32(value));
}
con.Close();
}
line += " " + CalculateNumberInNumberSystem(value);
offset += 4;
if (c.HexID == 0x28)
{
decompile = false;
if (!decompiledOffsets.Contains(value - 0x08000000))
{
offset = value - 0x08000001;
}
}
break;
}
case 2:
{
if (decompileMode == 2)
{
con.Open();
com = new SQLiteCommand("select type from commanddecompiletypes where commandid = " + c.HexID + " AND parameterid = " + i, con);
reader = com.ExecuteReader();
if (reader.HasRows)
{
string type = reader["type"].ToString();
line += " " + GetStringFromType(type, Convert.ToUInt32(DecompileHalfWordParameter(offset + 1, rom)));
}
else
{
line += " " + CalculateNumberInNumberSystem(DecompileHalfWordParameter(offset + 1, rom));
}
con.Close();
}
else
{
line += " " + CalculateNumberInNumberSystem(DecompileHalfWordParameter(offset + 1, rom));
}
offset += 2;
break;
}
default:
{
if (decompileMode == 2)
{
con.Open();
com = new SQLiteCommand("select type from commanddecompiletypes where commandid = " + c.HexID + " AND parameterid = " + i, con);
reader = com.ExecuteReader();
if (reader.HasRows)
{
string type = reader["type"].ToString();
line += " " + GetStringFromType(type, Convert.ToUInt32(DecompileByteParameter(offset + 1, rom)));
}
else
{
line += " " + CalculateNumberInNumberSystem(DecompileByteParameter(offset + 1, rom));
}
con.Close();
}
else
{
line += " " + CalculateNumberInNumberSystem(DecompileByteParameter(offset + 1, rom));
}
offset++;
break;
}
}
}
}
if (decompileCommandOffsetsToolStripMenuItem.Checked)
{
line += "\t\t" + commentString + " " + CalculateNumberInNumberSystem(commandOffset + 0x08000000);
}
toReturn.Add(line);
offset++;
con = new SQLiteConnection("Data Source=" + System.Windows.Forms.Application.StartupPath + @"\Data\Commands.sqlite;Version=3;");
con.Open();
com = new SQLiteCommand("select * from endingcommands where id = " + c.HexID, con);
reader = com.ExecuteReader();
if (reader.HasRows)
{
decompile = false;
}
if (!decompile)
{
if (c.HexID == 0x28)
{
if (!decompiledOffsets.Contains(startingOffset))
{
decompiledOffsets.Add(startingOffset);
}
else
{
decompile = true;
}
}
}
}
}
toReturn.Add("");
foreach (int i in alternateDebugLocations)
{
if (!decompiledOffsets.Contains(i))
{
string[] temp = DecompileScript(i, rom);
foreach (string s in temp)
{
toReturn.Add(s);
}
}
}
pokemonExport = null;
stdExport = null;
movesExport = null;
itemsExport = null;
abilitiesExport = null;
return toReturn.ToArray();
}