Skip to content

Commit e215443

Browse files
committed
Some preparations for 2026
1 parent 800bc18 commit e215443

6 files changed

Lines changed: 132 additions & 85 deletions

File tree

SyatiModuleBuildTool/CompileUtility.cs

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static void Compile(string Flags, string Includes, List<(string source, s
5858
string dir = new FileInfo(CompilerTasks[i].build).DirectoryName ?? throw new Exception();
5959
if (!Directory.Exists(dir))
6060
Directory.CreateDirectory(dir);
61-
if (LaunchProcess(Compiler, $"{CompileCommand} {Flags} \"{CompilerTasks[i].source}\" -o \"{CompilerTasks[i].build}\"") != 0)
61+
if (Utility.LaunchProcess(Compiler, $"{CompileCommand} {Flags} \"{CompilerTasks[i].source}\" -o \"{CompilerTasks[i].build}\"") != 0)
6262
{
6363
throw new Exception($"Failed to compile \"{CompilerTasks[i].source}\"");
6464
}
@@ -69,53 +69,10 @@ public static void Compile(string Flags, string Includes, List<(string source, s
6969
string dir = new FileInfo(AssemblerTasks[i].build).DirectoryName ?? throw new Exception();
7070
if (!Directory.Exists(dir))
7171
Directory.CreateDirectory(dir);
72-
if (LaunchProcess(Assembler, $"{AssembleCommand} {Flags} \"{AssemblerTasks[i].source}\" -o \"{AssemblerTasks[i].build}\"") != 0)
72+
if (Utility.LaunchProcess(Assembler, $"{AssembleCommand} {Flags} \"{AssemblerTasks[i].source}\" -o \"{AssemblerTasks[i].build}\"") != 0)
7373
{
7474
throw new Exception($"Failed to assemble \"{AssemblerTasks[i].source}\"");
7575
}
7676
}
7777
}
78-
79-
80-
public static int LaunchProcess(string Program, string Args)
81-
{
82-
Process process = new()
83-
{
84-
EnableRaisingEvents = true
85-
};
86-
process.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
87-
process.ErrorDataReceived += new DataReceivedEventHandler(Process_ErrorDataReceived);
88-
process.Exited += new EventHandler(Process_Exited);
89-
90-
process.StartInfo.FileName = Program;
91-
process.StartInfo.Arguments = Args;
92-
process.StartInfo.UseShellExecute = false;
93-
process.StartInfo.RedirectStandardError = true;
94-
process.StartInfo.RedirectStandardOutput = true;
95-
96-
process.Start();
97-
process.BeginErrorReadLine();
98-
process.BeginOutputReadLine();
99-
100-
//below line is optional if we want a blocking call
101-
process.WaitForExit();
102-
return process.ExitCode;
103-
}
104-
105-
static void Process_Exited(object? sender, EventArgs e)
106-
{
107-
//Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
108-
}
109-
110-
static void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
111-
{
112-
if ((e.Data?.Length ?? 0) > 0)
113-
Console.WriteLine(e.Data);
114-
}
115-
116-
static void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
117-
{
118-
if ((e.Data?.Length ?? 0) > 0)
119-
Console.WriteLine(e.Data);
120-
}
12178
}

SyatiModuleBuildTool/DiscUtility.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

SyatiModuleBuildTool/ModuleInfo.cs

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,79 @@ namespace SyatiModuleBuildTool;
66

77
public class ModuleInfo
88
{
9+
/// <summary>
10+
/// The name of the module
11+
/// </summary>
912
[AllowNull]
1013
public string Name { get; set; }
14+
/// <summary>
15+
/// The creator(s) of the module (if multiple people, separate with commas like this: Super Hackio, VTXG)
16+
/// </summary>
1117
[AllowNull]
1218
public string Author { get; set; }
19+
/// <summary>
20+
/// A description of the module. Keep this brief, but not worthless ("This is my module" isn't great. "My module adds XYZ ..." is better)<para/>
21+
/// Primary Modules (modules which are very essential to most other modules, such as those which provide a very important function) simply have "[Primary Module]" as the author
22+
/// </summary>
1323
[AllowNull]
1424
public string Description { get; set; }
25+
/// <summary>
26+
/// If this module is an API module, the API ID goes here. This must be unique to other modules to avoid API ID conflicts.<para/>
27+
/// Generally formatted as ModuleName_API
28+
/// </summary>
1529
[AllowNull]
1630
public string APIId { get; set; }
31+
/// <summary>
32+
/// This property allows defining what games/regions/versions of a game that this module works with.<para/>
33+
/// Format: [GAMEID]-VER<para/>
34+
/// Example: RMGE01-0 (SMG1 US Wii All Versions), SB4E01-0 (SMG2 US Wii All Versions), R49E01-0 (DKJB US Wii All Versions), GYBE01-0 (DKJB US GameCube All Versions), SMNE01-1 (NSMBW US Wii Revision 1)
35+
/// </summary>
36+
/// <remarks>The revision numbers are to be decided by community authorities, but 0 will always mean ALL revisions. No revision is the same as ALL revisions</remarks>
37+
[AllowNull]
38+
public string[] SupportedGames { get; set; } // Will be added in 2026
1739

40+
/// <summary>
41+
/// This property indicates which API modules are REQUIRED for this module to compile.
42+
/// </summary>
1843
[AllowNull]
19-
public string[] ModuleDependancies { get; set; }
44+
public string[] ModuleDependancies { get; set; } // This will be renamed in 2026
45+
/// <summary>
46+
/// This property indicates which API modules are OPTIONAL for this module to compile.
47+
/// </summary>
2048
[AllowNull]
21-
public string[] ModuleOptionalDependancies { get; set; }
49+
public string[] ModuleOptionalDependancies { get; set; } // This will be renamed in 2026
50+
/// <summary>
51+
/// Not currently used
52+
/// </summary>
2253
[AllowNull]
23-
public string[] SpecificSourcePaths { get; set; }
54+
public string[] SpecificSourcePaths { get; set; } // Will be added (or removed?) in 2026
55+
/// <summary>
56+
/// This allows modules to specify compiler flags.<para/>
57+
/// This is primarily used in combination with <see cref="ModuleOptionalDependancies"/> to allow optional features based on a module's existance
58+
/// </summary>
2459
[AllowNull]
2560
public string[] CompilerFlags { get; set; }
61+
62+
/// <summary>
63+
/// If this module has CodeGen, the CodeGen definition goes here
64+
/// </summary>
2665
[AllowNull]
2766
public ModuleExtensionInfo[] ModuleExtensionDefinition { get; set; }
28-
67+
/// <summary>
68+
/// If this module has data for OTHER modules, that data goes here.
69+
/// </summary>
2970
[AllowNull]
3071
public object[] ModuleData { get; set; }
3172

73+
74+
/// <summary>
75+
/// The absolute folder path this module is located at
76+
/// </summary>
3277
[JsonIgnore]
3378
public string FolderPath = "";
3479

80+
81+
/// <inheritdoc/>
3582
public override string ToString() => $"""
3683
=== Module Information ===
3784
Name: {Name}
@@ -42,7 +89,6 @@ public override string ToString() => $"""
4289
""";
4390

4491

45-
4692
public static ModuleInfo? Load(string FolderPath)
4793
{
4894
//Read the ModuleInfo
@@ -61,6 +107,10 @@ public override string ToString() => $"""
61107

62108
public class ModuleExtensionInfo
63109
{
110+
/// <summary>
111+
/// The name of this extension declaration
112+
/// </summary>
113+
/// <remarks>Must be unique to other modules</remarks>
64114
[AllowNull]
65115
public string Name { get; set; }
66116
[AllowNull]
@@ -81,8 +131,10 @@ public class ModuleExtensionInfo
81131
[JsonIgnore]
82132
public List<string> IncludePaths = [];
83133

134+
/// <inheritdoc/>
84135
public override string ToString() => $"{Name}, {CodeGenSource}";
85136

137+
86138
public struct CodeGenEntry
87139
{
88140
public string ReplaceTargetName { get; set; }

SyatiModuleBuildTool/ModuleUtility.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ public static string[] CreateModuleDependancyIncludes(ModuleInfo MI, List<Module
370370
if (Path.Exists(cb.Replace("\"", "")))
371371
Includes.Add(cb);
372372
}
373-
return Includes.ToArray();
373+
return [.. Includes];
374374
}
375375

376376

SyatiModuleBuildTool/Program.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ static void Main(string[] args)
1818
return;
1919
}
2020

21-
string SyatiFolderPath = args[1].Replace("\\", "/");
21+
string HeaderRepositoryPath = args[1].Replace("\\", "/");
2222
string ModuleFolderPath = args[2].Replace("\\", "/");
23-
string KamekPath, CompilerPath, AssemblerPath;
23+
string LinkerPath, CompilerPath, AssemblerPath;
2424
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
2525
{
26-
KamekPath = $"{Path.Combine(SyatiFolderPath, "deps/Kamek/Kamek.exe")}";
27-
CompilerPath = $"{Path.Combine(SyatiFolderPath, "deps/CodeWarrior/mwcceppc.exe")}";
28-
AssemblerPath = $"{Path.Combine(SyatiFolderPath, "deps/CodeWarrior/mwasmeppc.exe")}";
26+
LinkerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/Kamek/Kamek.exe")}";
27+
CompilerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/CodeWarrior/mwcceppc.exe")}";
28+
AssemblerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/CodeWarrior/mwasmeppc.exe")}";
2929
}
3030
else
3131
{
32-
KamekPath = $"{Path.Combine(SyatiFolderPath, "deps/Kamek/Kamek")}";
33-
CompilerPath = $"{Path.Combine(SyatiFolderPath, "deps/CodeWarrior/mwcceppc")}";
34-
AssemblerPath = $"{Path.Combine(SyatiFolderPath, "deps/CodeWarrior/mwasmeppc")}";
32+
LinkerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/Kamek/Kamek")}";
33+
CompilerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/CodeWarrior/mwcceppc")}";
34+
AssemblerPath = $"{Path.Combine(HeaderRepositoryPath, "deps/CodeWarrior/mwasmeppc")}";
3535
}
3636
if (!File.Exists(CompilerPath))
3737
{
@@ -43,9 +43,9 @@ static void Main(string[] args)
4343
Error(new MissingMethodException($"Could not locate CodeWarrior PPC Assembler at \"{AssemblerPath}\""));
4444
return;
4545
}
46-
if (!File.Exists(KamekPath))
46+
if (!File.Exists(LinkerPath))
4747
{
48-
Error(new MissingMethodException($"Could not locate Kamek Linker at \"{KamekPath}\""));
48+
Error(new MissingMethodException($"Could not locate Kamek Linker at \"{LinkerPath}\""));
4949
return;
5050
}
5151

@@ -73,10 +73,10 @@ static void Main(string[] args)
7373

7474
for (int i = 0; i < ShortcutsInsideModules.Length; i++)
7575
{
76-
string Target = Utility.GetShortcutTarget(ShortcutsInsideModules[i]);
77-
if (!File.GetAttributes(Target).HasFlag(FileAttributes.Directory))
76+
string? Target = Utility.GetShortcutTarget(ShortcutsInsideModules[i]);
77+
if (Target is null || !File.GetAttributes(Target).HasFlag(FileAttributes.Directory))
7878
{
79-
Console.WriteLine($"Failed to load module: \"{Target}\"");
79+
Console.WriteLine($"Failed to load module: \"{Target ?? ShortcutsInsideModules[i]}\"");
8080
continue;
8181
}
8282

@@ -149,7 +149,7 @@ void TryLoadModule(string ModulePath)
149149

150150
List<string> AllObjectOutputs = [];
151151
string[] IncludePaths = [
152-
"\"" + Path.Combine(SyatiFolderPath, "include") + "\""
152+
"\"" + Path.Combine(HeaderRepositoryPath, "include") + "\""
153153
];
154154
List<string> FlagSet = [ $"-D{args[0]}" ];
155155
for (int i = 3; i < args.Length; i++)
@@ -160,9 +160,9 @@ void TryLoadModule(string ModulePath)
160160
string[] Flags = [.. FlagSet];
161161
Console.WriteLine();
162162
if (args.Any(o => o.Equals("-u")))
163-
ModuleUtility.CompileAllUnibuild(Modules, Flags, IncludePaths, SyatiFolderPath, args[3], ref AllObjectOutputs);
163+
ModuleUtility.CompileAllUnibuild(Modules, Flags, IncludePaths, HeaderRepositoryPath, args[3], ref AllObjectOutputs);
164164
else
165-
ModuleUtility.CompileAllModules(Modules, Flags, IncludePaths, SyatiFolderPath, ref AllObjectOutputs);
165+
ModuleUtility.CompileAllModules(Modules, Flags, IncludePaths, HeaderRepositoryPath, ref AllObjectOutputs);
166166

167167
// If we made it here, we have a successful compile. Hooray!
168168
// I hope linking works...
@@ -172,7 +172,7 @@ void TryLoadModule(string ModulePath)
172172

173173
List<string> SymbolPaths =
174174
[
175-
Path.Combine(SyatiFolderPath, "symbols"),
175+
Path.Combine(HeaderRepositoryPath, "symbols"),
176176
];
177177
SymbolPaths.AddRange(ModuleUtility.CollectModuleSymbols(Modules));
178178
string Symbols = "";
@@ -182,7 +182,7 @@ void TryLoadModule(string ModulePath)
182182
}
183183
string MapFile = $"-output-map=\"{Path.Combine(args[3], $"CustomCode_{args[0]}.map")}\"";
184184
string Output = $"-output-kamek=\"{Path.Combine(args[3], $"CustomCode_{args[0]}.bin")}\"";
185-
int result = CompileUtility.LaunchProcess(KamekPath, $"{string.Join(" ", AllObjectOutputs)} {Symbols} {Output} {MapFile}");
185+
int result = Utility.LaunchProcess(LinkerPath, $"{string.Join(" ", AllObjectOutputs)} {Symbols} {Output} {MapFile}");
186186

187187
if (result != 0)
188188
{
@@ -196,10 +196,10 @@ static void Help()
196196
{
197197
Console.WriteLine(
198198
"""
199-
SyatiModuleBuildTool.exe <REGION> <Path_To_Syati_Repo> <Path_To_Modules_Folder> <Path_To_Output_Folder>
199+
SyatiModuleBuildTool.exe <REGION> <Path_To_Header_Repo> <Path_To_Modules_Folder> <Path_To_Output_Folder>
200200
201201
Extra options:
202-
-u Enable UniBuild. UniBuild can shrink the final .bin file size at the potential cost of debuggability. Should only be used when you have a lot of modules. (10+)
202+
-u Enable UniBuild. UniBuild can shrink the final .bin file size at the potential cost of debuggability. Should only be used when you have a lot of modules. (roughly 10 or more)
203203
""");
204204
}
205205
static void Error(Exception ex)

SyatiModuleBuildTool/Utility.cs

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
namespace SyatiModuleBuildTool;
1+
using System.Diagnostics;
2+
3+
namespace SyatiModuleBuildTool;
24

35
public static class Utility
46
{
5-
public static string GetShortcutTarget(string file)
7+
public static string? GetShortcutTarget(string file)
68
{
79
try
810
{
911
if (!Path.GetExtension(file).Equals(".lnk", StringComparison.OrdinalIgnoreCase))
10-
{
1112
throw new Exception("Supplied file must be a .LNK file");
12-
}
1313

1414
FileStream fileStream = File.Open(file, FileMode.Open, FileAccess.Read);
1515
using BinaryReader fileReader = new(fileStream);
@@ -50,17 +50,15 @@ public static string GetShortcutTarget(string file)
5050
}
5151
catch
5252
{
53-
return "";
53+
return null;
5454
}
5555
}
5656

5757
public static string ReplaceFirst(this string text, string search, string replace)
5858
{
5959
int pos = text.IndexOf(search);
6060
if (pos < 0)
61-
{
6261
return text;
63-
}
6462
return string.Concat(text.AsSpan(0, pos), replace, text.AsSpan(pos + search.Length));
6563
}
6664

@@ -77,6 +75,52 @@ public static List<T> RemoveOneItem<T>(List<T> list, int index)
7775
// Copy element after the index.
7876
list.CopyTo(index + 1, result, index, listCount - 1 - index);
7977

80-
return new List<T>(result);
78+
return [.. result];
79+
}
80+
81+
82+
83+
public static int LaunchProcess(string Program, string Args)
84+
{
85+
ProcessStartInfo PSI = new(Program, Args)
86+
{
87+
UseShellExecute = false,
88+
RedirectStandardError = true,
89+
RedirectStandardOutput = true,
90+
};
91+
92+
Process process = new()
93+
{
94+
StartInfo = PSI,
95+
EnableRaisingEvents = true,
96+
};
97+
process.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
98+
process.ErrorDataReceived += new DataReceivedEventHandler(Process_ErrorDataReceived);
99+
process.Exited += new EventHandler(Process_Exited);
100+
101+
process.Start();
102+
process.BeginErrorReadLine();
103+
process.BeginOutputReadLine();
104+
105+
//below line is optional if we want a blocking call
106+
process.WaitForExit();
107+
return process.ExitCode;
108+
}
109+
110+
static void Process_Exited(object? sender, EventArgs e)
111+
{
112+
//Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
113+
}
114+
115+
static void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
116+
{
117+
if ((e.Data?.Length ?? 0) > 0)
118+
Console.WriteLine(e.Data);
119+
}
120+
121+
static void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
122+
{
123+
if ((e.Data?.Length ?? 0) > 0)
124+
Console.WriteLine(e.Data);
81125
}
82126
}

0 commit comments

Comments
 (0)