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
|
|
|
|
|
|
|
|
|
static void Main(string[] args)
|
|
|
|
|
{
|
2015-03-16 04:16:12 +00:00
|
|
|
|
options = ParseCommandLine(args);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
if (options == null)
|
|
|
|
|
{
|
|
|
|
|
Usage();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-22 23:55:34 +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-13 22:04:23 +00:00
|
|
|
|
if (options.Command == CommandType.Decompile)
|
|
|
|
|
{
|
2015-03-22 23:55:34 +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-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Load ROMs
|
2015-03-16 04:16:12 +00:00
|
|
|
|
ebRom = File.ReadAllBytes(options.EbRom);
|
|
|
|
|
m12Rom = File.ReadAllBytes(options.M12Rom);
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
|
|
|
|
// Decompile misc string tables
|
|
|
|
|
if (options.DoMiscText)
|
|
|
|
|
{
|
2015-03-16 04:16:12 +00:00
|
|
|
|
//DecompileEbMisc();
|
|
|
|
|
DecompileM12Misc();
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decompile main string tables
|
|
|
|
|
if (options.DoMainText)
|
|
|
|
|
{
|
2015-03-22 23:55:34 +00:00
|
|
|
|
DecompileEb();
|
2015-03-16 04:16:12 +00:00
|
|
|
|
DecompileM12();
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (options.Command == CommandType.Compile)
|
|
|
|
|
{
|
2015-03-22 23:55:34 +00:00
|
|
|
|
// Set up compilers
|
|
|
|
|
m12Compiler = new Compiler(M12ControlCode.Codes, (rom, address) => rom[address + 1] == 0xFF);
|
2015-03-16 04:16:12 +00:00
|
|
|
|
|
|
|
|
|
using (IncludeFile = File.CreateText(Path.Combine(options.WorkingDirectory, "m12-includes.asm")))
|
|
|
|
|
{
|
|
|
|
|
IncludeFile.WriteLine("arch gba.thumb");
|
|
|
|
|
|
2015-03-18 16:31:42 +00:00
|
|
|
|
// Compile main string tables
|
|
|
|
|
if (options.DoMainText)
|
|
|
|
|
{
|
|
|
|
|
CompileM12();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
// Compile misc string tables
|
|
|
|
|
if (options.DoMiscText)
|
|
|
|
|
{
|
|
|
|
|
CompileM12Misc();
|
|
|
|
|
}
|
|
|
|
|
}
|
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))
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
// Check for ROM paths
|
|
|
|
|
string ebRom = null;
|
|
|
|
|
string m12Rom = null;
|
|
|
|
|
if (command == CommandType.Decompile && argList.Count == 3)
|
|
|
|
|
{
|
|
|
|
|
ebRom = argList[1];
|
|
|
|
|
m12Rom = argList[2];
|
|
|
|
|
if (!File.Exists(ebRom) || !File.Exists(m12Rom))
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)));
|
|
|
|
|
allRefs.Add(Tuple.Create("eb-enemy-encounters", EbTextTables.ReadEnemyTextRefs(ebRom)));
|
|
|
|
|
|
|
|
|
|
// 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]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-16 18:44:47 +00:00
|
|
|
|
allRefs.Add(Tuple.Create("m12-psihelp", M12TextTables.ReadPsiHelpRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-battle-actions", M12TextTables.ReadBattleActionRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-itemhelp", M12TextTables.ReadItemHelpRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-movements", M12TextTables.ReadMovementRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-objects", M12TextTables.ReadObjectRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-phonelist", M12TextTables.ReadPhoneRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-unknown", M12TextTables.ReadUnknownRefs(m12Rom)));
|
|
|
|
|
allRefs.Add(Tuple.Create("m12-enemy-encounters", M12TextTables.ReadEnemyEncounters(m12Rom)));
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
// Update labels for all refs and write to JSON
|
|
|
|
|
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];
|
2015-03-13 22:04:23 +00:00
|
|
|
|
|
2015-03-16 04:16:12 +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-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);
|
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 =
|
2015-03-16 04:16:12 +00:00
|
|
|
|
decompiler.DecompileRange(rom, fixedStringRef.OldPointer,
|
|
|
|
|
fixedStringRef.OldPointer + fixedStringCollection.EntryLength, 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
|
|
|
|
}
|
|
|
|
|
|
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-18 16:31:42 +00:00
|
|
|
|
"m12-psihelp",
|
|
|
|
|
"m12-battle-actions",
|
|
|
|
|
"m12-itemhelp",
|
|
|
|
|
"m12-movements",
|
|
|
|
|
"m12-objects",
|
|
|
|
|
"m12-phonelist",
|
|
|
|
|
"m12-unknown",
|
|
|
|
|
"m12-asmrefs",
|
|
|
|
|
"m12-enemy-encounters",
|
|
|
|
|
"m12-prayers"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using (var labelAsmFile = File.CreateText(Path.Combine(options.WorkingDirectory, "m12-main-strings.asm")))
|
|
|
|
|
{
|
|
|
|
|
labelAsmFile.WriteLine(String.Format("org ${0:X}; incbin m12-main-strings.bin", baseAddress | 0x8000000));
|
|
|
|
|
labelAsmFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
foreach (var file in labelFiles)
|
|
|
|
|
{
|
|
|
|
|
var mainStringRefs = JsonConvert.DeserializeObject<MainStringRef[]>(File.ReadAllText(
|
|
|
|
|
Path.Combine(options.WorkingDirectory, file + ".json")));
|
|
|
|
|
|
|
|
|
|
foreach (var stringRef in mainStringRefs)
|
|
|
|
|
{
|
|
|
|
|
labelAsmFile.WriteLine(String.Format("org ${0:X}; dd ${1:X8}",
|
|
|
|
|
stringRef.PointerLocation | 0x8000000, m12Compiler.AddressMap[stringRef.Label] | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IncludeFile.WriteLine("incsrc m12-main-strings.asm");
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:16:12 +00:00
|
|
|
|
static void CompileM12Misc()
|
|
|
|
|
{
|
|
|
|
|
int referenceAddress = 0xB3C000;
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
{
|
|
|
|
|
IncludeFile.WriteLine(String.Format("org ${0:X}; dd ${1:X8}",
|
|
|
|
|
address | 0x8000000, psiPointer | 0x8000000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PSI targets
|
|
|
|
|
CompileM12FixedStringCollection("m12-psitargets", 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
|
|
|
|
|
offsetFile.WriteLine(String.Format("org ${0:X}; incbin {1}.bin",
|
|
|
|
|
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
|
|
|
|
{
|
|
|
|
|
offsetFile.WriteLine(String.Format("org ${0:X}; dd ${1:X8}",
|
|
|
|
|
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
|
|
|
|
|
IncludeFile.WriteLine("incsrc " + name + ".asm");
|
|
|
|
|
}
|
2015-03-18 16:31:42 +00:00
|
|
|
|
|
|
|
|
|
static IList<int> CompileM12FixedStringCollection(string name, ref int referenceAddress)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
offsetFile.WriteLine(String.Format("org ${0:X}; incbin {1}.bin",
|
|
|
|
|
baseAddress | 0x8000000, name));
|
|
|
|
|
offsetFile.WriteLine();
|
|
|
|
|
|
|
|
|
|
// Update table pointers
|
|
|
|
|
foreach (int tablePointer in stringCollection.TablePointers)
|
|
|
|
|
{
|
|
|
|
|
offsetFile.WriteLine(String.Format("org ${0:X}; dd ${1:X8}",
|
|
|
|
|
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
|
|
|
|
|
IncludeFile.WriteLine("incsrc " + name + ".asm");
|
|
|
|
|
|
|
|
|
|
return newPointers;
|
|
|
|
|
}
|
2015-03-13 22:04:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|