feature: add apple silicon native macOS support (#81)

* feature: add apple silicon native macOS support - #81

* (macos): Fix crash

This fixes a crash when viewing the rear camera

* fix(macos): keep interpolated presentation on main thread

* fix(macos): supply Retro-WFC payload during setup

* perf(windows): compile out flat-memory fallback check

* remove duplicate smoke test

* test(macos): name and focus host platform tests

* fix(macos): validate Retro-WFC payload cache

* fix(payload): preserve staged file access failures

* Limit flat-page checks to variable-page hosts

---------

Co-authored-by: patchzyy <64382339+patchzyy@users.noreply.github.com>
This commit is contained in:
Michael Gandpatchzyy authored and GitHub committed 2026-09-01 18:57:15 +02:00
1 parent ae3096c89b
commit 5c76e2b0df
36 files changed
+1742 -251

No files matched your search

+34 -2
View File
@@ -166,6 +166,7 @@ return command switch
"emit-build-shards" => RunEmitBuildShards(tail),
"emit-base-manifest" => RunEmitBaseManifest(tail),
"check-base-mod-awareness" => RunCheckBaseModAwareness(tail),
"validate-retro-wfc-payload" => RunValidateRetroWfcPayload(tail),
_ => ShowHelp(command)
};
@@ -354,6 +355,33 @@ int RunInfo()
return 0;
}
int RunValidateRetroWfcPayload(string[] argsTail)
{
var directory = OptionValue(argsTail, "--directory");
if (string.IsNullOrWhiteSpace(directory))
{
Console.Error.WriteLine("--directory is required.");
return 1;
}
try
{
WiiCompiled.Setup.Common.RetroWfcPayload.ValidateStagedRetroWfcPayloadDirectory(directory);
Console.WriteLine("[translator] Retro WFC payload signature validated.");
return 0;
}
catch (InvalidDataException ex)
{
Console.Error.WriteLine($"[translator] Retro WFC payload validation failed: {ex.Message}");
return 2;
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
Console.Error.WriteLine($"[translator] Could not read Retro WFC payload: {ex.Message}");
return 1;
}
}
int RunTranslateRecursive(string[] argsTail)
{
if (argsTail.Length == 0 || argsTail[0].StartsWith("--", StringComparison.Ordinal))
@@ -3639,7 +3667,8 @@ static string[] KnownCommands() => new[]
"translate-mod",
"emit-base-manifest",
"emit-build-shards",
"check-base-mod-awareness"
"check-base-mod-awareness",
"validate-retro-wfc-payload"
};
/// <summary>
@@ -3682,6 +3711,10 @@ static (string? Positional, CommandOption[] Options)? CommandSpec(string command
new("--translation-output-metadata", "path"),
new("--code-pul", "path")
}),
"validate-retro-wfc-payload" => (null, new CommandOption[]
{
new("--directory", "directory", Required: true)
}),
"emit-base-manifest" => (null, new CommandOption[]
{
new("--out", "path"),
@@ -4061,4 +4094,3 @@ sealed record ResolvedDispatchEntry(
bool MustRemainDynamicallyDispatchable,
string SourceFile);
@@ -15,6 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\Translator.Core\Translator.Core.csproj" />
<ProjectReference Include="..\..\..\Launcher\WiiCompiled.Setup.Common\WiiCompiled.Setup.Common.csproj" />
</ItemGroup>
<ItemGroup>
@@ -22,14 +22,15 @@ internal static class AssemblyBlobWriter
var expectedFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var assembly = new StringBuilder();
foreach (var header in headerLines) assembly.AppendLine(header);
// PE/COFF (Windows) and ELF (Linux) spell a read-only data section differently in GNU-as
// syntax - COFF section flags ("dr" = data, read-only) versus an ELF section needing an
// allocatable-only flag plus an explicit @progbits type. The build always targets
// PE/COFF (Windows), Mach-O (macOS), and ELF (Linux) spell a read-only data section
// differently in GNU-as syntax. The build always targets
// whichever platform the translator itself runs on (there is no cross-compilation
// support), so that's what this picks the section syntax from.
assembly.AppendLine(OperatingSystem.IsWindows()
? ".section .rdata,\"dr\""
: ".section .rodata,\"a\",@progbits");
: OperatingSystem.IsMacOS()
? ".section __TEXT,__const"
: ".section .rodata,\"a\",@progbits");
assembly.AppendLine();
foreach (var blob in blobs)
@@ -40,8 +41,12 @@ internal static class AssemblyBlobWriter
var hash = ChecksumUtilities.Sha256Hex(blob.Data.Span);
assembly.AppendLine($"// {blob.Comment}; sha256={hash}");
assembly.AppendLine(".p2align 4");
assembly.AppendLine($".globl {blob.Symbol}");
assembly.AppendLine($"{blob.Symbol}:");
// C/C++ external symbols carry a leading underscore in Mach-O,
// unlike ELF and COFF. The generated C++ still names the symbol
// without that ABI decoration, so emit the platform spelling here.
var assemblySymbol = OperatingSystem.IsMacOS() ? $"_{blob.Symbol}" : blob.Symbol;
assembly.AppendLine($".globl {assemblySymbol}");
assembly.AppendLine($"{assemblySymbol}:");
var referencePath = Path.Combine(blobReferenceDirectory, blob.FileName);
assembly.AppendLine($".incbin \"{SanitizeAssemblyPath(referencePath)}\"");
assembly.AppendLine();
@@ -51,7 +56,7 @@ internal static class AssemblyBlobWriter
{
if (!expectedFiles.Contains(Path.GetFullPath(stalePath))) File.Delete(stalePath);
}
if (!OperatingSystem.IsWindows())
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{
// Absence of a .note.GNU-stack section makes the linker assume the oldest, most
// conservative default for this object (an executable stack) and warn about it; this