2015-03-13 22:04:23 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
|
|
namespace ScriptTool
|
|
|
|
|
{
|
|
|
|
|
class Program
|
|
|
|
|
{
|
2015-03-16 04:16:12 +00:00
|
|
|
|
// Options
|
|
|
|
|
static CommandOptions options;
|
|
|
|
|
|
|
|
|
|
// ROMs
|
|
|
|
|
static byte[] ebRom;
|
|
|
|
|
static byte[] m12Rom;
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Decompiler setup
|
2015-03-22 23:55:34 +00:00
|
|
|
|
static Decompiler m12Decompiler;
|
|
|
|
|
static Decompiler ebDecompiler;
|
|
|
|
|
|
|
|
|
|
static IDictionary<byte, string> m12CharLookup;
|
|
|
|
|
static IDictionary<byte, string> ebCharLookup;
|
2015-03-16 04:16:12 +00:00
|
|
|
|
|
|
|
|
|
// Compiler setup
|
2015-03-22 23:55:34 +00:00
|
|
|
|
static Compiler m12Compiler;
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static StreamWriter IncludeFile;
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
static int Main(string[] args)
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
try
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
options = ParseCommandLine(args);
|
|
|
|
|
if (options == null)
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
Usage();
|
|
|
|
|
return -1;
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
m12CharLookup = JsonConvert.DeserializeObject<Dictionary<byte, string>>(File.ReadAllText("m12-char-lookup.json"));
|
|
|
|
|
ebCharLookup = JsonConvert.DeserializeObject<Dictionary<byte, string>>(File.ReadAllText("eb-char-lookup.json"));
|
2015-03-16 04:16:12 +00:00
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
if (options.Command == CommandType.Decompile)
|
2015-03-16 04:16:12 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
// Set up decompilers
|
|
|
|
|
m12Decompiler = new Decompiler(M12ControlCode.Codes, m12CharLookup, (rom, address) => rom[address + 1] == 0xFF);
|
|
|
|
|
ebDecompiler = new Decompiler(EbControlCode.Codes, ebCharLookup, (rom, address) => rom[address] < 0x20);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
// Load ROMs
|
|
|
|
|
ebRom = File.ReadAllBytes(options.EbRom);
|
|
|
|
|
m12Rom = File.ReadAllBytes(options.M12Rom);
|
|
|
|
|
|
|
|
|
|
// Decompile misc string tables
|
|
|
|
|
if (options.DoMiscText)
|
2015-03-18 16:31:42 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
//DecompileEbMisc();
|
|
|
|
|
DecompileM12Misc();
|
2015-03-18 16:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
// Decompile main string tables
|
|
|
|
|
if (options.DoMainText)
|
2015-03-16 04:16:12 +00:00
|
|
|
|
{
|
2019-01-03 03:05:51 +00:00
|
|
|
|
DecompileEb();
|
|
|
|
|
DecompileM12();
|
2015-03-16 04:16:12 +00:00
|
|
|
|
}
|
2019-01-03 03:05:51 +00:00
|
|
|
|
}
|
|
|
|
|
else if (options.Command == CommandType.Compile)
|
|
|
|
|
{
|
|
|
|
|
// Set up compilers
|
|
|
|
|
m12Compiler = new Compiler(M12ControlCode.Codes, (rom, address) => rom[address + 1] == 0xFF);
|
2017-03-29 05:19:51 +01:00
|
|
|
|
|
2019-01-03 03:05:51 +00:00
|
|
|
|
using (IncludeFile = File.CreateText(Path.Combine(options.WorkingDirectory, "m12-includes.asm")))
|
|
|
|
|
{
|
|
|
|
|
IncludeFile.WriteLine(".gba");
|
|
|
|
|
IncludeFile.WriteLine(".open \"../m12.gba\",0x8000000");
|
|
|
|
|
|
|
|
|
|
// Compile main string tables
|
|
|
|
|
if (options.DoMainText)
|
|
|
|
|
{
|
|
|
|
|
CompileM12();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compile misc string tables
|
|
|
|
|
if (options.DoMiscText)
|
|
|
|
|
{
|
|
|
|
|
CompileM12Misc();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IncludeFile.WriteLine(".close");
|
|
|
|
|
}
|
2015-03-16 04:16:12 +00:00
|
|
|
|
}
|
2019-01-03 03:05:51 +00:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Encountered exception:");
|
|
|
|
|
Console.WriteLine(ex);
|
|
|
|
|
return -1;
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void Usage()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Usage:");
|
|
|
|
|
Console.WriteLine(" ScriptTool.exe [-decompile or -compile] [-misc] [-main] workingdirectory [ebrom m12rom]");;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static CommandOptions ParseCommandLine(string[] args)
|
|
|
|
|
{
|
|
|
|
|
var argList = new List<string>(args);
|
|
|
|
|
|
|
|
|
|
// Check for decompile switch
|
|
|
|
|
CommandType command;
|
|
|
|
|
if (argList.Contains("-decompile") && !argList.Contains("-compile"))
|
|
|
|
|
{
|
|
|
|
|
command = CommandType.Decompile;
|
|
|
|
|
argList.Remove("-decompile");
|
|
|
|
|
}
|
|
|
|
|
else if (argList.Contains("-compile") && !argList.Contains("-decompile"))
|
|
|
|
|
{
|
|
|
|
|
command = CommandType.Compile;
|
|
|
|
|
argList.Remove("-compile");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for main and misc flags
|
|
|
|
|
bool doMain = false;
|
|
|
|
|
bool doMisc = false;
|
|
|
|
|
if (argList.Contains("-main"))
|
|
|
|
|
{
|
|
|
|
|
doMain = true;
|
|
|
|
|
argList.Remove("-main");
|
|
|
|
|
}
|
|
|
|
|
if (argList.Contains("-misc"))
|
|
|
|
|
{
|
|
|
|
|
doMisc = true;
|
|
|
|
|
argList.Remove("-misc");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for working directory
|
|
|
|
|
if (argList.Count < 1)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
string working = argList[0];
|
|
|
|
|
if (!Directory.Exists(working))
|
2019-01-03 03:05:51 +00:00
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Directory does not exist: " + Path.GetFullPath(working));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
return null;
|
2019-01-03 03:05:51 +00:00
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Check for ROM paths
|
|
|
|
|
string ebRom = null;
|
|
|
|
|
string m12Rom = null;
|
|
|
|
|
if (command == CommandType.Decompile && argList.Count == 3)
|
|
|
|
|
{
|
|
|
|
|
ebRom = argList[1];
|
|
|
|
|
m12Rom = argList[2];
|
2019-01-03 03:05:51 +00:00
|
|
|
|
|
|
|
|
|
if (!File.Exists(ebRom))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("File does not exist: " + Path.GetFullPath(ebRom));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
return null;
|
2019-01-03 03:05:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(m12Rom))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("File does not exist: " + Path.GetFullPath(m12Rom));
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new CommandOptions
|
|
|
|
|
{
|
|
|
|
|
WorkingDirectory = working,
|
|
|
|
|
EbRom = ebRom,
|
|
|
|
|
M12Rom = m12Rom,
|
|
|
|
|
Command = command,
|
|
|
|
|
DoMainText = doMain,
|
|
|
|
|
DoMiscText = doMisc
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-22 23:55:34 +00:00
|
|
|
|
static void DecompileEb()
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
// Pull all string refs from the ROM
|
|
|
|
|
var allRefs = new List<Tuple<string, MainStringRef[]>>();
|
2015-03-22 23:55:34 +00:00
|
|
|
|
|
|
|
|
|
var tptTuple = EbTextTables.ReadTptRefs(ebRom);
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-tpt-primary", tptTuple.Item1));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-tpt-secondary", tptTuple.Item2));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("eb-battle-actions", EbTextTables.ReadBattleActionRefs(ebRom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-prayers", EbTextTables.ReadPrayerRefs(ebRom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-item-help", EbTextTables.ReadItemHelpRefs(ebRom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-psi-help", EbTextTables.ReadPsiHelpRefs(ebRom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-phone", EbTextTables.ReadPhoneRefs(ebRom)));
|
2015-08-13 20:57:49 +01:00
|
|
|
|
allRefs.Add(Tuple.Create("eb-enemy-encounters", EbTextTables.ReadEnemyEncounters(ebRom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-enemy-deaths", EbTextTables.ReadEnemyDeaths(ebRom)));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Decompile
|
2015-03-22 23:55:34 +00:00
|
|
|
|
var allPointers = allRefs.SelectMany(rl => rl.Item2).Select(r => r.OldPointer);
|
|
|
|
|
ebDecompiler.LabelMap.AddRange(allPointers);
|
|
|
|
|
|
|
|
|
|
IList<int[]> textRanges = new List<int[]>();
|
|
|
|
|
textRanges.Add(new int[] { 0x50000, 0x5FFEC });
|
|
|
|
|
textRanges.Add(new int[] { 0x60000, 0x6FFE3 });
|
|
|
|
|
textRanges.Add(new int[] { 0x70000, 0x7FF40 });
|
|
|
|
|
textRanges.Add(new int[] { 0x80000, 0x8BC2D });
|
|
|
|
|
textRanges.Add(new int[] { 0x8D9ED, 0x8FFF3 });
|
|
|
|
|
textRanges.Add(new int[] { 0x90000, 0x9FF2F });
|
|
|
|
|
textRanges.Add(new int[] { 0x2F4E20, 0x2FA460 });
|
|
|
|
|
|
|
|
|
|
var strings = new List<string>();
|
|
|
|
|
foreach (var range in textRanges)
|
|
|
|
|
{
|
|
|
|
|
ebDecompiler.ScanRange(ebRom, range[0], range[1]);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-19 16:18:52 +00:00
|
|
|
|
// Bit of a hack for now -- to avoid messing up label order, add new refs *after* scanning the ROM
|
|
|
|
|
var doorStuff = EbTextTables.ReadDoors(ebRom);
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-doors", doorStuff[0]));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-doorgaps", doorStuff[1]));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-dungeonman", doorStuff[2]));
|
|
|
|
|
ebDecompiler.LabelMap.AddRange(allRefs.Skip(9).SelectMany(r1 => r1.Item2).Select(r => r.OldPointer));
|
|
|
|
|
|
2015-03-22 23:55:34 +00:00
|
|
|
|
foreach (var range in textRanges)
|
|
|
|
|
{
|
|
|
|
|
strings.Add(ebDecompiler.DecompileRange(ebRom, range[0], range[1], true));
|
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Update labels for all refs and write to JSON
|
|
|
|
|
foreach (var refList in allRefs)
|
|
|
|
|
{
|
|
|
|
|
foreach (var stringRef in refList.Item2)
|
2015-03-22 23:55:34 +00:00
|
|
|
|
stringRef.Label = ebDecompiler.LabelMap.Labels[stringRef.OldPointer];
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2015-03-22 23:55:34 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, refList.Item1 + ".json"),
|
|
|
|
|
JsonConvert.SerializeObject(refList.Item2, Formatting.Indented));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the strings
|
2015-03-22 23:55:34 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, "eb-strings.txt"), String.Join(Environment.NewLine, strings));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void DecompileM12()
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
// Pull all string refs from the ROM
|
|
|
|
|
var allRefs = new List<Tuple<string, MainStringRef[]>>();
|
2015-03-20 21:40:43 +00:00
|
|
|
|
|
|
|
|
|
var tptTuple = M12TextTables.ReadTptRefs(m12Rom);
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-tpt-primary", tptTuple.Item1));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-tpt-secondary", tptTuple.Item2));
|
2015-03-25 15:55:09 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-psi-help", M12TextTables.ReadPsiHelpRefs(m12Rom)));
|
2015-03-16 18:44:47 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-battle-actions", M12TextTables.ReadBattleActionRefs(m12Rom)));
|
2015-03-25 15:55:09 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-item-help", M12TextTables.ReadItemHelpRefs(m12Rom)));
|
2015-03-16 18:44:47 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-movements", M12TextTables.ReadMovementRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-objects", M12TextTables.ReadObjectRefs(m12Rom)));
|
2015-03-25 15:55:09 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-phone-list", M12TextTables.ReadPhoneRefs(m12Rom)));
|
2015-03-16 18:44:47 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-unknown", M12TextTables.ReadUnknownRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-enemy-encounters", M12TextTables.ReadEnemyEncounters(m12Rom)));
|
2015-08-13 20:57:49 +01:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-enemy-deaths", M12TextTables.ReadEnemyDeaths(m12Rom)));
|
2015-03-16 18:44:47 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-prayers", M12TextTables.ReadPrayerRefs(m12Rom)));
|
2015-03-24 06:16:42 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-asmrefs", M12TextTables.ReadAsmRefs(m12Rom)));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Decompile
|
2015-03-16 04:16:12 +00:00
|
|
|
|
var allPointers = allRefs.SelectMany(rl => rl.Item2).Select(r => r.OldPointer);
|
|
|
|
|
m12Decompiler.LabelMap.AddRange(allPointers);
|
|
|
|
|
|
|
|
|
|
var strings = new List<string>();
|
|
|
|
|
m12Decompiler.ScanRange(m12Rom, 0x3697F, 0x8C4B0);
|
|
|
|
|
strings.Add(m12Decompiler.DecompileRange(m12Rom, 0x3697F, 0x8C4B0, true));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2017-03-18 17:47:25 +00:00
|
|
|
|
// Update labels for all refs
|
2015-03-13 22:04:23 +00:00
|
|
|
|
foreach (var refList in allRefs)
|
|
|
|
|
{
|
|
|
|
|
foreach (var stringRef in refList.Item2)
|
2015-03-16 04:16:12 +00:00
|
|
|
|
stringRef.Label = m12Decompiler.LabelMap.Labels[stringRef.OldPointer];
|
2017-03-18 17:47:25 +00:00
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2017-03-18 17:47:25 +00:00
|
|
|
|
// Write to JSON
|
|
|
|
|
foreach (var refList in allRefs)
|
|
|
|
|
{
|
2015-03-16 04:16:12 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, refList.Item1 + ".json"),
|
2017-03-18 17:47:25 +00:00
|
|
|
|
JsonConvert.SerializeObject(refList.Item2, Formatting.Indented));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the strings
|
2015-03-16 04:16:12 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, "m12-strings.txt"), String.Join(Environment.NewLine, strings));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void DecompileM12Misc()
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
// Item names
|
|
|
|
|
var itemNames = M12TextTables.ReadItemNames(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-itemnames", itemNames);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Menu choices
|
|
|
|
|
var menuChoices = M12TextTables.ReadMenuChoices(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-menuchoices", menuChoices);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Misc text
|
|
|
|
|
var miscText = M12TextTables.ReadMiscText(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-misctext", miscText);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2015-03-13 22:59:17 +00:00
|
|
|
|
// Dad
|
|
|
|
|
var dadText = M12TextTables.ReadDadText(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-dadtext", dadText);
|
2015-03-13 22:59:17 +00:00
|
|
|
|
|
|
|
|
|
// PSI text
|
|
|
|
|
var psiText = M12TextTables.ReadPsiText(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-psitext", psiText);
|
2015-03-13 22:59:17 +00:00
|
|
|
|
|
|
|
|
|
// Enemy names
|
|
|
|
|
var enemyNames = M12TextTables.ReadEnemyNames(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12MiscStringCollection("m12-enemynames", enemyNames);
|
2015-03-13 22:59:17 +00:00
|
|
|
|
|
2015-03-13 22:04:23 +00:00
|
|
|
|
// PSI names
|
|
|
|
|
var psiNames = M12TextTables.ReadPsiNames(m12Rom);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileFixedStringCollection(m12Decompiler, m12Rom, "m12-psinames", psiNames);
|
2015-03-18 16:31:42 +00:00
|
|
|
|
|
|
|
|
|
// PSI targets
|
|
|
|
|
var miscText2 = M12TextTables.ReadPsiTargets(m12Rom);
|
|
|
|
|
DecompileFixedStringCollection(m12Decompiler, m12Rom, "m12-psitargets", miscText2);
|
2017-04-16 04:42:07 +01:00
|
|
|
|
|
|
|
|
|
// Other
|
|
|
|
|
DecompileHardcodedStringCollection(m12Decompiler, m12Rom, "m12-other",
|
|
|
|
|
0xB1B492,
|
|
|
|
|
0xB1B497,
|
|
|
|
|
0xB1B49C,
|
|
|
|
|
0xB1B4A1,
|
|
|
|
|
0xB1B4A6,
|
|
|
|
|
0xB1BA00,
|
|
|
|
|
0xB1BA05,
|
|
|
|
|
0xB1BA0A,
|
|
|
|
|
0xB1BA0F,
|
|
|
|
|
0xB1BA14,
|
|
|
|
|
0xB1BA1A,
|
|
|
|
|
0xB1BA20,
|
|
|
|
|
0xB1BA26,
|
|
|
|
|
0xB1BA2C,
|
|
|
|
|
0xB1BA36,
|
|
|
|
|
0xB1BA40,
|
2017-04-17 00:07:50 +01:00
|
|
|
|
0xB1BA4A,
|
|
|
|
|
0xB1BA54,
|
|
|
|
|
0xB1BA61,
|
|
|
|
|
0xB1BA6E,
|
|
|
|
|
0xB1BA7B);
|
2018-12-14 05:50:56 +00:00
|
|
|
|
|
|
|
|
|
// Teleport destinations
|
|
|
|
|
var teleportNames = M12TextTables.ReadTeleportNames(m12Rom);
|
|
|
|
|
DecompileFixedStringCollection(m12Decompiler, m12Rom, "m12-teleport-names", teleportNames);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void DecompileM12MiscStringCollection(string name, MiscStringCollection miscStringCollection)
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
// Decompile the strings
|
|
|
|
|
foreach (var miscStringRef in miscStringCollection.StringRefs)
|
|
|
|
|
{
|
2015-03-16 04:16:12 +00:00
|
|
|
|
string decompiledString;
|
|
|
|
|
|
|
|
|
|
if (miscStringRef.BasicMode)
|
|
|
|
|
{
|
|
|
|
|
decompiledString = m12Decompiler.ReadFFString(m12Rom, miscStringRef.OldPointer);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
decompiledString = m12Decompiler.DecompileString(m12Rom, miscStringRef.OldPointer, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-13 22:04:23 +00:00
|
|
|
|
miscStringRef.Old =
|
2015-03-16 04:16:12 +00:00
|
|
|
|
miscStringRef.New = decompiledString;
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write JSON
|
2015-03-16 04:16:12 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, name + ".json"),
|
|
|
|
|
JsonConvert.SerializeObject(miscStringCollection, Formatting.Indented));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void DecompileFixedStringCollection(IDecompiler decompiler, byte[] rom, string name, FixedStringCollection fixedStringCollection)
|
2015-03-13 22:04:23 +00:00
|
|
|
|
{
|
|
|
|
|
// Decompile the strings
|
|
|
|
|
foreach (var fixedStringRef in fixedStringCollection.StringRefs)
|
|
|
|
|
{
|
|
|
|
|
fixedStringRef.Old =
|
|
|
|
|
fixedStringRef.New =
|
2018-12-14 05:49:33 +00:00
|
|
|
|
decompiler.DecompileString(rom, fixedStringRef.OldPointer, false);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write JSON
|
2015-03-16 04:16:12 +00:00
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, name + ".json"),
|
|
|
|
|
JsonConvert.SerializeObject(fixedStringCollection, Formatting.Indented));
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-16 04:42:07 +01:00
|
|
|
|
static void DecompileHardcodedStringCollection(IDecompiler decompiler, byte[] rom, string name,
|
|
|
|
|
params int[] pointers)
|
|
|
|
|
{
|
|
|
|
|
var hardcodedRefs = new List<HardcodedString>();
|
|
|
|
|
|
|
|
|
|
foreach (int pointer in pointers)
|
|
|
|
|
{
|
|
|
|
|
string str = decompiler.DecompileString(rom, pointer, false);
|
|
|
|
|
var references = new List<int>();
|
|
|
|
|
|
|
|
|
|
// Search for all references
|
|
|
|
|
for (int refAddress = 0; refAddress < 0x100000; refAddress += 4)
|
|
|
|
|
{
|
|
|
|
|
int value = rom.ReadGbaPointer(refAddress);
|
|
|
|
|
if (value == pointer)
|
|
|
|
|
{
|
|
|
|
|
references.Add(refAddress);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var hardcodedRef = new HardcodedString
|
|
|
|
|
{
|
|
|
|
|
Old = str,
|
|
|
|
|
New = "",
|
|
|
|
|
PointerLocations = references.ToArray(),
|
|
|
|
|
OldPointer = pointer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
hardcodedRefs.Add(hardcodedRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File.WriteAllText(Path.Combine(options.WorkingDirectory, name + ".json"),
|
|
|
|
|
JsonConvert.SerializeObject(hardcodedRefs, Formatting.Indented));
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 16:31:42 +00:00
|
|
|
|
static void CompileM12()
|
|
|
|
|
{
|
|
|
|
|
int baseAddress = 0xB80000;
|
|
|
|
|
int referenceAddress = baseAddress;
|
|
|
|
|
var buffer = new List<byte>();
|
|
|
|
|
|
|
|
|
|
// Get the strings
|
|
|
|
|
string m12Strings = File.ReadAllText(Path.Combine(options.WorkingDirectory, "m12-strings-english.txt"));
|
|
|
|
|
|
|
|
|
|
// Compile
|
2015-03-22 23:55:34 +00:00
|
|
|
|
m12Compiler.ScanString(m12Strings, ref referenceAddress, ebCharLookup, false);
|
2015-03-18 16:31:42 +00:00
|
|
|
|
referenceAddress = baseAddress;
|
2015-03-22 23:55:34 +00:00
|
|
|
|
m12Compiler.CompileString(m12Strings, buffer, ref referenceAddress, ebCharLookup);
|
2015-03-18 16:31:42 +00:00
|
|
|
|
File.WriteAllBytes(Path.Combine(options.WorkingDirectory, "m12-main-strings.bin"), buffer.ToArray());
|
|
|
|
|
|
|
|
|
|
// Update labels
|
|
|
|
|
string[] labelFiles = {
|
2015-03-22 23:55:34 +00:00
|
|
|
|
"m12-tpt-primary",
|
|
|
|
|
"m12-tpt-secondary",
|
2015-03-26 00:48:58 +00:00
|
|
|
|
"m12-psi-help",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
"m12-battle-actions",
|
2015-03-26 00:48:58 +00:00
|
|
|
|
"m12-item-help",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
"m12-movements",
|
|
|
|
|
"m12-objects",
|
2015-03-26 00:48:58 +00:00
|
|
|
|
"m12-phone-list",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
"m12-unknown",
|
|
|
|
|
"m12-asmrefs",
|
|
|
|
|
"m12-enemy-encounters",
|
2015-08-13 20:57:49 +01:00
|
|
|
|
"m12-enemy-deaths",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
"m12-prayers"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using (var labelAsmFile = File.CreateText(Path.Combine(options.WorkingDirectory, "m12-main-strings.asm")))
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
labelAsmFile.WriteLine(String.Format(".org 0x{0:X} :: .incbin \"m12-main-strings.bin\"", baseAddress | 0x8000000));
|
2015-03-18 16:31:42 +00:00
|
|
|
|
labelAsmFile.WriteLine();
|
2018-12-18 01:06:02 +00:00
|
|
|
|
|
2015-03-18 16:31:42 +00:00
|
|
|
|
foreach (var file in labelFiles)
|
|
|
|
|
{
|
|
|
|
|
var mainStringRefs = JsonConvert.DeserializeObject<MainStringRef[]>(File.ReadAllText(
|
|
|
|
|
Path.Combine(options.WorkingDirectory, file + ".json")));
|
|
|
|
|
|
|
|
|
|
foreach (var stringRef in mainStringRefs)
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
labelAsmFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
stringRef.PointerLocation | 0x8000000, m12Compiler.AddressMap[stringRef.Label] | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(".include \"m12-main-strings.asm\"");
|
2018-12-18 01:06:02 +00:00
|
|
|
|
|
|
|
|
|
// Dump labels
|
|
|
|
|
using (var labelFile = File.CreateText(Path.Combine(options.WorkingDirectory, "m12-labels.txt")))
|
|
|
|
|
{
|
|
|
|
|
foreach (var kv in m12Compiler.AddressMap.OrderBy(kv => kv.Key, new LabelComparer()))
|
|
|
|
|
{
|
|
|
|
|
labelFile.WriteLine(String.Format("{0,-30}: 0x{1:X8}", kv.Key, kv.Value | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-18 16:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void CompileM12Misc()
|
|
|
|
|
{
|
2017-03-09 18:13:57 +00:00
|
|
|
|
int referenceAddress = 0xB70000;
|
2015-03-16 04:16:12 +00:00
|
|
|
|
|
|
|
|
|
// Item names
|
|
|
|
|
CompileM12MiscStringCollection("m12-itemnames", ref referenceAddress);
|
|
|
|
|
|
|
|
|
|
// Misc text
|
|
|
|
|
CompileM12MiscStringCollection("m12-misctext", ref referenceAddress);
|
|
|
|
|
|
|
|
|
|
// PSI text
|
|
|
|
|
CompileM12MiscStringCollection("m12-psitext", ref referenceAddress);
|
2015-03-16 18:44:47 +00:00
|
|
|
|
|
|
|
|
|
// Enemy names
|
|
|
|
|
CompileM12MiscStringCollection("m12-enemynames", ref referenceAddress);
|
2015-03-18 16:31:42 +00:00
|
|
|
|
|
2018-12-01 05:40:47 +00:00
|
|
|
|
// Menu choices
|
|
|
|
|
CompileM12MiscStringCollection("m12-menuchoices", ref referenceAddress);
|
|
|
|
|
|
2015-03-18 16:31:42 +00:00
|
|
|
|
// PSI names
|
|
|
|
|
var newPsiPointers = CompileM12FixedStringCollection("m12-psinames", ref referenceAddress);
|
|
|
|
|
|
|
|
|
|
// Fix pointers to specific PSI strings
|
|
|
|
|
int psiPointer = newPsiPointers[1];
|
|
|
|
|
int[] updateAddresses = {
|
|
|
|
|
0xC21AC,
|
|
|
|
|
0xC2364,
|
|
|
|
|
0xC2420,
|
|
|
|
|
0xC24DC,
|
|
|
|
|
0xD3998
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
IncludeFile.WriteLine();
|
|
|
|
|
IncludeFile.WriteLine("// Fix pointers to \"PSI \"");
|
|
|
|
|
foreach (var address in updateAddresses)
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
address | 0x8000000, psiPointer | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PSI targets
|
|
|
|
|
CompileM12FixedStringCollection("m12-psitargets", ref referenceAddress);
|
2017-03-23 04:58:46 +00:00
|
|
|
|
|
|
|
|
|
// Battle command strings
|
2017-03-25 21:05:59 +00:00
|
|
|
|
CompileM12BattleCommands("m12-battle-commands", ref referenceAddress);
|
2017-04-16 04:42:07 +01:00
|
|
|
|
|
|
|
|
|
// Other
|
|
|
|
|
CompileM12HardcodedStringCollection("m12-other", ref referenceAddress);
|
2018-12-14 05:50:56 +00:00
|
|
|
|
|
|
|
|
|
// Teleport destinations
|
|
|
|
|
CompileM12FixedStringCollection("m12-teleport-names", ref referenceAddress);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CompileM12MiscStringCollection(string name, ref int referenceAddress)
|
|
|
|
|
{
|
|
|
|
|
int baseAddress = referenceAddress;
|
|
|
|
|
var buffer = new List<byte>();
|
|
|
|
|
|
|
|
|
|
// Read the JSON
|
|
|
|
|
MiscStringCollection stringCollection = JsonConvert.DeserializeObject<MiscStringCollection>(
|
|
|
|
|
File.ReadAllText(Path.Combine(options.WorkingDirectory, name + ".json")));
|
|
|
|
|
|
|
|
|
|
// Open the offset ASM file
|
|
|
|
|
using (var offsetFile = File.CreateText(Path.Combine(options.WorkingDirectory, name + ".asm")))
|
|
|
|
|
{
|
|
|
|
|
// Include the binfile
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: .incbin \"{1}.bin\"",
|
2015-03-16 04:16:12 +00:00
|
|
|
|
baseAddress | 0x8000000, name));
|
|
|
|
|
offsetFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
// Compile all strings
|
2015-03-18 16:31:42 +00:00
|
|
|
|
foreach (var str in stringCollection.StringRefs.OrderBy(s => s.Index))
|
2015-03-16 04:16:12 +00:00
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2015-03-16 04:16:12 +00:00
|
|
|
|
str.OffsetLocation | 0x8000000, referenceAddress - stringCollection.StringsLocation));
|
|
|
|
|
|
2015-03-22 23:55:34 +00:00
|
|
|
|
m12Compiler.CompileString(str.New, buffer, ref referenceAddress, ebCharLookup);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the buffer
|
|
|
|
|
File.WriteAllBytes(Path.Combine(options.WorkingDirectory, name + ".bin"), buffer.ToArray());
|
|
|
|
|
|
|
|
|
|
// Add to the include file
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(".include \"" + name + ".asm\"");
|
2015-03-16 04:16:12 +00:00
|
|
|
|
}
|
2015-03-18 16:31:42 +00:00
|
|
|
|
|
|
|
|
|
static IList<int> CompileM12FixedStringCollection(string name, ref int referenceAddress)
|
|
|
|
|
{
|
2018-12-14 05:48:47 +00:00
|
|
|
|
// Align to 4 bytes
|
|
|
|
|
referenceAddress = referenceAddress.AlignTo(4);
|
|
|
|
|
|
2015-03-18 16:31:42 +00:00
|
|
|
|
int baseAddress = referenceAddress;
|
|
|
|
|
var buffer = new List<byte>();
|
|
|
|
|
var newPointers = new List<int>();
|
|
|
|
|
|
|
|
|
|
// Read the JSON
|
|
|
|
|
FixedStringCollection stringCollection = JsonConvert.DeserializeObject<FixedStringCollection>(
|
|
|
|
|
File.ReadAllText(Path.Combine(options.WorkingDirectory, name + ".json")));
|
|
|
|
|
|
|
|
|
|
// Open the data ASM file
|
|
|
|
|
using (var offsetFile = File.CreateText(Path.Combine(options.WorkingDirectory, name + ".asm")))
|
|
|
|
|
{
|
|
|
|
|
// Include the binfile
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: .incbin \"{1}.bin\"",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
baseAddress | 0x8000000, name));
|
|
|
|
|
offsetFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
// Update table pointers
|
|
|
|
|
foreach (int tablePointer in stringCollection.TablePointers)
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2015-03-18 16:31:42 +00:00
|
|
|
|
tablePointer | 0x8000000, baseAddress | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compile all strings
|
|
|
|
|
foreach (var str in stringCollection.StringRefs.OrderBy(s => s.Index))
|
|
|
|
|
{
|
|
|
|
|
newPointers.Add(referenceAddress);
|
2015-03-22 23:55:34 +00:00
|
|
|
|
m12Compiler.CompileString(str.New, buffer, ref referenceAddress, ebCharLookup, stringCollection.EntryLength);
|
2015-03-18 16:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the buffer
|
|
|
|
|
File.WriteAllBytes(Path.Combine(options.WorkingDirectory, name + ".bin"), buffer.ToArray());
|
|
|
|
|
|
|
|
|
|
// Add to the include file
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(".include \"" + name + ".asm\"");
|
2015-03-18 16:31:42 +00:00
|
|
|
|
|
|
|
|
|
return newPointers;
|
|
|
|
|
}
|
2017-03-23 04:58:46 +00:00
|
|
|
|
|
|
|
|
|
static int[] CompileM12HardcodedStringCollection(string name, ref int referenceAddress)
|
|
|
|
|
{
|
|
|
|
|
int baseAddress = referenceAddress;
|
|
|
|
|
var buffer = new List<byte>();
|
|
|
|
|
|
|
|
|
|
// Read the JSON
|
|
|
|
|
var hardcodedStrings = JsonConvert.DeserializeObject<HardcodedString[]>(
|
|
|
|
|
File.ReadAllText(Path.Combine(options.WorkingDirectory, name + ".json")));
|
|
|
|
|
|
|
|
|
|
var stringAddresses = new int[hardcodedStrings.Length];
|
|
|
|
|
|
|
|
|
|
// Open the data ASM file
|
|
|
|
|
using (var offsetFile = File.CreateText(Path.Combine(options.WorkingDirectory, name + ".asm")))
|
|
|
|
|
{
|
|
|
|
|
// Include the binfile
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: .incbin \"{1}.bin\"",
|
2017-03-23 04:58:46 +00:00
|
|
|
|
baseAddress | 0x8000000, name));
|
|
|
|
|
offsetFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
// Compile all strings
|
|
|
|
|
int i = 0;
|
|
|
|
|
foreach (var str in hardcodedStrings)
|
|
|
|
|
{
|
2017-04-17 00:04:22 +01:00
|
|
|
|
offsetFile.WriteLine($".definelabel {name.Replace('-', '_')}_str{i},0x{referenceAddress | 0x8000000:X}");
|
|
|
|
|
|
2017-03-23 04:58:46 +00:00
|
|
|
|
foreach (int ptr in str.PointerLocations)
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2017-03-23 04:58:46 +00:00
|
|
|
|
ptr | 0x8000000, referenceAddress | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stringAddresses[i++] = referenceAddress;
|
|
|
|
|
m12Compiler.CompileString(str.New, buffer, ref referenceAddress, ebCharLookup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the buffer
|
|
|
|
|
File.WriteAllBytes(Path.Combine(options.WorkingDirectory, name + ".bin"), buffer.ToArray());
|
|
|
|
|
|
|
|
|
|
// Add to the include file
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(".include \"" + name + ".asm\"");
|
2017-03-23 04:58:46 +00:00
|
|
|
|
|
|
|
|
|
return stringAddresses;
|
|
|
|
|
}
|
2017-03-25 21:05:59 +00:00
|
|
|
|
|
|
|
|
|
static void CompileM12BattleCommands(string name, ref int referenceAddress)
|
|
|
|
|
{
|
|
|
|
|
int baseAddress = referenceAddress;
|
|
|
|
|
var buffer = new List<byte>();
|
|
|
|
|
|
|
|
|
|
// Read the JSON
|
|
|
|
|
var hardcodedStrings = JsonConvert.DeserializeObject<HardcodedString[]>(
|
|
|
|
|
File.ReadAllText(Path.Combine(options.WorkingDirectory, name + ".json")));
|
|
|
|
|
|
|
|
|
|
// Open the data ASM file
|
|
|
|
|
using (var offsetFile = File.CreateText(Path.Combine(options.WorkingDirectory, name + ".asm")))
|
|
|
|
|
{
|
|
|
|
|
// Include the binfile
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: .incbin \"{1}.bin\"",
|
2017-03-25 21:05:59 +00:00
|
|
|
|
baseAddress | 0x8000000, name));
|
|
|
|
|
offsetFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
// The first ten strings will be fixed to 16 bytes per string;
|
|
|
|
|
// the rest are variable-length
|
|
|
|
|
for (int i = 0; i < hardcodedStrings.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
var str = hardcodedStrings[i];
|
|
|
|
|
|
|
|
|
|
foreach (int ptr in str.PointerLocations)
|
|
|
|
|
{
|
2017-03-29 05:19:51 +01:00
|
|
|
|
offsetFile.WriteLine(String.Format(".org 0x{0:X} :: dw 0x{1:X8}",
|
2017-03-25 21:05:59 +00:00
|
|
|
|
ptr | 0x8000000, referenceAddress | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < 10)
|
|
|
|
|
m12Compiler.CompileString(str.New, buffer, ref referenceAddress, ebCharLookup, 16);
|
|
|
|
|
else
|
|
|
|
|
m12Compiler.CompileString(str.New, buffer, ref referenceAddress, ebCharLookup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the buffer
|
|
|
|
|
File.WriteAllBytes(Path.Combine(options.WorkingDirectory, name + ".bin"), buffer.ToArray());
|
|
|
|
|
|
|
|
|
|
// Add to the include file
|
2017-03-29 05:19:51 +01:00
|
|
|
|
IncludeFile.WriteLine(".include \"" + name + ".asm\"");
|
2017-03-25 21:05:59 +00:00
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
2018-12-18 01:06:02 +00:00
|
|
|
|
|
|
|
|
|
class LabelComparer : IComparer<string>
|
|
|
|
|
{
|
|
|
|
|
public int Compare(string x, string y)
|
|
|
|
|
{
|
|
|
|
|
if (x == null)
|
|
|
|
|
return (y == null) ? 0 : -1;
|
|
|
|
|
|
|
|
|
|
if (y == null)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (x.Length == 0 || y.Length == 0)
|
|
|
|
|
return x.CompareTo(y);
|
|
|
|
|
|
|
|
|
|
if (x[0] == 'L' && y[0] == 'L')
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(x.Substring(1), out int xInt) && int.TryParse(y.Substring(1), out int yInt))
|
|
|
|
|
{
|
|
|
|
|
return xInt.CompareTo(yInt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return x.CompareTo(y);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|