mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-10-02 16:10:26 -04:00
Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42d43ed407 | |||
| 4b115d73af | |||
| 75886669bc | |||
| a50bad2970 | |||
| 9b7b9913e4 | |||
| a88b7b502b | |||
| d0d58072d1 | |||
| 6b853ca371 | |||
| 77a8623416 | |||
| 10ab54adee | |||
| a05c89739d | |||
| 82991ec337 | |||
| e164af9ff4 | |||
| e409d9f99b | |||
| 85f250155f | |||
| a9c9c0de26 | |||
| c92e45c2e7 | |||
| 583e702547 | |||
| b59e035b87 | |||
| 6f14bde26a | |||
| 83463764b8 | |||
| 8008d885ad | |||
| 7e6604c415 | |||
| 6fb593749e | |||
| 8ec3a1b752 | |||
| 8705e957c7 | |||
| 8e0cc96898 | |||
| 6458ec6abe | |||
| 209405dfb7 | |||
| 4bdaff01fc | |||
| b555ede2d3 | |||
| 53d8f71c68 | |||
| 149cfef608 | |||
| 25c69ae28e | |||
| 0bb15f0a44 | |||
| 466d06d7db | |||
| 8769cf6dea | |||
| 452b478bb3 | |||
| 407f8a7190 | |||
| c2289e4ba4 | |||
| a135beb201 | |||
| 88b990b060 | |||
| e0e362bd99 | |||
| 5654d8f21b | |||
| 730e3122d5 | |||
| f424536d3b | |||
| 2d9dc4e0f2 | |||
| 8e57cc162f | |||
| 1c0a3edee9 | |||
| d1d80613cc | |||
| 5d67b229f6 | |||
| 56db6ba641 | |||
| a67069afd3 | |||
| 009697fb97 | |||
| 3f7fed48c9 | |||
| 6eba523d70 | |||
| 8c6c177857 | |||
| be153e0fa0 | |||
| e34f055b3a | |||
| 602348f905 | |||
| e6f9b2197e | |||
| 65047bc7b7 | |||
| 989d5e00da | |||
| efc44b0482 | |||
| d3d0de62a6 | |||
| c6ef17378e | |||
| 38a11b7b2c | |||
| 7a13696a8b | |||
| 2bcfdca199 | |||
| f2165a5aa6 | |||
| ffc7244277 | |||
| dec9ed8df1 | |||
| 8dc9bb67b3 | |||
| ca7d126a13 | |||
| 5c76e2b0df | |||
| ae3096c89b | |||
| 6f4dd2f470 | |||
| 2b5b889249 | |||
| fbfb741b49 | |||
| e630132dd3 | |||
| a6f3720598 | |||
| abe7cd2b61 | |||
| 7aa04bfe80 | |||
| 1af7cd6d9b | |||
| d31942c356 | |||
| 13b6d0b447 | |||
| db576cd5cb | |||
| edacfcb8bc | |||
| 36faa76dc0 | |||
| 3fc1555871 | |||
| be691bd08d | |||
| 243eb86021 | |||
| 7b750e96ac | |||
| e4e388295b | |||
| 2c38db4174 | |||
| 1c7e4e79c5 | |||
| 6ddc153e44 | |||
| cb812c1fd0 |
@@ -3,3 +3,4 @@
|
||||
|
||||
# Patch files must stay LF: git apply matches context bytes against LF upstream sources
|
||||
*.patch -text
|
||||
translator/tests/Translator.Tests/TestAssets/**/*.bin binary
|
||||
|
||||
@@ -14,18 +14,30 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
recompilation:
|
||||
name: Recompilation test
|
||||
uses: ./.github/workflows/recomp-test.yml
|
||||
|
||||
translator:
|
||||
name: Translator (build + test)
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-dotnet@v4
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('translator/Translator.sln', '**/*.csproj', '**/*.props', '**/*.targets', '**/packages.lock.json', 'global.json', 'NuGet.config', 'nuget.config') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nuget-
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore translator/Translator.sln
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
name: Package installers
|
||||
|
||||
# Builds the per-platform installer/setup tool (WiiCompiled-Setup.exe /
|
||||
# WiiCompiled-Setup-x86_64.AppImage) via Launcher/Build-Installer.ps1 and
|
||||
# Launcher/build-appimage.sh respectively - the same scripts a maintainer runs by hand today to
|
||||
# produce a GitHub Release asset. This does NOT build the actual translated game executable:
|
||||
# that step requires the end user's own Mario Kart Wii dump (Assets/main.dol, Assets/StaticR.rel),
|
||||
# which is proprietary and not present in this repository or in CI.
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: package-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
recompilation:
|
||||
name: Recompilation test
|
||||
uses: ./.github/workflows/recomp-test.yml
|
||||
|
||||
linux-appimage:
|
||||
name: Linux (AppImage, ${{ matrix.arch }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: ubuntu-22.04
|
||||
arch: x86_64
|
||||
- runner: ubuntu-22.04-arm
|
||||
arch: aarch64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
# appimagetool ships as an AppImage itself and needs to self-mount via FUSE to run directly;
|
||||
# GitHub's ubuntu-latest runners don't have libfuse2 preinstalled.
|
||||
- name: Install dependencies (required by appimagetool and SDL3 build)
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libfuse2 build-essential git make \
|
||||
pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
|
||||
libaudio-dev libfribidi-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
|
||||
libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \
|
||||
libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
|
||||
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev libthai-dev libusb-1.0-0-dev \
|
||||
libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev
|
||||
|
||||
- name: Build AppImage
|
||||
run: bash Launcher/build-appimage.sh
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: WiiCompiled-Setup-linux-${{ matrix.arch }}
|
||||
path: Launcher/dist/WiiCompiled-Setup-${{ matrix.arch }}.AppImage
|
||||
if-no-files-found: error
|
||||
archive: false
|
||||
|
||||
windows-installer:
|
||||
name: Windows (installer exe)
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Build installer
|
||||
shell: pwsh
|
||||
run: ./Launcher/Build-Installer.ps1
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: WiiCompiled-Setup-windows-x64
|
||||
path: Launcher/dist/WiiCompiled-Setup.exe
|
||||
if-no-files-found: error
|
||||
archive: false
|
||||
|
||||
# Publishes the packaged installers as a GitHub Release whenever a v* tag is pushed. Wheel Wizard
|
||||
# discovers updates from these releases, so the contract it relies on is enforced here: a full
|
||||
# (non-prerelease) release whose tag is v<semver>, carrying an asset named exactly
|
||||
# WiiCompiled-Setup.exe, produced by a setup host that reports that same version.
|
||||
release:
|
||||
name: Publish GitHub Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [linux-appimage, windows-installer, recompilation]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
# Wheel Wizard runs the downloaded setup with --version and refuses it when the reported
|
||||
# version differs from the release tag, so a tag that was pushed without bumping the pinned
|
||||
# version would ship an update nobody can install. Catch that before anything is published.
|
||||
- name: Verify the tag matches the pinned setup version
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="${TAG#v}"
|
||||
status=0
|
||||
check() {
|
||||
if ! grep -Fq "$2" "$1"; then
|
||||
echo "::error file=$1::expected '$2' for tag $TAG"
|
||||
status=1
|
||||
fi
|
||||
}
|
||||
check Launcher/Directory.Build.props "<Version>$version</Version>"
|
||||
exit $status
|
||||
|
||||
# The build jobs upload with `archive: false`, which stores each installer as a raw file
|
||||
# rather than a zip (and names the artifact after the file). Only download-artifact v8 and
|
||||
# later understand such direct uploads; v7 tries to unzip everything and fails on them.
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Publish release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ls -lR artifacts
|
||||
assets=()
|
||||
for name in WiiCompiled-Setup.exe WiiCompiled-Setup-x86_64.AppImage WiiCompiled-Setup-aarch64.AppImage; do
|
||||
found="$(find artifacts -type f -name "$name" | head -n 1)"
|
||||
[ -n "$found" ] && [ -s "$found" ] || { echo "::error::missing release asset $name"; exit 1; }
|
||||
assets+=("$found")
|
||||
done
|
||||
# A re-run of a tag whose release already exists only refreshes the assets.
|
||||
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
||||
gh release upload "$TAG" "${assets[@]}" --repo "$GITHUB_REPOSITORY" --clobber
|
||||
else
|
||||
gh release create "$TAG" "${assets[@]}" \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--title "$TAG" \
|
||||
--verify-tag \
|
||||
--generate-notes
|
||||
fi
|
||||
@@ -0,0 +1,62 @@
|
||||
name: Synthetic recompilation
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
name: Windows runtime (synthetic DOL)
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
# Cache downloads only. Preparation still validates pins, and every run
|
||||
# compiles current Aurora, runtime, and generated sources from scratch.
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: Launcher/artifacts/downloads
|
||||
key: windows-recomp-downloads-${{ hashFiles('Launcher/Prepare-PortableTools.ps1', 'Launcher/Prepare-Dependencies.ps1') }}
|
||||
|
||||
# Install sccache.
|
||||
- name: Run sccache-action
|
||||
uses: mozilla/sccache-action@v0.0.11
|
||||
|
||||
# Tell CMake to use sccache and use GitHub's API.
|
||||
- name: Configure sccache environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
"SCCACHE_GHA_ENABLED=true" | Add-Content -Path $env:GITHUB_ENV
|
||||
"ACTIONS_CACHE_SERVICE_V2=on" | Add-Content -Path $env:GITHUB_ENV
|
||||
"CMAKE_C_COMPILER_LAUNCHER=$env:SCCACHE_PATH" | Add-Content -Path $env:GITHUB_ENV
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER=$env:SCCACHE_PATH" | Add-Content -Path $env:GITHUB_ENV
|
||||
|
||||
- name: Prepare the shipped Windows toolchain
|
||||
shell: pwsh
|
||||
run: ./Launcher/Prepare-PortableTools.ps1
|
||||
|
||||
- name: Prepare pinned native dependencies
|
||||
shell: pwsh
|
||||
run: ./Launcher/Prepare-Dependencies.ps1
|
||||
|
||||
# Expose cache token context to the build script.
|
||||
- name: Translate, compile the full runtime, and link
|
||||
shell: pwsh
|
||||
run: ./Launcher/Test-Recompilation.ps1 -Parallel 4
|
||||
|
||||
# Print cache results (even if the build fails)
|
||||
- name: Show sccache stats
|
||||
if: always()
|
||||
shell: pwsh
|
||||
run: sccache --show-stats
|
||||
@@ -25,6 +25,9 @@ Code.pul
|
||||
# Build output
|
||||
/build/
|
||||
/build-*/
|
||||
/native-build/
|
||||
/native-build-macos/
|
||||
/local-products/
|
||||
/dist/
|
||||
/out/
|
||||
[Bb]in/
|
||||
@@ -69,3 +72,5 @@ project.lock.json
|
||||
*.log
|
||||
output.txt
|
||||
|
||||
# Operating System
|
||||
.DS_Store
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "aurora-main"]
|
||||
path = aurora-main
|
||||
url = https://github.com/patchzyy/aurora.git
|
||||
@@ -73,7 +73,16 @@ function Resolve-VcRuntimeDirectory([string]$RequestedPath) {
|
||||
function Copy-Directory([string]$Source, [string]$Destination) {
|
||||
Assert-Directory $Source "Source directory"
|
||||
[IO.Directory]::CreateDirectory($Destination) | Out-Null
|
||||
Copy-Item -Path (Join-Path $Source '*') -Destination $Destination -Recurse -Force
|
||||
# Source payloads are materialized trees, independent of Git checkout metadata.
|
||||
foreach ($entry in Get-ChildItem -LiteralPath $Source -Force) {
|
||||
if ($entry.Name -eq '.git') { continue }
|
||||
$target = Join-Path $Destination $entry.Name
|
||||
if ($entry.PSIsContainer) {
|
||||
Copy-Directory $entry.FullName $target
|
||||
} else {
|
||||
Copy-Item -LiteralPath $entry.FullName -Destination $target -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
function Compress-Zip([string]$Source, [string]$Destination, [string[]]$Entries) {
|
||||
$tar = Join-Path $env:SystemRoot 'System32\tar.exe'
|
||||
@@ -88,17 +97,23 @@ Assert-File $setupProject '.NET setup project'
|
||||
Assert-File $translatorProject 'Translator CLI project'
|
||||
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $portableTools 'llvm-mingw\bin\x86_64-w64-mingw32-clang++.exe'))) {
|
||||
# A PowerShell script, not a native executable - it never touches $LASTEXITCODE, and its own
|
||||
# $ErrorActionPreference = 'Stop' + throw already aborts this run on failure.
|
||||
& (Join-Path $PSScriptRoot 'Prepare-PortableTools.ps1') -Destination $portableTools
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Portable tool preparation failed.' }
|
||||
}
|
||||
Assert-File (Join-Path $portableTools 'CMake\bin\cmake.exe') 'Portable CMake'
|
||||
Assert-File (Join-Path $portableTools 'Ninja\ninja.exe') 'Portable Ninja'
|
||||
Assert-Directory $dependencySources 'Pinned offline dependency sources'
|
||||
# native_prebuilt carries the aurora/third-party archives the user no longer has
|
||||
# to compile (launcher/Prepare-NativePrebuilt.ps1).
|
||||
# Kept in step with InstalledLayout.DependencyNames by Test-PinnedFacts.ps1: the installed host
|
||||
# refuses to call a toolkit complete unless every one of these directories is present.
|
||||
$requiredDependencies = @('abseil-cpp','cppwinrt','dawn_prebuilt','fmt','freetype','imgui','libusb','native_prebuilt','png','SDL','sqlite3','tracy','xxhash','zlib','zstd')
|
||||
$missingSources = @($requiredDependencies | Where-Object { $_ -ne 'native_prebuilt' } |
|
||||
Where-Object { -not (Test-Path -LiteralPath (Join-Path $dependencySources $_) -PathType Container) })
|
||||
if ($missingSources.Count -gt 0) {
|
||||
& (Join-Path $PSScriptRoot 'Prepare-Dependencies.ps1') -Destination $dependencySources
|
||||
}
|
||||
Assert-Directory $dependencySources 'Pinned offline dependency sources'
|
||||
|
||||
# The precompiled archives are only interchangeable with what the user's machine
|
||||
# compiles if both came from this toolchain and this flag set, so a stale package
|
||||
@@ -165,8 +180,7 @@ Assert-File $translator 'Self-contained translator'
|
||||
|
||||
# Resolved via the shared WiiCompiled.Setup.Common.Cli helper (also used by build-appimage.sh on
|
||||
# Linux) rather than a separate download/version-pin copy here: it downloads and caches the same way
|
||||
# NodToolProvider.cs always does (Launcher/artifacts/nodtool.exe), replacing the old manual
|
||||
# -DolphinToolPath handoff with an automated, pinned acquisition step.
|
||||
# NodToolProvider.cs always does (Launcher/artifacts/nodtool.exe)
|
||||
$nodToolCliProject = Join-Path $PSScriptRoot 'WiiCompiled.Setup.Common.Cli'
|
||||
$nodTool = (& dotnet run --project $nodToolCliProject -c Release -- --workspace $repoRoot | Select-Object -Last 1)
|
||||
if ($LASTEXITCODE -ne 0) { throw "nodtool resolution failed with exit code $LASTEXITCODE." }
|
||||
@@ -274,9 +288,12 @@ foreach ($required in @('ToolkitFingerprint','TranslationFingerprint','NativeToo
|
||||
if ([string]::IsNullOrWhiteSpace($identities.$required)) { throw "Payload identity output is missing $required." }
|
||||
}
|
||||
|
||||
$productVersion = ((& $setupHost --version) -join '').Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($productVersion)) { throw 'The setup host did not report its version.' }
|
||||
|
||||
$manifest = [ordered]@{
|
||||
SchemaVersion = 2
|
||||
ProductVersion = '0.2.25'
|
||||
ProductVersion = $productVersion
|
||||
ExpectedGameId = $pins.GameId
|
||||
ExpectedDolSha256 = $pins.DolSha256
|
||||
ExpectedRelSha256 = $pins.RelSha256
|
||||
@@ -292,11 +309,12 @@ $manifest = [ordered]@{
|
||||
$manifest | ConvertTo-Json | Set-Content (Join-Path $payloadRoot 'payload-manifest.json') -Encoding UTF8
|
||||
|
||||
Write-Host '[4/6] Enforcing the copyright and generated-code boundary...'
|
||||
# Both audits are PowerShell scripts that throw directly on failure (Test-PayloadBoundary.ps1
|
||||
# never invokes a native command at all, so it never touches $LASTEXITCODE); there is no exit
|
||||
# code to check here, and doing so risks reading a stale value from an unrelated earlier command.
|
||||
& (Join-Path $PSScriptRoot 'Test-PayloadBoundary.ps1') -PayloadRoot $payloadRoot
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Payload boundary audit failed.' }
|
||||
& (Join-Path $PSScriptRoot 'Test-NativeDependencies.ps1') -PayloadRoot $payloadRoot -SetupHost $setupHost `
|
||||
-LlvmReadobjPath (Join-Path $portableTools 'llvm-mingw\bin\llvm-readobj.exe')
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Native dependency audit failed.' }
|
||||
|
||||
Write-Host '[5/6] Creating the canonical installer payload...'
|
||||
$payloadZip = Join-Path $workRoot 'payload.zip'
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- The one product version. Release tags must match it. -->
|
||||
<Version>0.2.33</Version>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
+10
-2
@@ -103,7 +103,7 @@ function Write-MkwBuildStep([string]$StepId, [string]$Message) {
|
||||
function Reset-LocalDirectory([string]$Path) {
|
||||
$full = [IO.Path]::GetFullPath($Path)
|
||||
$root = [IO.Path]::GetFullPath($Workspace).TrimEnd('\') + '\'
|
||||
$installRoot = [IO.Path]::GetFullPath((Split-Path -Parent $Workspace)).TrimEnd('\') + '\'
|
||||
$installRoot = [IO.Path]::GetFullPath((Split-Path -Parent $realWorkspace)).TrimEnd('\') + '\'
|
||||
# The caller-supplied output destinations are legitimate reset targets by
|
||||
# definition, wherever the caller placed them: a fresh install's operation
|
||||
# scratch lives beside the installation directory rather than inside it.
|
||||
@@ -150,8 +150,16 @@ if ($Profile -eq 'both' -and [string]::IsNullOrWhiteSpace($BaseOutputDirectory))
|
||||
if ($Profile -ne 'both' -and -not [string]::IsNullOrWhiteSpace($BaseOutputDirectory)) {
|
||||
throw '-BaseOutputDirectory is valid only with -Profile both.'
|
||||
}
|
||||
$realWorkspace = $Workspace.TrimEnd('\')
|
||||
$Workspace = Get-MkwBuildSafePath $realWorkspace 'workspace' 'runtime\CMakeLists.txt'
|
||||
# A selected package inside the install may also name the same Code.pul through the real path.
|
||||
# Give it the workspace spelling before comparing it with the staged copy.
|
||||
if (-not [string]::IsNullOrWhiteSpace($RetroRewindPackageDirectory) -and
|
||||
$RetroRewindPackageDirectory.StartsWith($realWorkspace + '\', [StringComparison]::OrdinalIgnoreCase)) {
|
||||
$RetroRewindPackageDirectory = $Workspace + $RetroRewindPackageDirectory.Substring($realWorkspace.Length)
|
||||
}
|
||||
$translator = Join-Path $Toolkit 'Translator\Translator.Cli.exe'
|
||||
$toolchain = Get-MkwShellSafeToolchainRoot $Toolkit
|
||||
$toolchain = Get-MkwBuildSafePath $Toolkit 'toolchain' 'CMake\bin\cmake.exe'
|
||||
$cmake = Join-Path $toolchain 'CMake\bin\cmake.exe'
|
||||
$ninja = Join-Path $toolchain 'Ninja\ninja.exe'
|
||||
$toolchainBin = Join-Path $toolchain 'llvm-mingw\bin'
|
||||
|
||||
@@ -40,41 +40,55 @@ function Get-MkwToolchainPath([string]$ToolchainRoot) {
|
||||
) -join ';')
|
||||
}
|
||||
|
||||
function Get-MkwShellSafeToolchainRoot([string]$ToolchainRoot) {
|
||||
if ([string]::IsNullOrWhiteSpace($ToolchainRoot)) { throw 'A toolchain root is required.' }
|
||||
$full = [IO.Path]::GetFullPath($ToolchainRoot)
|
||||
function Get-MkwBuildSafePath([string]$Path, [string]$Kind, [string]$MarkerFile) {
|
||||
<#
|
||||
The Windows native build passes workspace paths through CMake, Ninja response files and
|
||||
clang, which do not all interpret quotes the same way. Keep those paths plain even when the
|
||||
user's install directory contains an apostrophe, ampersand or other punctuation.
|
||||
#>
|
||||
if ([string]::IsNullOrWhiteSpace($Path)) { throw "A $Kind path is required." }
|
||||
$full = [IO.Path]::GetFullPath($Path)
|
||||
# A drive root keeps its separator: "C:" is relative to the current directory on that drive.
|
||||
if ($full -ne [IO.Path]::GetPathRoot($full)) { $full = $full.TrimEnd('\') }
|
||||
if ($full -notmatch '[()&^%!]') { return $full }
|
||||
if ($full -cmatch '^[A-Za-z0-9 ._\\:-]+$') { return $full }
|
||||
|
||||
Assert-File (Join-Path $full $MarkerFile) "$Kind marker"
|
||||
|
||||
$sha = [Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
$bytes = $sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($full.ToLowerInvariant()))
|
||||
} finally { $sha.Dispose() }
|
||||
$linkName = 'toolchain-' + ((($bytes[0..7]) | ForEach-Object { $_.ToString('x2') }) -join '')
|
||||
$linkName = "$Kind-" + ((($bytes[0..7]) | ForEach-Object { $_.ToString('x2') }) -join '')
|
||||
|
||||
$failures = @()
|
||||
foreach ($base in @($env:ProgramData, $env:PUBLIC)) {
|
||||
if ([string]::IsNullOrWhiteSpace($base) -or $base -match '[()&^%! ]') { continue }
|
||||
if ([string]::IsNullOrWhiteSpace($base) -or $base -cnotmatch '^[A-Za-z0-9._\\:-]+$') { continue }
|
||||
$link = Join-Path (Join-Path $base 'WiiCompiled') $linkName
|
||||
try {
|
||||
[IO.Directory]::CreateDirectory((Split-Path -Parent $link)) | Out-Null
|
||||
# The name already identifies the target, so an existing junction that still resolves is
|
||||
# this one; only a broken leftover is replaced. Directory.Delete removes the reparse
|
||||
# point itself, where Remove-Item -Recurse would delete the toolchain it points at.
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $link 'CMake\bin\cmake.exe') -PathType Leaf)) {
|
||||
if (Test-Path -LiteralPath $link) { [IO.Directory]::Delete($link) }
|
||||
$existing = Get-Item -LiteralPath $link -Force -ErrorAction SilentlyContinue
|
||||
if ($null -ne $existing) {
|
||||
# Never trust a directory just because it has the marker: it could point at a
|
||||
# different installation. Nor may we remove a directory we did not create.
|
||||
if ($existing.LinkType -ne 'Junction' -or
|
||||
@($existing.Target).Count -ne 1 -or
|
||||
-not [string]::Equals([IO.Path]::GetFullPath(@($existing.Target)[0]),
|
||||
$full, [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "An existing path is not the expected junction: $link"
|
||||
}
|
||||
} else {
|
||||
New-Item -ItemType Junction -Path $link -Target $full -ErrorAction Stop | Out-Null
|
||||
}
|
||||
Write-Host "MKWCBUILD: Building through $link, because $full contains characters cmd.exe cannot parse"
|
||||
Assert-File (Join-Path $link $MarkerFile) "$Kind junction marker"
|
||||
Write-Host "MKWCBUILD: Building the $Kind through $link, because $full contains characters the native build cannot quote reliably"
|
||||
return $link
|
||||
} catch {
|
||||
$failures += "$link ($($_.Exception.Message))"
|
||||
}
|
||||
}
|
||||
throw ("The toolchain path $full contains a character (one of ( ) & ^ % !) that the compiler " +
|
||||
'cannot be invoked through, and no junction to it could be created: ' + ($failures -join '; ') +
|
||||
'. Install to a path without those characters.')
|
||||
throw ("The $Kind path $full cannot be passed safely to the native build, and no junction " +
|
||||
'to it could be created: ' + ($failures -join '; ') + '. Install to a path of plain ' +
|
||||
'letters, digits and spaces, or make a safe junction location available.')
|
||||
}
|
||||
|
||||
function Get-MkwProjectPins([string]$ProjectFile) {
|
||||
@@ -117,12 +131,13 @@ function Get-MkwProjectPins([string]$ProjectFile) {
|
||||
}
|
||||
|
||||
function Invoke-Checked([string]$FilePath, [string[]]$Arguments, [string]$Description,
|
||||
[string]$LogPrefix = 'MKWCBUILD', [string]$StepId = '') {
|
||||
[string]$LogPrefix = 'MKWCBUILD', [string]$StepId = '', [bool]$WaitForProcessTree = $true) {
|
||||
<#
|
||||
Runs a build tool and turns a non-zero exit code into a described failure. Start-Process -Wait
|
||||
is deliberate: it waits for the whole process tree, since a .NET single-file bundle host may
|
||||
hand off to an extracted child that PowerShell's call operator would not wait for. Start-Process
|
||||
doesn't publish $LASTEXITCODE, so this sets it manually for callers that check it.
|
||||
Runs a build tool and turns a non-zero exit code into a described failure. By default,
|
||||
Start-Process -Wait waits for the whole process tree, since a .NET single-file bundle host may
|
||||
hand off to an extracted child that PowerShell's call operator would not wait for. Callers that
|
||||
need to avoid waiting on unrelated descendants can opt into the call-operator path.
|
||||
Start-Process doesn't publish $LASTEXITCODE, so this sets it manually for callers that check it.
|
||||
-StepId emits the machine-readable form the installer's progress bar consumes (BuildStepIds in
|
||||
WiiCompiled.Setup/InstallProgress.cs); the human sentence stays on the same log line.
|
||||
#>
|
||||
@@ -132,9 +147,14 @@ function Invoke-Checked([string]$FilePath, [string[]]$Arguments, [string]$Descri
|
||||
if ($_.Contains('"')) { throw "A native build argument contains an unsupported quote: $_" }
|
||||
'"' + $_ + '"'
|
||||
})
|
||||
$process = Start-Process -FilePath $FilePath -ArgumentList $quotedArguments `
|
||||
-NoNewWindow -Wait -PassThru
|
||||
$exitCode = $process.ExitCode
|
||||
if ($WaitForProcessTree) {
|
||||
$process = Start-Process -FilePath $FilePath -ArgumentList $quotedArguments `
|
||||
-NoNewWindow -Wait -PassThru
|
||||
$exitCode = $process.ExitCode
|
||||
} else {
|
||||
& $FilePath @Arguments
|
||||
$exitCode = $LASTEXITCODE
|
||||
}
|
||||
$global:LASTEXITCODE = $exitCode
|
||||
if ($exitCode -ne 0) { throw "$Description failed with exit code $exitCode." }
|
||||
}
|
||||
@@ -224,13 +244,14 @@ function Get-MkwAuroraSourceFingerprint([string]$AuroraDirectory) {
|
||||
(Join-Path $root 'extern') + '\',
|
||||
(Join-Path $root 'build') + '\'
|
||||
)
|
||||
# Hidden files are skipped deliberately: Build-Installer.ps1 stages this tree
|
||||
# with Copy-Item -Recurse (no -Force), so they never reach the payload and
|
||||
# hashing them would make the two sides disagree by construction.
|
||||
# Git metadata identifies a checkout location, not a source revision's bytes.
|
||||
# Exclude it explicitly, including a submodule's non-hidden .git file.
|
||||
$files = Get-ChildItem -LiteralPath $root -Recurse -File |
|
||||
Where-Object {
|
||||
$full = $_.FullName
|
||||
-not ($excludedPrefixes | Where-Object { $full.StartsWith($_, [StringComparison]::OrdinalIgnoreCase) })
|
||||
$relative = $full.Substring($root.Length + 1).Replace('\', '/')
|
||||
($relative -notmatch '(^|/)\.git(/|$)') -and
|
||||
-not ($excludedPrefixes | Where-Object { $full.StartsWith($_, [StringComparison]::OrdinalIgnoreCase) })
|
||||
} |
|
||||
Sort-Object { $_.FullName.Substring($root.Length + 1).Replace('\', '/') }
|
||||
$sha = [Security.Cryptography.SHA256]::Create()
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
# Populates Launcher/artifacts/dependencies: the pinned, unpatched upstream source trees (plus the
|
||||
# prebuilt Dawn package and generated C++/WinRT headers) that Build-Installer.ps1 ships inside the
|
||||
# installer so the user's build runs with FETCHCONTENT_FULLY_DISCONNECTED=ON. Every pin is the one
|
||||
# aurora-main's own CMake declares; the Pin fields below are asserted against those files so the
|
||||
# two cannot drift apart silently. native_prebuilt is not fetched here - Prepare-NativePrebuilt.ps1
|
||||
# compiles it from these trees.
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Destination,
|
||||
# Windows metadata source for cppwinrt.exe: 'local' (this machine's WinMetadata), 'sdk', or an
|
||||
# installed SDK version such as 10.0.26100.0.
|
||||
[string]$CppWinRtInput = 'local'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 3.0
|
||||
|
||||
$repoRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
|
||||
$auroraCMake = Join-Path $repoRoot 'aurora-main\CMakeLists.txt'
|
||||
$auroraExtern = Join-Path $repoRoot 'aurora-main\extern\CMakeLists.txt'
|
||||
$auroraDawn = Join-Path $repoRoot 'aurora-main\cmake\AuroraDawnProvider.cmake'
|
||||
$auroraLibUsb = Join-Path $repoRoot 'aurora-main\cmake\AuroraLibUSB.cmake'
|
||||
$auroraSdl = Join-Path $repoRoot 'aurora-main\cmake\AuroraSDL3Provider.cmake'
|
||||
if (-not (Test-Path -LiteralPath $auroraCMake -PathType Leaf)) {
|
||||
throw 'Aurora sources are missing. Run git submodule update --init --recursive from the repository root first.'
|
||||
}
|
||||
|
||||
# Name = directory under the destination; FetchContent maps it back through
|
||||
# FETCHCONTENT_SOURCE_DIR_<UPPERCASE NAME> (NativeBuildFlags.ps1), so the names are the declared
|
||||
# FetchContent names, not the upstream project names.
|
||||
$packages = @(
|
||||
[pscustomobject]@{
|
||||
Name = 'SDL'; File = 'SDL3-3.4.4.tar.gz'
|
||||
Uris = @('https://github.com/libsdl-org/SDL/releases/download/release-3.4.4/SDL3-3.4.4.tar.gz')
|
||||
Pins = @(@{ File = $auroraCMake; Text = 'set(AURORA_SDL3_VERSION "3.4.4"' },
|
||||
@{ File = $auroraSdl; Text = 'releases/download/release-${AURORA_SDL3_VERSION}/SDL3-${AURORA_SDL3_VERSION}.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'abseil-cpp'; File = 'abseil-cpp-20240722.0.tar.gz'
|
||||
Uris = @('https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'dawn_prebuilt'; File = 'dawn-v20260603.191052-windows-amd64.tar.gz'
|
||||
Uris = @('https://github.com/theofficialgman/dawn-build/releases/download/v20260603.191052/dawn-windows-amd64.tar.gz')
|
||||
Pins = @(@{ File = $auroraCMake; Text = 'set(AURORA_DAWN_VERSION "v20260603.191052"' },
|
||||
@{ File = $auroraDawn; Text = 'SHA256=13be9cff8b9b179c42dcd16aeabb6effcc8f0dfdcc14463eda2a5caeda225142' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'fmt'; File = 'fmt-11.1.4.tar.gz'
|
||||
Uris = @('https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'freetype'; File = 'freetype-2.14.3.tar.gz'
|
||||
Uris = @('https://files.twilitrealm.dev/freetype-2.14.3.tar.gz',
|
||||
'https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.gz',
|
||||
'https://downloads.sourceforge.net/project/freetype/freetype2/2.14.3/freetype-2.14.3.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://files.twilitrealm.dev/freetype-2.14.3.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'imgui'; File = 'imgui-1.91.9b-docking.tar.gz'
|
||||
Uris = @('https://github.com/ocornut/imgui/archive/refs/tags/v1.91.9b-docking.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/ocornut/imgui/archive/refs/tags/v1.91.9b-docking.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'libusb'; File = 'libusb-1.0.30.tar.bz2'
|
||||
Uris = @('https://github.com/libusb/libusb/releases/download/v1.0.30/libusb-1.0.30.tar.bz2')
|
||||
Pins = @(@{ File = $auroraCMake; Text = 'set(AURORA_LIBUSB_VERSION "1.0.30"' },
|
||||
@{ File = $auroraLibUsb; Text = 'releases/download/v${AURORA_LIBUSB_VERSION}/libusb-${AURORA_LIBUSB_VERSION}.tar.bz2' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'png'; File = 'libpng-1.6.58.tar.gz'
|
||||
Uris = @('https://github.com/pnggroup/libpng/archive/refs/tags/v1.6.58.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/pnggroup/libpng/archive/refs/tags/v1.6.58.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'sqlite3'; File = 'sqlite-amalgamation-3510300.zip'
|
||||
Uris = @('https://sqlite.org/2026/sqlite-amalgamation-3510300.zip')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://sqlite.org/2026/sqlite-amalgamation-3510300.zip' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'tracy'; File = 'tracy-a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz'
|
||||
Uris = @('https://github.com/wolfpld/tracy/archive/a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/wolfpld/tracy/archive/a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'xxhash'; File = 'xxHash-0.8.4.tar.gz'
|
||||
Uris = @('https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.4.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.4.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'zlib'; File = 'zlib-1.3.2.tar.gz'
|
||||
Uris = @('https://github.com/madler/zlib/releases/download/v1.3.2/zlib-1.3.2.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/madler/zlib/releases/download/v1.3.2/zlib-1.3.2.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'zstd'; File = 'zstd-1.5.7.tar.gz'
|
||||
Uris = @('https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz' })
|
||||
}
|
||||
)
|
||||
|
||||
# The C++/WinRT compiler (NuGet package = zip) that generates the projection headers.
|
||||
$cppWinRtTool = [pscustomobject]@{
|
||||
Name = 'cppwinrt-tool'; File = 'Microsoft.Windows.CppWinRT.3.0.260818.1.nupkg'
|
||||
Uris = @('https://www.nuget.org/api/v2/package/Microsoft.Windows.CppWinRT/3.0.260818.1')
|
||||
Pins = @()
|
||||
}
|
||||
|
||||
if (-not $Destination) { $Destination = Join-Path $PSScriptRoot 'artifacts\dependencies' }
|
||||
$Destination = [IO.Path]::GetFullPath($Destination)
|
||||
$downloads = Join-Path $PSScriptRoot 'artifacts\downloads'
|
||||
$tar = Join-Path $env:SystemRoot 'System32\tar.exe'
|
||||
if (-not (Test-Path -LiteralPath $tar -PathType Leaf)) { throw "Windows archive tool is missing: $tar" }
|
||||
[IO.Directory]::CreateDirectory($Destination) | Out-Null
|
||||
[IO.Directory]::CreateDirectory($downloads) | Out-Null
|
||||
|
||||
function Assert-Pinned($Package) {
|
||||
foreach ($pin in $Package.Pins) {
|
||||
if (-not (Test-Path -LiteralPath $pin.File -PathType Leaf)) { throw "Pin source is missing: $($pin.File)" }
|
||||
$content = [IO.File]::ReadAllText($pin.File)
|
||||
if (-not $content.Contains($pin.Text)) {
|
||||
throw "$($Package.Name) is pinned to '$($pin.Text)' here but $($pin.File) no longer declares it; update both."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-Archive($Package) {
|
||||
$archive = Join-Path $downloads $Package.File
|
||||
if (Test-Path -LiteralPath $archive -PathType Leaf) { return $archive }
|
||||
$temporary = $archive + '.partial'
|
||||
$failures = @()
|
||||
foreach ($uri in $Package.Uris) {
|
||||
Remove-Item -LiteralPath $temporary -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Downloading $($Package.Name) from $uri..."
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $uri -OutFile $temporary
|
||||
} catch {
|
||||
$failures += "$uri ($($_.Exception.Message))"
|
||||
continue
|
||||
}
|
||||
Move-Item -LiteralPath $temporary -Destination $archive -Force
|
||||
return $archive
|
||||
}
|
||||
Remove-Item -LiteralPath $temporary -Force -ErrorAction SilentlyContinue
|
||||
throw "$($Package.Name) could not be fetched: $($failures -join '; ')"
|
||||
}
|
||||
|
||||
function Expand-Package([string]$Archive, [string]$Target) {
|
||||
# Release archives wrap everything in one versioned directory (SDL3-3.4.4/, tracy-<sha>/) while
|
||||
# dawn-build's package is flat; either way the tree lands directly under the target.
|
||||
$extract = Join-Path (Split-Path -Parent $Target) ('.extract-' + (Split-Path -Leaf $Target))
|
||||
if (Test-Path -LiteralPath $extract) { Remove-Item -LiteralPath $extract -Recurse -Force }
|
||||
[IO.Directory]::CreateDirectory($extract) | Out-Null
|
||||
# Symbolic links need a privilege Windows tar usually lacks; the only ones in these archives
|
||||
# are zstd test aliases, and none are build inputs.
|
||||
$listing = & $tar -tvf $Archive
|
||||
if ($LASTEXITCODE -ne 0) { throw "Listing $Archive failed with exit code $LASTEXITCODE." }
|
||||
$excludes = @($listing | ForEach-Object { if ($_ -match '^l.*\s(\S+)\s->\s') { '--exclude=' + $Matches[1] } })
|
||||
& $tar -xf $Archive -C $extract @excludes
|
||||
if ($LASTEXITCODE -ne 0) { throw "Extracting $Archive failed with exit code $LASTEXITCODE." }
|
||||
$entries = @(Get-ChildItem -LiteralPath $extract -Force)
|
||||
$source = $extract
|
||||
if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) { $source = $entries[0].FullName }
|
||||
if (Test-Path -LiteralPath $Target) { Remove-Item -LiteralPath $Target -Recurse -Force }
|
||||
Move-Item -LiteralPath $source -Destination $Target
|
||||
if (Test-Path -LiteralPath $extract) { Remove-Item -LiteralPath $extract -Recurse -Force }
|
||||
}
|
||||
|
||||
foreach ($package in $packages) {
|
||||
Assert-Pinned $package
|
||||
$target = Join-Path $Destination $package.Name
|
||||
if (Test-Path -LiteralPath $target -PathType Container) { continue }
|
||||
Expand-Package (Get-Archive $package) $target
|
||||
Write-Host "Prepared $($package.Name)"
|
||||
}
|
||||
|
||||
$cppWinRt = Join-Path $Destination 'cppwinrt'
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $cppWinRt 'winrt\base.h') -PathType Leaf)) {
|
||||
$toolRoot = Join-Path $PSScriptRoot 'artifacts\cppwinrt-tool'
|
||||
$compiler = Join-Path $toolRoot 'bin\cppwinrt.exe'
|
||||
if (-not (Test-Path -LiteralPath $compiler -PathType Leaf)) {
|
||||
Expand-Package (Get-Archive $cppWinRtTool) $toolRoot
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $compiler -PathType Leaf)) { throw "cppwinrt.exe is missing: $compiler" }
|
||||
if (Test-Path -LiteralPath $cppWinRt) { Remove-Item -LiteralPath $cppWinRt -Recurse -Force }
|
||||
[IO.Directory]::CreateDirectory($cppWinRt) | Out-Null
|
||||
Write-Host "Generating C++/WinRT headers (-input $CppWinRtInput)..."
|
||||
& $compiler -input $CppWinRtInput -output $cppWinRt
|
||||
if ($LASTEXITCODE -ne 0) { throw "cppwinrt.exe failed with exit code $LASTEXITCODE." }
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $cppWinRt 'winrt\base.h') -PathType Leaf)) {
|
||||
throw "cppwinrt.exe produced no winrt\base.h under $cppWinRt"
|
||||
}
|
||||
Copy-Item -LiteralPath (Join-Path $toolRoot 'LICENSE') -Destination (Join-Path $cppWinRt 'LICENSE.txt')
|
||||
Write-Host 'Prepared cppwinrt'
|
||||
}
|
||||
|
||||
Write-Host "Pinned dependency sources ready: $Destination"
|
||||
@@ -61,8 +61,6 @@ Assert-File $windres 'Portable resource compiler'
|
||||
Assert-File $clangBinary 'Portable clang driver binary'
|
||||
Assert-Directory $dependencies 'Pinned offline dependency sources'
|
||||
Assert-Directory $auroraSource 'aurora-main source tree'
|
||||
Assert-File (Join-Path $repoRoot 'generated\build_shards\shards.cmake') `
|
||||
'Translator shard manifest (run the developer build once so runtime/ can configure)'
|
||||
|
||||
if ($Parallel -le 0) { $Parallel = [Environment]::ProcessorCount }
|
||||
|
||||
|
||||
Executable
+660
@@ -0,0 +1,660 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds the redistributable precompiled aurora + third-party package for native Linux: aurora
|
||||
# (~43% of local build CPU time per Prepare-NativePrebuilt.ps1), Crypto++ and mbed TLS are identical
|
||||
# for every user under the pinned toolchain prepare-portable-tools.sh bundles, so this configures
|
||||
# runtime/ against that toolchain, builds just that closure, and harvests the archives plus a
|
||||
# generated CMake description into an output package - the Linux counterpart to
|
||||
# Launcher/Prepare-NativePrebuilt.ps1, consumed by the same platform-agnostic
|
||||
# runtime/cmake/NativePrebuilt.cmake either script's package works with unmodified.
|
||||
#
|
||||
# Not a byte-for-byte port of the Windows script: Linux needs no offline pinned dependency cache.
|
||||
# Every FetchContent dependency in aurora-main/extern/CMakeLists.txt is a fixed-version URL already
|
||||
# (verified directly), and aurora-main/CMakeLists.txt's own _default_linkage is "static" on any
|
||||
# non-Windows platform. Windows pins Launcher/artifacts/dependencies because its installer ships
|
||||
# pre-fetched sources to end users for a fully offline build; this harvest only ever runs on a
|
||||
# maintainer's own machine (network access needed once, here, not shipped to anyone), so a plain
|
||||
# networked configure is exactly as reproducible - what actually makes the harvested archives safe
|
||||
# to link into any consumer's own build is the pinned compiler below, not an offline source cache.
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
workspace=$(cd "$script_dir/.." && pwd)
|
||||
|
||||
arch=""
|
||||
output_dir=""
|
||||
toolchain_dir=""
|
||||
ninja_bin=""
|
||||
cmake_bin=""
|
||||
llvm_dir=""
|
||||
sysroot=""
|
||||
stage_dir="$workspace/build/native-prebuilt-stage"
|
||||
keep_stage=0
|
||||
reuse_stage=0
|
||||
parallel=0
|
||||
print_fingerprint_only=0
|
||||
disconnected=0
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: Prepare-NativePrebuilt.sh --arch {x86_64|aarch64} [options]
|
||||
|
||||
--arch ARCH Target architecture; selects the matching bundled toolchain (required)
|
||||
--output-dir DIR Where the package is written (default: Launcher/artifacts/native-prebuilt-ARCH)
|
||||
--stage-dir DIR Staging build directory (default: build/native-prebuilt-stage)
|
||||
--keep-stage Do not delete the staging build directory afterward
|
||||
--reuse-stage Reuse an existing staging build directory (maintainer iteration aid: a
|
||||
re-harvest does not recompile aurora from scratch)
|
||||
--parallel N Ninja build parallelism (default: nproc)
|
||||
--print-fingerprint-only Print the provenance inputs as "key=value" lines and
|
||||
exit, without configuring/building/harvesting anything - lets a caller
|
||||
(build-appimage.sh) decide whether an existing package is still current
|
||||
without paying for a full aurora rebuild just to find out.
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--arch) arch=$2; shift 2 ;;
|
||||
--output-dir) output_dir=$2; shift 2 ;;
|
||||
--stage-dir) stage_dir=$2; shift 2 ;;
|
||||
--keep-stage) keep_stage=1; shift ;;
|
||||
--reuse-stage) reuse_stage=1; shift ;;
|
||||
--parallel) parallel=$2; shift 2 ;;
|
||||
--print-fingerprint-only) print_fingerprint_only=1; shift ;;
|
||||
--toolchain-dir) toolchain_dir=$2; shift 2 ;;
|
||||
--ninja-bin) ninja_bin=$2; shift 2 ;;
|
||||
--cmake-bin) cmake_bin=$2; shift 2 ;;
|
||||
--llvm-dir) llvm_dir=$2; shift 2 ;;
|
||||
--sysroot) sysroot=$2; shift 2 ;;
|
||||
--disconnected) disconnected=1; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Prepare-NativePrebuilt.sh: unknown argument: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$arch" in
|
||||
x86_64|aarch64) ;;
|
||||
*) echo "Prepare-NativePrebuilt.sh: --arch must be x86_64 or aarch64" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
|
||||
fail() { echo "Prepare-NativePrebuilt.sh: error: $*" >&2; exit 1; }
|
||||
assert_file() { [[ -f "$1" ]] || fail "$2 is missing: $1"; }
|
||||
assert_dir() { [[ -d "$1" ]] || fail "$2 is missing: $1"; }
|
||||
sha256_of() { sha256sum "$1" | awk '{print $1}'; }
|
||||
normalize() { readlink -f "$1"; }
|
||||
|
||||
# Environment check: Ensure the `SOURCE_DATE_EPOCH` value is not invalid
|
||||
# before trying to build anything (fail-fast)
|
||||
if [[ -n "${SOURCE_DATE_EPOCH:-}" ]] && ! python3 -c \
|
||||
'import datetime, os; datetime.datetime.fromtimestamp(int(os.environ.get("SOURCE_DATE_EPOCH")), datetime.timezone.utc)'
|
||||
then
|
||||
fail "SOURCE_DATE_EPOCH must be a valid UNIX timestamp"
|
||||
fi
|
||||
|
||||
[[ -n "$output_dir" ]] || output_dir="$script_dir/artifacts/native-prebuilt-$arch"
|
||||
[[ "$stage_dir" = /* ]] || stage_dir="$workspace/$stage_dir"
|
||||
|
||||
toolchain_dir="${toolchain_dir:-$script_dir/artifacts/portable-tools/toolchain-$arch}"
|
||||
cc="${llvm_dir:-$toolchain_dir}/bin/clang"
|
||||
cxx="${llvm_dir:-$toolchain_dir}/bin/clang++"
|
||||
cmake_bin="${cmake_bin:-$toolchain_dir/bin/cmake}"
|
||||
ninja_bin="${ninja_bin:-$toolchain_dir/bin/ninja}"
|
||||
runtime_source="$workspace/runtime"
|
||||
aurora_source="$workspace/aurora-main"
|
||||
|
||||
assert_file "$cmake_bin" "Portable CMake (run prepare-portable-tools.sh --arch $arch first)"
|
||||
assert_file "$ninja_bin" "Portable Ninja"
|
||||
assert_file "$cc" "Portable C compiler"
|
||||
assert_file "$cxx" "Portable C++ compiler"
|
||||
assert_dir "$aurora_source" "aurora-main source tree"
|
||||
clang_binary=$(normalize "${llvm_dir:-$toolchain_dir}/bin/clang-22")
|
||||
assert_file "$clang_binary" "Portable clang driver binary"
|
||||
|
||||
(( parallel > 0 )) || parallel=$(nproc)
|
||||
|
||||
fingerprint_tree() {
|
||||
# $1 = root dir, remaining args = top-level subdirectory names to exclude
|
||||
local root=$1; shift
|
||||
root=$(normalize "$root")
|
||||
[[ -d "$root" ]] || return 0
|
||||
local find_args=("$root" -name .git -prune -o)
|
||||
local ex
|
||||
for ex in "$@"; do find_args+=(-path "$root/$ex" -prune -o); done
|
||||
find_args+=(-type f -print)
|
||||
find "${find_args[@]}" | LC_ALL=C sort | while IFS= read -r abs; do
|
||||
printf '%s %s\n' "${abs#$root/}" "$(sha256_of "$abs")"
|
||||
done | sha256sum | awk '{print $1}'
|
||||
}
|
||||
|
||||
# The fixed (path-independent) half of the configure command line - identical for every
|
||||
# harvest, which is what lets one package be valid regardless of where it was built.
|
||||
# -DBUILD_SHARED_LIBS=OFF: aurora-main/extern/CMakeLists.txt derives its own _USE_SHARED from
|
||||
# whether BUILD_SHARED_LIBS is *defined at all* (not its value), so leaving it unset would default
|
||||
# zlib/libpng to shared. -DAURORA_SDL3_PROVIDER=vendor: without it, "auto" resolves to "system" on
|
||||
# any machine that happens to have an SDL3 dev package installed. -DCMAKE_DISABLE_FIND_PACKAGE_*:
|
||||
# absl/PNG/Freetype each call find_package() unconditionally, with no provider flag to gate them
|
||||
# (unlike SDL3/Dawn) - verified directly that this machine's system libpng-dev/freetype-dev get
|
||||
# linked in shared instead of the pinned vendored source otherwise. Disabling find_package for
|
||||
# these three forces the same FetchContent-vendored, statically-built result regardless of what a
|
||||
# given maintainer's machine happens to have installed. ZLIB is deliberately NOT disabled the same
|
||||
# way: libpng's own vendored CMakeLists.txt calls find_package(ZLIB REQUIRED) internally even when
|
||||
# zlib came from aurora's own FetchContent (extern/CMakeLists.txt writes a redirect config for
|
||||
# exactly this), and CMAKE_DISABLE_FIND_PACKAGE_ZLIB errors out on any REQUIRED call site outright
|
||||
# (verified directly) - it cannot be scoped to only aurora's own initial, non-required check.
|
||||
# Dawn stays a prebuilt package regardless (Linux x86_64/aarch64 always auto-resolve to "package" -
|
||||
# see AuroraDawnProvider.cmake).
|
||||
fixed_configure_flags=(
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DAURORA_SDL3_PROVIDER=vendor
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_absl=ON
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_PNG=ON
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_Freetype=ON
|
||||
-DUSE_STATIC_MBEDTLS_LIBRARY=ON
|
||||
-DUSE_SHARED_MBEDTLS_LIBRARY=OFF
|
||||
# Freetype's own vendored CMakeLists.txt separately probes for system BZip2 (optional
|
||||
# bzip2-compressed-font support aurora-main never asked for) regardless of the Freetype
|
||||
# find_package disable above, since that only stops aurora's own outer find_package(Freetype)
|
||||
# from picking up a system Freetype - it does not reach into the FetchContent-built copy's own
|
||||
# internal find_package(BZip2) call. FT_DISABLE_BZIP2 is Freetype's own documented flag for
|
||||
# exactly this (verified in its CMakeLists.txt), unlike the ZLIB/libpng situation where no such
|
||||
# source-level flag exists.
|
||||
-DFT_DISABLE_BZIP2=ON
|
||||
-DCMAKE_POLICY_DEFAULT_CMP0168=NEW
|
||||
)
|
||||
if [[ "$disconnected" -eq 1 ]]; then
|
||||
fixed_configure_flags+=(
|
||||
-DFETCHCONTENT_FULLY_DISCONNECTED=ON
|
||||
)
|
||||
fi
|
||||
if [[ -n "$sysroot" ]]; then
|
||||
fixed_configure_flags+=(
|
||||
-DCMAKE_SYSROOT="$sysroot"
|
||||
)
|
||||
fi
|
||||
flag_fingerprint=$(printf '%s\n' "${fixed_configure_flags[@]}" | sha256sum | awk '{print $1}')
|
||||
|
||||
# extern/ is excluded because the payload ships that tree separately (aurora-main/extern is bundled
|
||||
# whole by build-appimage.sh); build/ is a plain developer build directory.
|
||||
aurora_fingerprint=$(fingerprint_tree "$aurora_source" extern build)
|
||||
[[ -n "$aurora_fingerprint" ]] || fail "The aurora source tree could not be fingerprinted: $aurora_source"
|
||||
|
||||
# The harvested Crypto++ archive is consumed against this tree's headers, so it is fingerprinted.
|
||||
third_party_fingerprint=$(fingerprint_tree "$runtime_source/third_party")
|
||||
[[ -n "$third_party_fingerprint" ]] || fail "The vendored third-party tree could not be fingerprinted: $runtime_source/third_party"
|
||||
mbedtls_fingerprint=$(sha256_of "$runtime_source/cmake/MbedTLSPin.cmake")
|
||||
|
||||
compiler_sha256=$(sha256_of "$cc")
|
||||
cxx_sha256=$(sha256_of "$cxx")
|
||||
# Append the CXX SHA256 if it doesn't match the hash of CC
|
||||
if [[ "${cxx_sha256}" != "${compiler_sha256}" ]]; then
|
||||
compiler_sha256="${compiler_sha256}:${cxx_sha256}"
|
||||
fi
|
||||
|
||||
if [[ "$print_fingerprint_only" -eq 1 ]]; then
|
||||
printf 'compiler_sha256=%s\n' "$compiler_sha256"
|
||||
printf 'flag_fingerprint=%s\n' "$flag_fingerprint"
|
||||
printf 'aurora_fingerprint=%s\n' "$aurora_fingerprint"
|
||||
printf 'third_party_fingerprint=%s\n' "$third_party_fingerprint"
|
||||
printf 'mbedtls_fingerprint=%s\n' "$mbedtls_fingerprint"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# The package must never contain a stale mixture of two builds.
|
||||
rm -rf "$output_dir"
|
||||
mkdir -p "$output_dir/lib" "$output_dir/bin" "$output_dir/include"
|
||||
|
||||
# The staging build has to be configured without the package present, otherwise the runtime would
|
||||
# consume the very package this script is producing.
|
||||
if [[ "$reuse_stage" -eq 0 ]]; then rm -rf "$stage_dir"; fi
|
||||
export_dir="$stage_dir/export"
|
||||
mkdir -p "$export_dir"
|
||||
|
||||
# fixed_configure_flags/flag_fingerprint were already computed above (needed before the
|
||||
# --print-fingerprint-only early exit).
|
||||
echo "Prepare-NativePrebuilt.sh: configuring the aurora/third-party staging build..."
|
||||
"$cmake_bin" -S "$runtime_source" -B "$stage_dir" -G Ninja \
|
||||
"${fixed_configure_flags[@]}" \
|
||||
-DCMAKE_C_COMPILER="$cc" -DCMAKE_CXX_COMPILER="$cxx" \
|
||||
-DCMAKE_MAKE_PROGRAM="$ninja_bin" \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
|
||||
-DMKW_NATIVE_PREBUILT_EXPORT_DIR="$export_dir"
|
||||
|
||||
# mkw_np_probe links exactly what mkw_runtime_common and the public products link, so building it
|
||||
# compiles the whole redistributable closure and nothing else - and a successful link proves the
|
||||
# harvested archives are complete.
|
||||
echo "Prepare-NativePrebuilt.sh: building the aurora/third-party closure..."
|
||||
"$cmake_bin" --build "$stage_dir" --target mkw_np_probe --parallel "$parallel"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Read the description CMake wrote, plus the resolved command lines Ninja holds.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
meta_path="$export_dir/meta.txt"
|
||||
assert_file "$meta_path" "Native prebuilt export metadata"
|
||||
get_meta() { awk -F= -v k="$1" '$0 ~ "^" k "=" { sub(/^[^=]*=/, ""); print; exit }' "$meta_path"; }
|
||||
|
||||
build_ninja="$stage_dir/build.ninja"
|
||||
assert_file "$build_ninja" "Generated build.ninja"
|
||||
|
||||
extract_ninja_vars() {
|
||||
# $1 = ninja file, $2 = exact rule name. Prints "KEY\tVALUE" for every " KEY = VALUE" line
|
||||
# following the first "build ...: RULE ..." statement that uses that rule.
|
||||
awk -v rule="$2" '
|
||||
BEGIN { in_stmt = 0 }
|
||||
/^build / {
|
||||
if (in_stmt) exit
|
||||
colon = index($0, ": ")
|
||||
if (colon == 0) next
|
||||
rest = substr($0, colon + 2)
|
||||
sp = index(rest, " ")
|
||||
stmt_rule = (sp > 0) ? substr(rest, 1, sp - 1) : rest
|
||||
if (stmt_rule == rule) in_stmt = 1
|
||||
next
|
||||
}
|
||||
in_stmt {
|
||||
if (substr($0, 1, 2) != " ") exit
|
||||
line = substr($0, 3)
|
||||
eq = index(line, " = ")
|
||||
if (eq == 0) exit
|
||||
print substr(line, 1, eq - 1) "\t" substr(line, eq + 3)
|
||||
}
|
||||
' "$1"
|
||||
}
|
||||
|
||||
declare -A probe_compile=() control_compile=() probe_link=() control_link=()
|
||||
load_vars() {
|
||||
local -n dest=$1
|
||||
local k v
|
||||
while IFS=$'\t' read -r k v; do dest["$k"]=$v; done < <(extract_ninja_vars "$build_ninja" "$2")
|
||||
}
|
||||
load_vars probe_compile "CXX_COMPILER__mkw_np_probe_unscanned_Release"
|
||||
load_vars control_compile "CXX_COMPILER__mkw_np_probe_control_unscanned_Release"
|
||||
load_vars probe_link "CXX_EXECUTABLE_LINKER__mkw_np_probe_Release"
|
||||
load_vars control_link "CXX_EXECUTABLE_LINKER__mkw_np_probe_control_Release"
|
||||
[[ -n "${probe_compile[INCLUDES]+x}" ]] || fail "No Ninja statement used rule CXX_COMPILER__mkw_np_probe_unscanned_Release."
|
||||
[[ -n "${probe_link[LINK_LIBRARIES]+x}" ]] || fail "No Ninja statement used rule CXX_EXECUTABLE_LINKER__mkw_np_probe_Release."
|
||||
|
||||
split_list() {
|
||||
# $1 = string value, $2 = name of the array to fill (nameref)
|
||||
local -n out=$2
|
||||
out=()
|
||||
[[ -n "$1" ]] || return 0
|
||||
read -ra out <<< "$1"
|
||||
}
|
||||
|
||||
subtract_multiset() {
|
||||
# $1 = "all" array name, $2 = "remove" array name, $3 = result array name (all namerefs)
|
||||
local -n all_ref=$1 remove_ref=$2 result_ref=$3
|
||||
local -A pending=()
|
||||
local item
|
||||
for item in "${remove_ref[@]}"; do
|
||||
pending["$item"]=$(( ${pending["$item"]:-0} + 1 ))
|
||||
done
|
||||
result_ref=()
|
||||
for item in "${all_ref[@]}"; do
|
||||
if [[ "${pending["$item"]:-0}" -gt 0 ]]; then
|
||||
pending["$item"]=$(( pending["$item"] - 1 ))
|
||||
continue
|
||||
fi
|
||||
result_ref+=("$item")
|
||||
done
|
||||
}
|
||||
|
||||
split_list "${probe_compile[INCLUDES]:-}" _probe_includes
|
||||
split_list "${control_compile[INCLUDES]:-}" _control_includes
|
||||
subtract_multiset _probe_includes _control_includes include_arguments
|
||||
|
||||
split_list "${probe_compile[DEFINES]:-}" _probe_defines
|
||||
split_list "${control_compile[DEFINES]:-}" _control_defines
|
||||
subtract_multiset _probe_defines _control_defines define_arguments
|
||||
|
||||
split_list "${probe_compile[FLAGS]:-}" _probe_flags
|
||||
split_list "${control_compile[FLAGS]:-}" _control_flags
|
||||
subtract_multiset _probe_flags _control_flags compile_options_raw
|
||||
|
||||
split_list "${probe_link[LINK_LIBRARIES]:-}" _probe_link
|
||||
split_list "${control_link[LINK_LIBRARIES]:-}" _control_link
|
||||
subtract_multiset _probe_link _control_link link_items
|
||||
|
||||
[[ ${#include_arguments[@]} -gt 0 ]] || fail "The aurora compile interface is empty; the probe did not link aurora."
|
||||
[[ ${#link_items[@]} -gt 0 ]] || fail "The aurora link interface is empty; the probe did not link aurora."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Harvest the built libraries.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
binary_root=$(normalize "$stage_dir")
|
||||
aurora_root=$(normalize "$(get_meta aurora_dir)")
|
||||
runtime_root=$(normalize "$(get_meta runtime_dir)")
|
||||
|
||||
generated_include_index=0
|
||||
copy_harvested() {
|
||||
# $1 = source path, $2 = subdirectory under the package. Echoes "subdir/name".
|
||||
local source=$1 subdir=$2
|
||||
local name destination
|
||||
name=$(basename "$source")
|
||||
destination="$output_dir/$subdir/$name"
|
||||
[[ ! -e "$destination" ]] || fail "Two harvested files collide on the name $name: $source"
|
||||
cp "$source" "$destination"
|
||||
printf '%s/%s' "$subdir" "$name"
|
||||
}
|
||||
declare -A generated_include_tokens=()
|
||||
convert_to_token() {
|
||||
# $1 = absolute path, $2 = 'include' or another kind. Sets $TOKEN_RESULT - NOT echoed/command-
|
||||
# substituted: this needs to mutate generated_include_tokens/generated_include_index, and a
|
||||
# $(...) call runs in a subshell, silently discarding that mutation once it returns (verified
|
||||
# directly: every build-tree include directory collided into the same "generated01" until this
|
||||
# was written this way instead).
|
||||
local path kind=$2
|
||||
path=$(normalize "$1")
|
||||
case "$path" in
|
||||
"$aurora_root"/*) TOKEN_RESULT="@AURORA@/${path#$aurora_root/}"; return ;;
|
||||
"$runtime_root"/*) TOKEN_RESULT="@RUNTIME@/${path#$runtime_root/}"; return ;;
|
||||
"$binary_root"/*)
|
||||
[[ "$kind" == include ]] || fail "Unhandled build-tree artifact: $path"
|
||||
if [[ -n "${generated_include_tokens[$path]:-}" ]]; then
|
||||
TOKEN_RESULT=${generated_include_tokens[$path]}
|
||||
return
|
||||
fi
|
||||
generated_include_index=$((generated_include_index + 1))
|
||||
local name destination
|
||||
name=$(printf 'generated%02d' "$generated_include_index")
|
||||
destination="$output_dir/include/$name"
|
||||
mkdir -p "$destination"
|
||||
cp -a "$path/." "$destination/"
|
||||
TOKEN_RESULT="@PKG@/include/$name"
|
||||
generated_include_tokens[$path]=$TOKEN_RESULT
|
||||
return ;;
|
||||
*) fail "Path escapes every shippable root ($kind): $path" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
declare -A linker_file_to_reference=()
|
||||
shared_import_targets=() shared_import_runtime=() shared_import_implib=()
|
||||
targets_txt="$export_dir/targets.txt"
|
||||
assert_file "$targets_txt" "Native prebuilt export targets list"
|
||||
while IFS='|' read -r name type file linkerfile; do
|
||||
[[ -n "$name" ]] || continue
|
||||
[[ -f "$linkerfile" ]] || continue # not part of the closure mkw_np_probe pulled in
|
||||
linkerfile=$(normalize "$linkerfile")
|
||||
relative_linker=$(copy_harvested "$linkerfile" lib)
|
||||
if [[ "$type" == "SHARED_LIBRARY" ]]; then
|
||||
file_abs=$(normalize "$file")
|
||||
# Unlike Windows (a .dll + a separate .dll.a import library), a Linux shared object's
|
||||
# TARGET_FILE and TARGET_LINKER_FILE are the same path - one file, harvested once.
|
||||
if [[ "$file_abs" == "$linkerfile" ]]; then
|
||||
relative_runtime=$relative_linker
|
||||
else
|
||||
[[ -f "$file_abs" ]] || fail "Shared library $name has no runtime file: $file_abs"
|
||||
relative_runtime=$(copy_harvested "$file_abs" bin)
|
||||
fi
|
||||
shared_import_targets+=("mkw_np::$name")
|
||||
shared_import_runtime+=("$relative_runtime")
|
||||
shared_import_implib+=("$relative_linker")
|
||||
linker_file_to_reference["$linkerfile"]="mkw_np::$name"
|
||||
else
|
||||
linker_file_to_reference["$linkerfile"]="@PKG@/$relative_linker"
|
||||
fi
|
||||
done < "$targets_txt"
|
||||
mbedtls_refs=()
|
||||
mbedtls_txt="$export_dir/mbedtls.txt"
|
||||
assert_file "$mbedtls_txt" "Mbed TLS export targets list"
|
||||
while IFS='|' read -r name linkerfile; do
|
||||
[[ -n "$name" ]] || continue
|
||||
linkerfile=$(normalize "$linkerfile")
|
||||
ref=${linker_file_to_reference["$linkerfile"]:-}
|
||||
[[ -n "$ref" ]] || fail "Mbed TLS archive was not harvested: $name ($linkerfile)"
|
||||
mbedtls_refs+=("$ref")
|
||||
done < "$mbedtls_txt"
|
||||
[[ ${#mbedtls_refs[@]} -ge 3 ]] || fail "Expected at least three Mbed TLS archives, got ${#mbedtls_refs[@]}"
|
||||
mbedtls_source_dir=$(get_meta mbedtls_source_dir)
|
||||
assert_dir "$mbedtls_source_dir/include/mbedtls" "Mbed TLS headers"
|
||||
mkdir -p "$output_dir/include/mbedtls"
|
||||
cp -a "$mbedtls_source_dir/include/." "$output_dir/include/mbedtls/"
|
||||
# Unlike Windows (SDL/zlib/libpng ship as DLLs by default), everything here was forced static above
|
||||
# and Dawn's own Linux package (verified directly) ships libwebgpu_dawn.a, also static - so zero
|
||||
# shared imports is the expected, normal outcome, not a failure.
|
||||
echo "Prepare-NativePrebuilt.sh: harvested ${#linker_file_to_reference[@]} archive(s) (${#shared_import_targets[@]} shared)"
|
||||
|
||||
dawn_linker_file="" dawn_runtime_file=""
|
||||
dawn_txt="$export_dir/dawn.txt"
|
||||
if [[ -s "$dawn_txt" ]]; then
|
||||
IFS='|' read -r _ dawn_runtime_file dawn_linker_file < "$dawn_txt"
|
||||
dawn_runtime_file=$(normalize "$dawn_runtime_file")
|
||||
dawn_linker_file=$(normalize "$dawn_linker_file")
|
||||
fi
|
||||
[[ -n "$dawn_linker_file" ]] && linker_file_to_reference["$dawn_linker_file"]="dawn::webgpu_dawn"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Rewrite the compile/link interface into workspace-relative tokens.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
package_include_dirs=()
|
||||
include_count=${#include_arguments[@]}
|
||||
i=0
|
||||
while (( i < include_count )); do
|
||||
entry=${include_arguments[i]}
|
||||
case "$entry" in
|
||||
-I*) convert_to_token "${entry#-I}" include; package_include_dirs+=("$TOKEN_RESULT") ;;
|
||||
-isystem)
|
||||
i=$((i + 1))
|
||||
(( i < include_count )) || fail "Trailing -isystem with no argument"
|
||||
convert_to_token "${include_arguments[i]}" include; package_include_dirs+=("$TOKEN_RESULT") ;;
|
||||
-isystem*) convert_to_token "${entry#-isystem}" include; package_include_dirs+=("$TOKEN_RESULT") ;;
|
||||
*) fail "Unexpected include argument: $entry" ;;
|
||||
esac
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
package_definitions=()
|
||||
for entry in "${define_arguments[@]}"; do
|
||||
case "$entry" in
|
||||
# Ninja records a quoted define's value with its quotes backslash-escaped (verified
|
||||
# directly: IMGUI_USER_CONFIG=\"aurora/imgui_config.h\" in build.ninja) regardless of
|
||||
# platform - format_cmake_block below re-escapes for CMake's own string syntax, so the
|
||||
# literal backslash has to come out here first or the result is double-escaped and the
|
||||
# define expands to literal backslash-quote characters instead of a quoted string.
|
||||
-D*) package_definitions+=("${entry#-D}") ;;
|
||||
*) fail "Unexpected define argument: $entry" ;;
|
||||
esac
|
||||
done
|
||||
package_definitions=("${package_definitions[@]//\\\"/\"}")
|
||||
|
||||
# fmt's `-include cstdlib` (and anything like it) is recorded from a C++ compile line, so re-scope
|
||||
# it to C++. The runtime also assembles generated .S blobs through the same targets, and a forced
|
||||
# C++ header include would break them.
|
||||
package_compile_options=()
|
||||
for entry in "${compile_options_raw[@]}"; do
|
||||
package_compile_options+=("\$<\$<COMPILE_LANGUAGE:CXX>:$entry>")
|
||||
done
|
||||
|
||||
package_link_items=()
|
||||
for item in "${link_items[@]}"; do
|
||||
case "$item" in
|
||||
-*) package_link_items+=("$item"); continue ;;
|
||||
esac
|
||||
if [[ "$item" = /* ]]; then item_abs=$(normalize "$item"); else item_abs=$(normalize "$stage_dir/$item"); fi
|
||||
ref=${linker_file_to_reference["$item_abs"]:-}
|
||||
if [[ -n "$ref" ]]; then
|
||||
for mbedtls_ref in "${mbedtls_refs[@]}"; do
|
||||
[[ "$ref" == "$mbedtls_ref" ]] && continue 2
|
||||
done
|
||||
package_link_items+=("$ref")
|
||||
continue
|
||||
fi
|
||||
case "$item_abs" in
|
||||
*/libz.so*)
|
||||
# The one unavoidable system reference: libpng's own vendored CMakeLists.txt calls
|
||||
# find_package(ZLIB REQUIRED) internally even when zlib came from aurora's own
|
||||
# FetchContent (extern/CMakeLists.txt writes a redirect config for exactly this case),
|
||||
# and CMAKE_DISABLE_FIND_PACKAGE_ZLIB errors out on any REQUIRED call site outright
|
||||
# (verified directly), so it cannot be forced to vendor/static the way absl/PNG/Freetype
|
||||
# are above. zlib is as close to a universal baseline as a Linux shared library gets
|
||||
# (glibc-adjacent - practically every distro has it already), so this is recorded as a
|
||||
# portable `-lz` link flag instead of the harvesting machine's absolute path.
|
||||
package_link_items+=("-lz")
|
||||
continue ;;
|
||||
esac
|
||||
fail "Link item is neither a system library nor a harvested archive: $item"
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Emit the consumer-facing CMake description.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
format_cmake_block() {
|
||||
# $1 = CMake variable name, remaining args = list items
|
||||
local name=$1; shift
|
||||
if [[ $# -eq 0 ]]; then
|
||||
printf 'set(%s "")\n' "$name"
|
||||
return
|
||||
fi
|
||||
printf 'set(%s\n' "$name"
|
||||
local item escaped
|
||||
for item in "$@"; do
|
||||
escaped=${item//\\/\\\\}
|
||||
escaped=${escaped//\"/\\\"}
|
||||
printf ' "%s"\n' "$escaped"
|
||||
done
|
||||
printf ')\n'
|
||||
}
|
||||
|
||||
dawn_config_dir_meta=$(get_meta dawn_config_dir)
|
||||
dawn_config_token=""
|
||||
if [[ -n "$dawn_config_dir_meta" ]]; then
|
||||
dawn_config_dir_abs=$(normalize "$dawn_config_dir_meta")
|
||||
case "$dawn_config_dir_abs" in
|
||||
"$binary_root"/*)
|
||||
# Dawn's find_package() config directory (lib/cmake/Dawn under its own fetched package
|
||||
# root) cannot go through the generic single-directory copy other build-tree artifacts
|
||||
# use: DawnConfig.cmake/DawnTargets.cmake derive _IMPORT_PREFIX/PACKAGE_PREFIX_DIR from
|
||||
# their OWN file location by walking up three parent directories (verified directly), so
|
||||
# the whole package root - include/, lib/, lib/cmake/Dawn/ together - must be copied as
|
||||
# one self-contained unit for that relative navigation to still resolve once moved.
|
||||
dawn_package_root=$(normalize "$dawn_config_dir_abs/../../..")
|
||||
dawn_config_relative=${dawn_config_dir_abs#$dawn_package_root/}
|
||||
mkdir -p "$output_dir/include/dawn_package"
|
||||
cp -a "$dawn_package_root/." "$output_dir/include/dawn_package/"
|
||||
dawn_config_token="@PKG@/include/dawn_package/$dawn_config_relative"
|
||||
;;
|
||||
*) convert_to_token "$dawn_config_dir_abs" include; dawn_config_token=$TOKEN_RESULT ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
generated_cmake="$output_dir/native_prebuilt.cmake"
|
||||
{
|
||||
echo "# Generated by Launcher/Prepare-NativePrebuilt.sh - do not edit."
|
||||
echo "#"
|
||||
echo "# Describes the precompiled aurora + third-party archives that replace a"
|
||||
echo "# from-source aurora-main build. Every path is a token resolved against the"
|
||||
echo "# consuming workspace, because the source trees still ship next to this"
|
||||
echo "# package and the runtime compiles against their headers."
|
||||
echo ""
|
||||
echo 'if(NOT MKW_NP_PACKAGE_DIR OR NOT MKW_NP_AURORA_DIR OR NOT MKW_NP_RUNTIME_DIR OR NOT MKW_NP_DEPS_DIR)'
|
||||
echo ' message(FATAL_ERROR "native_prebuilt.cmake must be included by runtime/cmake/NativePrebuilt.cmake")'
|
||||
echo 'endif()'
|
||||
echo ""
|
||||
format_cmake_block MKW_NP_INCLUDE_DIRECTORIES "${package_include_dirs[@]}"
|
||||
format_cmake_block MKW_NP_COMPILE_DEFINITIONS "${package_definitions[@]}"
|
||||
format_cmake_block MKW_NP_COMPILE_OPTIONS "${package_compile_options[@]}"
|
||||
format_cmake_block MKW_NP_LINK_LIBRARIES "${package_link_items[@]}"
|
||||
format_cmake_block MKW_NP_MBEDTLS_LIBRARIES "${mbedtls_refs[@]}"
|
||||
echo 'set(MKW_NP_MBEDTLS_INCLUDE_DIR "@PKG@/include/mbedtls")'
|
||||
printf 'set(MKW_NP_MBEDTLS_FINGERPRINT "%s")\n' "$mbedtls_fingerprint"
|
||||
format_cmake_block MKW_NP_AURORA_TARGETS "aurora::gx" "aurora::pad" "aurora::si" "aurora::vi" "aurora::mtx"
|
||||
echo ""
|
||||
printf 'set(MKW_NP_DAWN_CONFIG_DIR "%s")\n' "$dawn_config_token"
|
||||
printf 'set(MKW_NP_DAWN_VERSION "%s")\n' "$(get_meta aurora_dawn_version)"
|
||||
echo ""
|
||||
echo "# Shared third-party libraries keep imported SHARED targets so that"
|
||||
echo '# $<TARGET_RUNTIME_DLLS> still copies them next to the game executable.'
|
||||
for idx in "${!shared_import_targets[@]}"; do
|
||||
printf 'add_library(%s SHARED IMPORTED GLOBAL)\n' "${shared_import_targets[$idx]}"
|
||||
printf 'set_target_properties(%s PROPERTIES\n' "${shared_import_targets[$idx]}"
|
||||
printf ' IMPORTED_LOCATION "${MKW_NP_PACKAGE_DIR}/%s"\n' "${shared_import_runtime[$idx]}"
|
||||
printf ' IMPORTED_IMPLIB "${MKW_NP_PACKAGE_DIR}/%s")\n' "${shared_import_implib[$idx]}"
|
||||
done
|
||||
} > "$generated_cmake"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Provenance: the pinned toolchain is what makes a precompiled archive interchangeable with
|
||||
# locally compiled objects (bit-for-bit the compiler and flag set the user's machine will use);
|
||||
# LocalBuild.ps1's Windows equivalent re-checks both before consuming a package, and a Linux
|
||||
# consumer-side check (once local-build.sh gains --native-prebuilt-dir) should do the same.
|
||||
# compiler_sha256/flag_fingerprint/aurora_fingerprint/third_party_fingerprint were already computed
|
||||
# above (needed before the --print-fingerprint-only early exit).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
dawn_runtime_sha256=""
|
||||
[[ -n "$dawn_runtime_file" && -f "$dawn_runtime_file" ]] && dawn_runtime_sha256=$(sha256_of "$dawn_runtime_file")
|
||||
[[ -n "$dawn_runtime_sha256" ]] || fail "The Dawn runtime could not be hashed: $dawn_runtime_file"
|
||||
|
||||
compiler_version=$(get_meta cxx_compiler_version)
|
||||
sdl3_target=$(get_meta aurora_sdl3_target)
|
||||
dawn_version=$(get_meta aurora_dawn_version)
|
||||
harvested_count=${#linker_file_to_reference[@]}
|
||||
|
||||
python3 - "$output_dir" "$compiler_sha256" "$compiler_version" "$flag_fingerprint" \
|
||||
"$dawn_version" "$dawn_runtime_sha256" "$aurora_fingerprint" "$third_party_fingerprint" \
|
||||
"$sdl3_target" "$harvested_count" "$mbedtls_fingerprint" <<'PY'
|
||||
import hashlib, json, os, sys, datetime
|
||||
|
||||
(output_dir, compiler_sha256, compiler_version, flag_fingerprint, dawn_version,
|
||||
dawn_runtime_sha256, aurora_fingerprint, third_party_fingerprint, sdl3_target,
|
||||
harvested_count, mbedtls_fingerprint) = sys.argv[1:]
|
||||
|
||||
contents = []
|
||||
for root, dirs, files in os.walk(output_dir):
|
||||
dirs.sort()
|
||||
for name in sorted(files):
|
||||
if name == "provenance.json":
|
||||
continue
|
||||
path = os.path.join(root, name)
|
||||
rel = os.path.relpath(path, output_dir).replace(os.sep, "/")
|
||||
with open(path, "rb") as fh:
|
||||
digest = hashlib.sha256(fh.read()).hexdigest()
|
||||
contents.append({"Path": rel, "Bytes": os.path.getsize(path), "Sha256": digest})
|
||||
contents.sort(key=lambda c: c["Path"])
|
||||
|
||||
source_date_epoch = os.environ.get("SOURCE_DATE_EPOCH") or None
|
||||
utc = datetime.timezone.utc
|
||||
if source_date_epoch is not None:
|
||||
built_utc = datetime.datetime.fromtimestamp(
|
||||
int(source_date_epoch),
|
||||
utc
|
||||
)
|
||||
else:
|
||||
built_utc = datetime.datetime.now(utc)
|
||||
|
||||
built_utc = built_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
|
||||
|
||||
provenance = {
|
||||
"SchemaVersion": 1,
|
||||
"BuiltUtc": built_utc,
|
||||
"CompilerSha256": compiler_sha256,
|
||||
"CompilerVersion": compiler_version,
|
||||
"FlagFingerprint": flag_fingerprint,
|
||||
"DawnVersion": dawn_version,
|
||||
"DawnRuntimeSha256": dawn_runtime_sha256,
|
||||
"AuroraSourceFingerprint": aurora_fingerprint,
|
||||
"ThirdPartySourceFingerprint": third_party_fingerprint,
|
||||
"MbedTlsFingerprint": mbedtls_fingerprint,
|
||||
"Sdl3Target": sdl3_target,
|
||||
"HarvestedLibraryCount": int(harvested_count),
|
||||
"Contents": contents,
|
||||
}
|
||||
with open(os.path.join(output_dir, "provenance.json"), "w", encoding="utf-8") as fh:
|
||||
json.dump(provenance, fh, indent=2)
|
||||
fh.write("\n")
|
||||
|
||||
total_bytes = sum(c["Bytes"] for c in contents)
|
||||
print(f" files: {len(contents)}; size: {total_bytes / (1024 * 1024):.1f} MiB")
|
||||
PY
|
||||
|
||||
if [[ "$keep_stage" -eq 0 ]]; then rm -rf "$stage_dir"; fi
|
||||
|
||||
echo ""
|
||||
echo "Native prebuilt package: $output_dir"
|
||||
echo " archives: $(find "$output_dir/lib" -maxdepth 1 -type f | wc -l); shared imports: ${#shared_import_targets[@]}"
|
||||
echo " flag fingerprint: $flag_fingerprint"
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fails the release build when a fact duplicated across the repo stops agreeing with the copy
|
||||
# that owns it (recomp.yml). Scripts read pinned facts through Get-MkwProjectPins, but three
|
||||
# consumers can't read YAML (the C++ runtime header, the C# constants, hand-written lists on
|
||||
# consumers can't read YAML (the C++ runtime header, the C# constants, shell scripts, and hand-written lists on
|
||||
# both sides of the C#/PowerShell boundary), so those are checked here instead.
|
||||
[CmdletBinding()]
|
||||
param([string]$RepositoryRoot)
|
||||
@@ -58,6 +58,12 @@ $hostUri = Get-CapturedValue $retroWfcPayload 'CurrentRetroWfcPayloadUri\s*=\s*"
|
||||
if ($hostUri -cne $pins.RetroWfcPayloadUri) {
|
||||
Add-Failure "InputValidation.CurrentRetroWfcPayloadUri is '$hostUri' but recomp.yml pins '$($pins.RetroWfcPayloadUri)'."
|
||||
}
|
||||
$macosSetup = Read-SourceFile (Join-Path $launcher 'macos\setup.command') 'macOS setup.command'
|
||||
$macosUri = Get-CapturedValue $macosSetup "'([^']*/api/wfc/payload\?g=RMCPD00)'" `
|
||||
'The macOS Retro-WFC endpoint'
|
||||
if ($macosUri -cne $pins.RetroWfcPayloadUri) {
|
||||
Add-Failure "macOS setup.command downloads '$macosUri' but recomp.yml pins '$($pins.RetroWfcPayloadUri)'."
|
||||
}
|
||||
|
||||
# --- The game identity: the manifest carries it, but the host also compiles a fallback for a
|
||||
# --- manifest that predates the field, and that fallback decides which disc is accepted.
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
# Build the real Windows runtime with translated, entirely synthetic PowerPC code.
|
||||
# No game dump, game symbol map, REL, mod download, or existing generated/ output is used.
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$PortableToolsDirectory = 'Launcher/artifacts/portable-tools',
|
||||
[string]$DependencySourceDirectory = 'Launcher/artifacts/dependencies',
|
||||
[string]$StageDirectory = 'build/recomp-test',
|
||||
[ValidateRange(1, 64)] [int]$Parallel = 3
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 3.0
|
||||
. (Join-Path $PSScriptRoot 'NativeBuildFlags.ps1')
|
||||
|
||||
$repoRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
|
||||
function Full([string]$Path) {
|
||||
if ([IO.Path]::IsPathRooted($Path)) { return [IO.Path]::GetFullPath($Path) }
|
||||
return [IO.Path]::GetFullPath((Join-Path $repoRoot $Path))
|
||||
}
|
||||
$portableTools = Full $PortableToolsDirectory
|
||||
$dependencies = Full $DependencySourceDirectory
|
||||
$stage = Full $StageDirectory
|
||||
$dotnet = (Get-Command dotnet -CommandType Application).Source
|
||||
$cmake = Join-Path $portableTools 'CMake/bin/cmake.exe'
|
||||
$ninja = Join-Path $portableTools 'Ninja/ninja.exe'
|
||||
$compilerBin = Join-Path $portableTools 'llvm-mingw/bin'
|
||||
Assert-File $cmake 'Pinned CMake (run Prepare-PortableTools.ps1 first)'
|
||||
Assert-File $ninja 'Pinned Ninja'
|
||||
Assert-File (Join-Path $dependencies 'cppwinrt/winrt/base.h') 'Pinned dependencies (run Prepare-Dependencies.ps1 first)'
|
||||
|
||||
# Refuse reuse so a developer's game translation or an earlier build cannot make
|
||||
# the test pass. Keep the staging tree after the run for diagnostics.
|
||||
if (Test-Path -LiteralPath $stage) { throw "Test stage already exists; choose a fresh -StageDirectory: $stage" }
|
||||
[IO.Directory]::CreateDirectory($stage) | Out-Null
|
||||
Write-Host "Synthetic recompilation workspace: $stage"
|
||||
|
||||
# Copy current sources, including uncommitted edits, but no ignored build output.
|
||||
# An isolated workspace preserves the developer's real generated/ directory.
|
||||
$auroraRoot = Join-Path $repoRoot 'aurora-main'
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $auroraRoot '.git'))) {
|
||||
throw 'Aurora submodule is not initialized. Run git submodule update --init --recursive first.'
|
||||
}
|
||||
# The parent tracks Aurora as one gitlink; enumerate its repository separately.
|
||||
# Retain untracked source files so local development edits are still tested.
|
||||
$sourceFiles = @(& git -C $repoRoot -c core.quotepath=false ls-files --cached --others --exclude-standard -- runtime)
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Could not enumerate runtime sources.' }
|
||||
$auroraFiles = @(& git -C $auroraRoot -c core.quotepath=false ls-files --cached --others --exclude-standard)
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Could not enumerate Aurora sources.' }
|
||||
$sourceFiles += @($auroraFiles | ForEach-Object { "aurora-main/$_" })
|
||||
foreach ($relative in $sourceFiles | Sort-Object -Unique) {
|
||||
$destination = Join-Path $stage $relative
|
||||
[IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($destination)) | Out-Null
|
||||
Copy-Item -LiteralPath (Join-Path $repoRoot $relative) -Destination $destination
|
||||
}
|
||||
|
||||
# One synthetic text section: li r3,40; addi r3,r3,2; nop; blr.
|
||||
# Native HLE wrappers also call these eight guest symbols directly. Give each
|
||||
# its own generated blr function so the real product can link without game code.
|
||||
# Keep this list explicit: a new unresolved guest dependency must fail the test.
|
||||
[uint32]$entry = 0x80001000L
|
||||
[uint32[]]$guestCallbacks = @(
|
||||
0x8012B830L, 0x801A0620L, 0x801A1ED8L, 0x801A961CL,
|
||||
0x801AADE0L, 0x801D8D30L, 0x801D9E94L, 0x8055531CL
|
||||
)
|
||||
$textSize = [int]($guestCallbacks[-1] - $entry + 4)
|
||||
$dataOffset = 0x100 + $textSize
|
||||
$dol = [byte[]]::new($dataOffset + 4)
|
||||
function Write-BigEndian32([int]$Offset, [uint32]$Value) {
|
||||
$dol[$Offset] = [byte](($Value -shr 24) -band 255)
|
||||
$dol[$Offset + 1] = [byte](($Value -shr 16) -band 255)
|
||||
$dol[$Offset + 2] = [byte](($Value -shr 8) -band 255)
|
||||
$dol[$Offset + 3] = [byte]($Value -band 255)
|
||||
}
|
||||
Write-BigEndian32 0x00 0x100 # text[0] file offset
|
||||
Write-BigEndian32 0x48 $entry # text[0] guest address
|
||||
Write-BigEndian32 0x90 $textSize # text[0] length (unreachable gaps are zero)
|
||||
Write-BigEndian32 0x1C $dataOffset # data[0] file offset
|
||||
Write-BigEndian32 0x64 0x80600000L # data[0] guest address
|
||||
Write-BigEndian32 0xAC 4 # data[0] length
|
||||
Write-BigEndian32 0xD8 0x80601000L # BSS address
|
||||
Write-BigEndian32 0xDC 32 # BSS length
|
||||
Write-BigEndian32 0xE0 $entry # entry point
|
||||
Write-BigEndian32 0x100 0x38600028 # li r3,40
|
||||
Write-BigEndian32 0x104 0x38630002 # addi r3,r3,2
|
||||
Write-BigEndian32 0x108 0x60000000 # nop
|
||||
Write-BigEndian32 0x10C 0x4E800020 # blr
|
||||
foreach ($address in $guestCallbacks) {
|
||||
Write-BigEndian32 ([int](0x100 + $address - $entry)) 0x4E800020
|
||||
}
|
||||
Write-BigEndian32 $dataOffset 0x12345678
|
||||
[IO.File]::WriteAllBytes((Join-Path $stage 'synthetic.dol'), $dol)
|
||||
$entryPoints = (@($entry) + $guestCallbacks | ForEach-Object { '0x{0:X8}' -f $_ }) -join ', '
|
||||
$functionMap = (@($entry) + $guestCallbacks | ForEach-Object { '{0:X8} func_{0:X8}' -f $_ }) -join "`n"
|
||||
[IO.File]::WriteAllText((Join-Path $stage 'synthetic-functions.txt'), $functionMap)
|
||||
$manifest = Join-Path $stage 'recomp.yml'
|
||||
[IO.File]::WriteAllText($manifest, @"
|
||||
schema_version: 1
|
||||
workspace_root: .
|
||||
project:
|
||||
id: ci-synthetic-dol
|
||||
display_name: CI Synthetic DOL
|
||||
memory:
|
||||
base: 0x80000000
|
||||
size: 0x01800000
|
||||
sda_base: 0x80600000
|
||||
sda2_base: 0x80600000
|
||||
inputs:
|
||||
dol:
|
||||
path: synthetic.dol
|
||||
translation:
|
||||
entry_points: [$entryPoints]
|
||||
function_map:
|
||||
path: synthetic-functions.txt
|
||||
allow_unsupported_instructions: false
|
||||
runtime:
|
||||
native_abi_directories: []
|
||||
native_registration_root: runtime/src
|
||||
output:
|
||||
root: generated
|
||||
"@)
|
||||
|
||||
$translatorProject = Join-Path $repoRoot 'translator/src/Translator.Cli/Translator.Cli.csproj'
|
||||
Invoke-Checked $dotnet @('build', $translatorProject, '-c', 'Release', '--disable-build-servers') 'Building the translator'
|
||||
$translator = Join-Path $repoRoot 'translator/src/Translator.Cli/bin/Release/net8.0/Translator.Cli.dll'
|
||||
$metadata = Join-Path $stage 'generated/base_translation_output.json'
|
||||
Invoke-Checked $dotnet @($translator, 'translate-recursive', '0x80001000', '--project', $manifest,
|
||||
'--output-metadata', $metadata, '--threads', "$Parallel") `
|
||||
'Translating the synthetic DOL'
|
||||
# Function-map seeds can be skipped by discovery; do not accept a partial fixture.
|
||||
$translated = Get-Content -LiteralPath $metadata -Raw | ConvertFrom-Json
|
||||
foreach ($address in @($entry) + $guestCallbacks) {
|
||||
if ($address -notin $translated.functions.entryPoint) {
|
||||
throw ('Synthetic function 0x{0:X8} was not translated.' -f $address)
|
||||
}
|
||||
}
|
||||
Invoke-Checked $dotnet @($translator, 'generate-data-init', '--project', $manifest) 'Generating synthetic data and runtime configuration'
|
||||
Invoke-Checked $dotnet @($translator, 'emit-build-shards', '--project', $manifest) 'Emitting the production build graph'
|
||||
|
||||
$nativeBuild = Join-Path $stage 'native-build'
|
||||
$oldPath = $env:PATH
|
||||
try {
|
||||
$env:PATH = Get-MkwToolchainPath $portableTools
|
||||
$configure = Get-MkwNativeConfigureArguments -SourceDirectory (Join-Path $stage 'runtime') -BuildDirectory $nativeBuild `
|
||||
-Ninja $ninja -CCompiler (Join-Path $compilerBin 'x86_64-w64-mingw32-clang.exe') `
|
||||
-CxxCompiler (Join-Path $compilerBin 'x86_64-w64-mingw32-clang++.exe') `
|
||||
-ResourceCompiler (Join-Path $compilerBin 'x86_64-w64-mingw32-windres.exe') `
|
||||
-DependenciesDirectory $dependencies -AdditionalArguments @('-DMKW_BUILD_PRODUCTS=ON')
|
||||
Invoke-Checked $cmake $configure 'Configuring the production Windows runtime' `
|
||||
-WaitForProcessTree $false
|
||||
Invoke-Checked $cmake @('--build', $nativeBuild, '--target', 'WiiCompiled', '--parallel', "$Parallel") `
|
||||
'Compiling and linking the synthetic product with the full runtime' `
|
||||
-WaitForProcessTree $false
|
||||
Assert-File (Join-Path $nativeBuild 'WiiCompiled.exe') 'Linked synthetic product'
|
||||
} finally {
|
||||
$env:PATH = $oldPath
|
||||
}
|
||||
Write-Host 'Synthetic recompilation passed (translation, data generation, runtime compilation, and product link).'
|
||||
@@ -6,7 +6,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>WiiCompiled.Setup.Common.Cli</RootNamespace>
|
||||
<AssemblyName>WiiCompiled.Setup.Common.Cli</AssemblyName>
|
||||
<Version>0.2.22</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Packaging-time helper: resolves (downloading if needed) the nodtool binary bundled by build-appimage.sh and Build-Installer.ps1</Description>
|
||||
|
||||
@@ -24,7 +24,7 @@ public static class RetroWfcPayload
|
||||
private static readonly TimeSpan RetroWfcDownloadTimeout = TimeSpan.FromSeconds(30);
|
||||
private static readonly TimeSpan RetroWfcRetryDelay = TimeSpan.FromSeconds(1);
|
||||
|
||||
public const string CurrentRetroWfcPayloadUri = "http://nas.play.rwfc.net/payload?g=RMCPD00";
|
||||
public const string CurrentRetroWfcPayloadUri = "https://rwfc.net/api/wfc/payload?g=RMCPD00";
|
||||
private static readonly string RetroWfcOfflinePayloadFile =
|
||||
Path.Combine("binary", "payload.RMCPD00.bin");
|
||||
|
||||
@@ -53,9 +53,22 @@ public static class RetroWfcPayload
|
||||
|
||||
var root = Path.GetFullPath(stagedDirectory);
|
||||
var payload = Path.Combine(root, RetroWfcOfflinePayloadFile);
|
||||
if (!File.Exists(payload))
|
||||
try
|
||||
{
|
||||
if ((File.GetAttributes(payload) & FileAttributes.Directory) != 0)
|
||||
throw new InvalidDataException(
|
||||
"The staged Retro-WFC payload directory does not contain binary\\payload.RMCPD00.bin.");
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
"The staged Retro-WFC payload directory does not contain binary\\payload.RMCPD00.bin.");
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
"The staged Retro-WFC payload directory does not contain binary\\payload.RMCPD00.bin.");
|
||||
}
|
||||
ValidateRetroWfcPayloadFile(payload, signingKey);
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>WiiCompiled.Setup.Common</RootNamespace>
|
||||
<AssemblyName>WiiCompiled.Setup.Common</AssemblyName>
|
||||
<Version>0.2.22</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Shared nodtool/Retro-WFC-payload logic used by both the Windows and Linux installers</Description>
|
||||
|
||||
@@ -12,7 +12,10 @@ internal static class BuildRunner
|
||||
public static async Task RunAsync(
|
||||
string workspace, string profile, string outputDir, string? baseOutputDir,
|
||||
string? retroDir, string? retroWfcOfflineDir, bool skipRetroWfcPayload,
|
||||
bool forceCleanBuild, string? translatorBin, IInstallReporter reporter, CancellationToken cancellationToken)
|
||||
bool forceCleanBuild, string? translatorBin, string? ccBin, string? cxxBin, string? fuseLd,
|
||||
string? cmakeBin, string? ninjaBin, string? nativePrebuiltDir, string? sysroot,
|
||||
IInstallReporter reporter,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var script = Path.Combine(workspace, "Launcher", "local-build.sh");
|
||||
if (!File.Exists(script)) throw new FileNotFoundException("local-build.sh is missing", script);
|
||||
@@ -47,6 +50,38 @@ internal static class BuildRunner
|
||||
{
|
||||
startInfo.ArgumentList.Add("--translator-bin"); startInfo.ArgumentList.Add(translatorBin);
|
||||
}
|
||||
// Forwarded by AppRun so the AppImage's bundled clang/lld (see prepare-portable-clang.sh)
|
||||
// is used instead of local-build.sh's own default of whatever clang is on $PATH.
|
||||
if (!string.IsNullOrEmpty(ccBin))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--cc"); startInfo.ArgumentList.Add(ccBin);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(cxxBin))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--cxx"); startInfo.ArgumentList.Add(cxxBin);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(fuseLd))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--fuse-ld"); startInfo.ArgumentList.Add(fuseLd);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(cmakeBin))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--cmake"); startInfo.ArgumentList.Add(cmakeBin);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(ninjaBin))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--ninja"); startInfo.ArgumentList.Add(ninjaBin);
|
||||
}
|
||||
// Forwarded by AppRun so the AppImage's bundled precompiled aurora/third-party package (see
|
||||
// Prepare-NativePrebuilt.sh) is used instead of local-build.sh compiling aurora-main itself.
|
||||
if (!string.IsNullOrEmpty(nativePrebuiltDir))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--native-prebuilt-dir"); startInfo.ArgumentList.Add(nativePrebuiltDir);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(sysroot))
|
||||
{
|
||||
startInfo.ArgumentList.Add("--sysroot"); startInfo.ArgumentList.Add(sysroot);
|
||||
}
|
||||
|
||||
using var process = new Process { StartInfo = startInfo };
|
||||
var window = new BuildProgressWindow(reporter, InstallStages.Build, start: 6, end: 96);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace WiiCompiled.Setup.Linux;
|
||||
|
||||
internal static class ProductInfo
|
||||
{
|
||||
public const string Name = "WiiCompiled";
|
||||
public const string Version = "0.2.22";
|
||||
public static readonly string Version =
|
||||
typeof(ProductInfo).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
|
||||
.InformationalVersion;
|
||||
}
|
||||
|
||||
/// <summary>One installed product's record inside install-state.json.</summary>
|
||||
|
||||
@@ -127,22 +127,52 @@ internal static class Program
|
||||
string? retroWfcOfflineDir = null;
|
||||
if (downloadPayload)
|
||||
{
|
||||
// Reused if a previous install already downloaded and it's still valid - matches
|
||||
// Windows's own reuse-if-valid behavior instead of re-downloading on every install.
|
||||
var cacheDir = Path.Combine(workspace, "generated", "retro-wfc-payload");
|
||||
reporter.Progress(InstallStages.Validate, "Preparing the Retro-WFC payload", 1);
|
||||
reporter.Progress(InstallStages.Validate,
|
||||
"Downloading the current Retro-WFC payload", 1);
|
||||
try
|
||||
{
|
||||
RetroWfcPayload.ValidateStagedRetroWfcPayloadDirectory(cacheDir);
|
||||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
// A valid signature authenticates a payload, but does not prove it is the latest
|
||||
// signed revision. Always ask the fixed endpoint for the current snapshot; the
|
||||
// downloader verifies it before atomically replacing the cache.
|
||||
await RetroWfcPayload.DownloadRetroWfcPayloadAsync(
|
||||
RetroWfcPayload.CurrentRetroWfcPayloadUri, cacheDir, token);
|
||||
}
|
||||
catch (Exception downloadFailure) when (!token.IsCancellationRequested &&
|
||||
downloadFailure is HttpRequestException or TimeoutException
|
||||
or IOException)
|
||||
{
|
||||
// Offline installs may continue with a previously authenticated snapshot. Do not
|
||||
// use this path for a newly downloaded payload that failed signature validation:
|
||||
// that must remain a hard failure instead of hiding possible endpoint tampering.
|
||||
try
|
||||
{
|
||||
RetroWfcPayload.ValidateStagedRetroWfcPayloadDirectory(cacheDir);
|
||||
}
|
||||
catch (Exception cacheFailure) when (cacheFailure is IOException or
|
||||
UnauthorizedAccessException or InvalidDataException)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"The current Retro-WFC payload could not be downloaded and no valid cached " +
|
||||
$"payload is available ({cacheFailure.Message.TrimEnd('.')}).", downloadFailure);
|
||||
}
|
||||
|
||||
reporter.Diagnostic(
|
||||
"The current Retro-WFC payload could not be downloaded; using the previously " +
|
||||
$"verified cached payload instead ({downloadFailure.Message.TrimEnd('.')}).");
|
||||
}
|
||||
retroWfcOfflineDir = cacheDir;
|
||||
}
|
||||
|
||||
var sysroot = flags.GetValueOrDefault("sysroot");
|
||||
// --sysroot explicitly provided (even as bare flag at end of argv, which ParseArgs
|
||||
// stores as null) must carry a path; omitting --sysroot entirely is fine (local-build.sh
|
||||
// adds -UCMAKE_SYSROOT to clear any stale cached value from a prior configure).
|
||||
if (flags.ContainsKey("sysroot") && string.IsNullOrWhiteSpace(sysroot))
|
||||
{
|
||||
throw new ArgumentException("--sysroot requires a non-empty directory path.");
|
||||
}
|
||||
|
||||
await BuildRunner.RunAsync(
|
||||
workspace, profile, installDir, baseInstallDir,
|
||||
retroDir,
|
||||
@@ -150,6 +180,13 @@ internal static class Program
|
||||
skipPayload,
|
||||
flags.ContainsKey("force-clean-build"),
|
||||
flags.GetValueOrDefault("translator-bin"),
|
||||
flags.GetValueOrDefault("cc"),
|
||||
flags.GetValueOrDefault("cxx"),
|
||||
flags.GetValueOrDefault("fuse-ld"),
|
||||
flags.GetValueOrDefault("cmake"),
|
||||
flags.GetValueOrDefault("ninja"),
|
||||
flags.GetValueOrDefault("native-prebuilt-dir"),
|
||||
sysroot,
|
||||
reporter, token);
|
||||
|
||||
reporter.Progress(InstallStages.Shortcuts, "Creating shortcuts", 98);
|
||||
@@ -317,7 +354,8 @@ internal static class Program
|
||||
install [--game ISO_PATH] [--install-dir DIR] [--retro-dir DIR
|
||||
{--download-retro-wfc-payload | --skip-retro-wfc-payload}]
|
||||
[--force-clean-build] [--translator-bin PATH] [--disc-tool-bin PATH]
|
||||
[--progress-json] [--workspace DIR]
|
||||
[--cc PATH] [--cxx PATH] [--fuse-ld NAME_OR_PATH] [--cmake PATH] [--ninja PATH]
|
||||
[--native-prebuilt-dir DIR] [--sysroot PATH] [--progress-json] [--workspace DIR]
|
||||
uninstall
|
||||
launch-base
|
||||
launch-retro
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>WiiCompiled.Setup.Linux</AssemblyName>
|
||||
<RootNamespace>WiiCompiled.Setup.Linux</RootNamespace>
|
||||
<Version>0.2.22</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Command-line installer and launcher for WiiCompiled on Linux</Description>
|
||||
|
||||
@@ -22,6 +22,9 @@ internal sealed class InstallerEngine
|
||||
var existing = new Installation(installDirectory);
|
||||
|
||||
PortableInstallHealing.HealMovedInstall(existing, _reporter);
|
||||
// Capture this before publishing anything. An existing installation may be repaired or
|
||||
// updated by this invocation, but those operations must not recreate the user's shortcuts.
|
||||
var firstInstall = !existing.IsPresent;
|
||||
var previousState = existing.ReadInstallState();
|
||||
using var scratch = Directory.Exists(installDirectory)
|
||||
? InstallScratchSpace.CreateInsideInstall(installDirectory, _reporter)
|
||||
@@ -139,7 +142,7 @@ internal sealed class InstallerEngine
|
||||
updatedState.RetroRewindInstalled, candidateRuntimeAssetsFingerprint,
|
||||
remainingCancellation);
|
||||
Publish(staging, installDirectory, canonicalRetroRoot, updatedState,
|
||||
releaseEntries, remainingCancellation);
|
||||
releaseEntries, remainingCancellation, createShortcuts: firstInstall);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,7 +164,8 @@ internal sealed class InstallerEngine
|
||||
|
||||
await PublishToolkitAndReconcileProductsAsync(existing, staging, workspace, manifest,
|
||||
previousState, options, canonicalRetroRoot, retroCompileInputs,
|
||||
publishGameAssets: reusableGameAssets is null, cancellationToken);
|
||||
publishGameAssets: reusableGameAssets is null, createShortcuts: firstInstall,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +190,7 @@ internal sealed class InstallerEngine
|
||||
string stagedWorkspace, PayloadManifest manifest, InstallState? previousState,
|
||||
InstallOptions options, string? canonicalRetroRoot,
|
||||
RetroRewindCompileInputs? retroCompileInputs,
|
||||
bool publishGameAssets, CancellationToken cancellationToken)
|
||||
bool publishGameAssets, bool createShortcuts, CancellationToken cancellationToken)
|
||||
{
|
||||
var installDirectory = existing.Root;
|
||||
|
||||
@@ -214,7 +218,8 @@ internal sealed class InstallerEngine
|
||||
if (publishGameAssets) AddComponent(entries, staging, installDirectory, "GameAssets");
|
||||
|
||||
Publish(staging, installDirectory, canonicalRetroRoot, state,
|
||||
entries, cancellationToken, progressPercent: 8, completionPercent: 10);
|
||||
entries, cancellationToken, progressPercent: 8, completionPercent: 10,
|
||||
createShortcuts: createShortcuts);
|
||||
|
||||
_reporter.Progress(InstallStages.BuildBase,
|
||||
"Producing the installed products with the published toolkit...", 11);
|
||||
@@ -277,7 +282,7 @@ internal sealed class InstallerEngine
|
||||
private void Publish(string staging, string installDirectory,
|
||||
string? canonicalRetroRoot, InstallState state,
|
||||
List<InstallTransactionEntry> entries, CancellationToken cancellationToken,
|
||||
int progressPercent = 95, int completionPercent = 99)
|
||||
int progressPercent = 95, int completionPercent = 99, bool createShortcuts = false)
|
||||
{
|
||||
entries.Add(InstallTransactionEntry.Directory(Path.Combine(staging, "licenses"),
|
||||
Path.Combine(installDirectory, "licenses")));
|
||||
@@ -322,7 +327,8 @@ internal sealed class InstallerEngine
|
||||
{
|
||||
ShellIntegration.RegisterUninstaller(installDirectory, state.RetroRewindInstalled);
|
||||
}
|
||||
ShellIntegration.CreateShortcuts(installDirectory);
|
||||
if (createShortcuts)
|
||||
ShellIntegration.CreateShortcuts(installDirectory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -110,8 +110,7 @@ internal sealed class ProductRepairService
|
||||
InputValidation.CurrentRetroWfcPayloadUri, payloadScratch, cancellationToken);
|
||||
}
|
||||
catch (Exception ex) when (!cancellationToken.IsCancellationRequested &&
|
||||
ex is HttpRequestException or IOException or InvalidDataException
|
||||
or InvalidOperationException or OperationCanceledException)
|
||||
ex is HttpRequestException or TimeoutException or IOException)
|
||||
{
|
||||
payloadSnapshot = RecoverInstalledRetroWfcPayload(toolkitFingerprint,
|
||||
Path.Combine(scratchRoot, "retro-wfc-payload-recovered"), ex, cancellationToken);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace WiiCompiled.Setup.Windows;
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static class Program
|
||||
@@ -121,7 +122,9 @@ internal static class PlatformChecks
|
||||
internal static class ProductInfo
|
||||
{
|
||||
public const string Name = "WiiCompiled";
|
||||
public const string Version = "0.2.25";
|
||||
public static readonly string Version =
|
||||
typeof(ProductInfo).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
|
||||
.InformationalVersion;
|
||||
|
||||
/// <summary>
|
||||
/// The setup executable is copied into the installation under this name. It is the launcher and
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<AssemblyName>WiiCompiled.Setup</AssemblyName>
|
||||
<RootNamespace>WiiCompiled.Setup.Windows</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Version>0.2.25</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Command-line installer and launcher for WiiCompiled</Description>
|
||||
|
||||
Regular → Executable
+147
-14
@@ -5,8 +5,12 @@
|
||||
# self-contained binaries, and `nodtool` (a prebuilt MIT/Apache-2.0 CLI from encounter/nod, see
|
||||
# NodToolProvider.cs) is downloaded and bundled too - AppRun passes --translator-bin and
|
||||
# --disc-tool-bin so local-build.sh/DiscTool.cs skip their from-source/download fallbacks entirely.
|
||||
# It still shells out to system clang/cmake/ninja - no C/C++ toolchain is bundled, matching
|
||||
# Launcher/local-build.sh's own remaining prerequisites.
|
||||
# A pruned native clang/lld/cmake/ninja toolchain (see prepare-portable-tools.sh) is bundled the
|
||||
# same way - AppRun passes --cc/--cxx/--fuse-ld/--cmake/--ninja so local-build.sh never has to find
|
||||
# a system compiler, CMake, or Ninja. It still shells out to system pkg-config and Vulkan headers,
|
||||
# matching Launcher/local-build.sh's own remaining prerequisites. A precompiled aurora +
|
||||
# third-party package (see Prepare-NativePrebuilt.sh) is bundled the same way too - AppRun passes
|
||||
# --native-prebuilt-dir so local-build.sh never compiles aurora-main from source at all.
|
||||
#
|
||||
# An AppImage mounts read-only, but local-build.sh writes generated/, native-build/, Assets/, etc.
|
||||
# into the workspace it's given. So AppRun (written below) copies the bundled workspace snapshot
|
||||
@@ -15,12 +19,58 @@
|
||||
# - generated/native-build/Assets/PulsarPacks live only in that writable cache and are never
|
||||
# touched by the sync, so local-build.sh's own incremental caching survives across runs and across
|
||||
# AppImage updates. translator/ isn't part of this snapshot at all: it's published as its own
|
||||
# self-contained binary (usr/bin/translator-cli) below and never needs a writable copy.
|
||||
# self-contained binary (usr/bin/translator-cli) below and never needs a writable copy. Neither
|
||||
# native-prebuilt/ nor the toolchain are copied into the cache either - both are large
|
||||
# (~90 MiB / ~500 MiB) and local-build.sh only ever reads from them - but AppRun does point
|
||||
# $CACHE/toolchain and $CACHE/native-prebuilt symlinks at the current mount on every single launch
|
||||
# (see AppRun's own comment): an AppImage's FUSE mount is at a fresh random /tmp/.mount_XXXXXX
|
||||
# every run, and CMake bakes whatever compiler/tool path it's given directly into each
|
||||
# build.ninja rule's command line, so referencing $HERE straight would change that command line -
|
||||
# and Ninja reruns any rule whose command line changed - forcing a full rebuild on every single
|
||||
# launch even though the compiler itself never actually changed. The symlink keeps the path
|
||||
# string CMake/Ninja see identical across runs while what it resolves to tracks the current mount
|
||||
# underneath.
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
workspace=$(cd "$script_dir/.." && pwd)
|
||||
|
||||
# `uname -m` reports the *kernel's* architecture, which can differ from userspace - an aarch64
|
||||
# kernel can run a 32-bit armhf userland (as shipped by 32-bit Raspberry Pi OS), same as an x86_64
|
||||
# kernel can run an i686 one. What matters here is which userspace binaries (dotnet, appimagetool)
|
||||
# will actually run, so this reads the ELF header of this script's own running bash interpreter -
|
||||
# real userspace - rather than trusting the kernel's self-report. /proc/$$/exe (not /proc/self/exe:
|
||||
# that would resolve inside the readlink subprocess below, to readlink itself, not to bash) is this
|
||||
# shell's own PID. EI_CLASS (byte 4: 1=32-bit, 2=64-bit) and e_machine (bytes 18-19: 3=EM_386,
|
||||
# 40=EM_ARM, 62=EM_X86_64, 183=EM_AARCH64) are read as plain little-endian bytes, which every
|
||||
# real-world x86/ARM Linux userland uses; ELF's big-endian encoding is a non-issue here since no
|
||||
# Linux distro ships a big-endian x86 or ARM userland.
|
||||
elf_exe=$(readlink -f "/proc/$$/exe")
|
||||
elf_class=$(od -An -t u1 -j 4 -N 1 "$elf_exe" | tr -d ' ')
|
||||
elf_machine_lo=$(od -An -t u1 -j 18 -N 1 "$elf_exe" | tr -d ' ')
|
||||
elf_machine_hi=$(od -An -t u1 -j 19 -N 1 "$elf_exe" | tr -d ' ')
|
||||
elf_machine=$(( elf_machine_hi * 256 + elf_machine_lo ))
|
||||
|
||||
# Mirrors the host-architecture detection NodToolProvider.cs already does (RuntimeInformation.
|
||||
# OSArchitecture) so this script's own dotnet RID and appimagetool selection agree with the
|
||||
# nodtool binary that same code path resolves below. local-build.sh needs no such mapping itself:
|
||||
# it just drives the native CMake configure, which already accepts x86_64 or aarch64 natively
|
||||
# (see runtime/CMakeLists.txt's CMAKE_SYSTEM_PROCESSOR check).
|
||||
case "$elf_class:$elf_machine" in
|
||||
2:62)
|
||||
dotnet_rid=linux-x64
|
||||
appimagetool_arch=x86_64
|
||||
;;
|
||||
2:183)
|
||||
dotnet_rid=linux-arm64
|
||||
appimagetool_arch=aarch64
|
||||
;;
|
||||
*)
|
||||
echo "build-appimage.sh: unsupported userspace architecture (ELF class $elf_class, machine $elf_machine) - WiiCompiled requires a 64-bit x86_64 or aarch64 userland" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
output_dir="$workspace/Launcher/dist"
|
||||
appimagetool_override=""
|
||||
|
||||
@@ -40,10 +90,10 @@ appdir="$workspace/Launcher/artifacts/appimage-build/AppDir"
|
||||
rm -rf "$appdir"
|
||||
mkdir -p "$appdir/usr/bin" "$appdir/workspace/Launcher"
|
||||
|
||||
echo "Publishing the installer (self-contained linux-x64)..."
|
||||
echo "Publishing the installer (self-contained $dotnet_rid)..."
|
||||
publish_tmp="$workspace/Launcher/artifacts/appimage-build/publish"
|
||||
rm -rf "$publish_tmp"
|
||||
dotnet publish "$workspace/Launcher/WiiCompiled.Setup.Linux" -c Release -r linux-x64 \
|
||||
dotnet publish "$workspace/Launcher/WiiCompiled.Setup.Linux" -c Release -r "$dotnet_rid" \
|
||||
--self-contained -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true \
|
||||
-o "$publish_tmp"
|
||||
cp "$publish_tmp/WiiCompiled.Setup.Linux" "$appdir/usr/bin/wiicompiled-setup"
|
||||
@@ -52,10 +102,10 @@ chmod +x "$appdir/usr/bin/wiicompiled-setup"
|
||||
# Published as a self-contained binary too, so an AppImage user never needs a `dotnet` SDK on
|
||||
# PATH at all - local-build.sh is told about it via --translator-bin and skips its own
|
||||
# dotnet-build-from-source step entirely (see local-build.sh's translator resolution branch).
|
||||
echo "Publishing the translator (self-contained linux-x64)..."
|
||||
echo "Publishing the translator (self-contained $dotnet_rid)..."
|
||||
translator_publish_tmp="$workspace/Launcher/artifacts/appimage-build/publish-translator"
|
||||
rm -rf "$translator_publish_tmp"
|
||||
dotnet publish "$workspace/translator/src/Translator.Cli" -c Release -r linux-x64 \
|
||||
dotnet publish "$workspace/translator/src/Translator.Cli" -c Release -r "$dotnet_rid" \
|
||||
--self-contained -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true \
|
||||
-o "$translator_publish_tmp"
|
||||
cp "$translator_publish_tmp/Translator.Cli" "$appdir/usr/bin/translator-cli"
|
||||
@@ -71,10 +121,54 @@ nodtool_path=$(dotnet run --project "$workspace/Launcher/WiiCompiled.Setup.Commo
|
||||
cp "$nodtool_path" "$appdir/usr/bin/nodtool"
|
||||
chmod +x "$appdir/usr/bin/nodtool"
|
||||
|
||||
echo "Preparing the portable clang/lld/cmake/ninja toolchain ($appimagetool_arch)..."
|
||||
bash "$script_dir/prepare-portable-tools.sh" --arch "$appimagetool_arch"
|
||||
mkdir -p "$appdir/usr/toolchain"
|
||||
cp -a "$workspace/Launcher/artifacts/portable-tools/toolchain-$appimagetool_arch"/. "$appdir/usr/toolchain/"
|
||||
|
||||
# Precompiled aurora + third-party package (see Prepare-NativePrebuilt.sh) so a user's own
|
||||
# local-build.sh never has to compile aurora itself (~43% of local build CPU time). Re-harvesting
|
||||
# recompiles the aurora/Crypto++/mbed TLS closure with the toolchain above, so this is skipped unless
|
||||
# --print-fingerprint-only (a fast, build-free check) says the existing package no longer matches
|
||||
# the current compiler, flags, source trees or mbed TLS pin.
|
||||
native_prebuilt_dir="$workspace/Launcher/artifacts/native-prebuilt-$appimagetool_arch"
|
||||
echo "Checking whether the precompiled aurora + third-party package ($appimagetool_arch) is current..."
|
||||
current_fingerprint=$(bash "$script_dir/Prepare-NativePrebuilt.sh" --arch "$appimagetool_arch" --print-fingerprint-only)
|
||||
package_current=0
|
||||
if [[ -f "$native_prebuilt_dir/provenance.json" ]]; then
|
||||
package_current=$(CURRENT_FINGERPRINT="$current_fingerprint" python3 - "$native_prebuilt_dir/provenance.json" <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
provenance = json.load(open(sys.argv[1], encoding="utf-8"))
|
||||
current = dict(line.split("=", 1) for line in os.environ["CURRENT_FINGERPRINT"].splitlines() if line)
|
||||
fields = {
|
||||
"compiler_sha256": "CompilerSha256",
|
||||
"flag_fingerprint": "FlagFingerprint",
|
||||
"aurora_fingerprint": "AuroraSourceFingerprint",
|
||||
"third_party_fingerprint": "ThirdPartySourceFingerprint",
|
||||
"mbedtls_fingerprint": "MbedTlsFingerprint",
|
||||
}
|
||||
print(1 if all(provenance.get(v) == current.get(k) for k, v in fields.items()) else 0)
|
||||
PY
|
||||
)
|
||||
fi
|
||||
if [[ "$package_current" == "1" ]]; then
|
||||
echo "Native prebuilt package is current; reusing $native_prebuilt_dir"
|
||||
else
|
||||
echo "Native prebuilt package is missing or stale; harvesting a fresh one (compiles aurora once, can take a while)..."
|
||||
bash "$script_dir/Prepare-NativePrebuilt.sh" --arch "$appimagetool_arch"
|
||||
fi
|
||||
mkdir -p "$appdir/native-prebuilt"
|
||||
cp -a "$native_prebuilt_dir/." "$appdir/native-prebuilt/"
|
||||
|
||||
echo "Staging the bundled workspace snapshot..."
|
||||
for dir in runtime aurora-main projects; do
|
||||
cp -r "$workspace/$dir" "$appdir/workspace/$dir"
|
||||
done
|
||||
# Ship source bytes, never submodule checkout pointers or embedded Git databases.
|
||||
find "$appdir/workspace" -name .git -prune -exec rm -rf {} +
|
||||
# Mirrors Build-Installer.ps1's own staging exclusions exactly: aurora-main/extern/CMakeLists.txt
|
||||
# is the real FetchContent driver and must ship, but any already-fetched dependency *subdirectory*
|
||||
# a developer's local checkout accumulated under extern/ is stale/large build output, not a
|
||||
@@ -84,8 +178,21 @@ find "$appdir/workspace/aurora-main/extern" -mindepth 1 -maxdepth 1 -type d -exe
|
||||
rm -rf "$appdir/workspace/runtime/build"
|
||||
cp "$workspace/Launcher/local-build.sh" "$appdir/workspace/Launcher/local-build.sh"
|
||||
|
||||
# AppRun re-syncs runtime/aurora-main/projects/local-build.sh into the writable cache only when
|
||||
# this changes, so it must change whenever any of those bundled paths actually did - a bare commit
|
||||
# hash gets this wrong for an uncommitted change (verified directly: rebuilding after editing
|
||||
# local-build.sh with no commit produced the same hash as the stale cache, so AppRun kept serving
|
||||
# the old script and failed on a flag that didn't exist yet). `git status --porcelain` catches both
|
||||
# modified tracked files and new untracked ones; appending a fresh timestamp when it's non-empty
|
||||
# guarantees this never matches a previous build's stamp, forcing a resync every time the tree is
|
||||
# dirty. A clean tree (a real tagged release) keeps the stable commit-hash behavior, so identical
|
||||
# reruns of the same release AppImage don't resync needlessly.
|
||||
if git -C "$workspace" rev-parse HEAD >/dev/null 2>&1; then
|
||||
git -C "$workspace" rev-parse HEAD > "$appdir/workspace/.bundle-version"
|
||||
version=$(git -C "$workspace" rev-parse HEAD)
|
||||
if [[ -n "$(git -C "$workspace" status --porcelain 2>/dev/null)" ]]; then
|
||||
version="$version-dirty-$(date -u +%s)"
|
||||
fi
|
||||
echo "$version" > "$appdir/workspace/.bundle-version"
|
||||
else
|
||||
date -u +%s > "$appdir/workspace/.bundle-version"
|
||||
fi
|
||||
@@ -96,6 +203,7 @@ cat > "$appdir/AppRun" <<'APPRUN'
|
||||
set -euo pipefail
|
||||
HERE="$(dirname "$(readlink -f "$0")")"
|
||||
CACHE="${XDG_DATA_HOME:-$HOME/.local/share}/WiiCompiled/workspace"
|
||||
mkdir -p "$CACHE"
|
||||
if [ ! -f "$CACHE/.bundle-version" ] || \
|
||||
[ "$(cat "$HERE/workspace/.bundle-version")" != "$(cat "$CACHE/.bundle-version")" ]; then
|
||||
mkdir -p "$CACHE/Launcher"
|
||||
@@ -106,9 +214,31 @@ if [ ! -f "$CACHE/.bundle-version" ] || \
|
||||
cp "$HERE/workspace/Launcher/local-build.sh" "$CACHE/Launcher/local-build.sh"
|
||||
cp "$HERE/workspace/.bundle-version" "$CACHE/.bundle-version"
|
||||
fi
|
||||
# toolchain/ and native-prebuilt/ are NOT copied into the cache (they're large - ~500 MiB /
|
||||
# ~90 MiB - and local-build.sh only ever reads from them): $CACHE/toolchain and
|
||||
# $CACHE/native-prebuilt are symlinks re-pointed at the current mount on every single launch
|
||||
# (unconditionally, not gated on .bundle-version above, since the mount path itself - unlike the
|
||||
# bundled content - changes every run regardless). CMake bakes a compiler/tool path directly into
|
||||
# each build.ninja rule's command line and Ninja reruns any rule whose command line changed since
|
||||
# the last build (verified directly) - an AppImage's FUSE mount is at a fresh random
|
||||
# /tmp/.mount_XXXXXX every launch, so referencing $HERE straight would change that command line,
|
||||
# and therefore force a full rebuild, on every single run even though the compiler itself never
|
||||
# actually changed. A symlink keeps the *path string* CMake/Ninja see identical across runs while
|
||||
# what it resolves to tracks the current mount underneath (verified directly: CMake records
|
||||
# whatever path it's given as-is - including a symlink - without resolving it first).
|
||||
[ -L "$CACHE/toolchain" ] || rm -rf "$CACHE/toolchain"
|
||||
[ -L "$CACHE/native-prebuilt" ] || rm -rf "$CACHE/native-prebuilt"
|
||||
ln -sfn "$HERE/usr/toolchain" "$CACHE/toolchain"
|
||||
ln -sfn "$HERE/native-prebuilt" "$CACHE/native-prebuilt"
|
||||
exec "$HERE/usr/bin/wiicompiled-setup" --workspace "$CACHE" \
|
||||
--translator-bin "$HERE/usr/bin/translator-cli" \
|
||||
--disc-tool-bin "$HERE/usr/bin/nodtool" "$@"
|
||||
--disc-tool-bin "$HERE/usr/bin/nodtool" \
|
||||
--cc "$CACHE/toolchain/bin/clang" \
|
||||
--cxx "$CACHE/toolchain/bin/clang++" \
|
||||
--fuse-ld lld \
|
||||
--cmake "$CACHE/toolchain/bin/cmake" \
|
||||
--ninja "$CACHE/toolchain/bin/ninja" \
|
||||
--native-prebuilt-dir "$CACHE/native-prebuilt" "$@"
|
||||
APPRUN
|
||||
chmod +x "$appdir/AppRun"
|
||||
|
||||
@@ -155,11 +285,13 @@ PY
|
||||
echo "Resolving appimagetool..."
|
||||
appimagetool="$appimagetool_override"
|
||||
if [[ -z "$appimagetool" ]]; then
|
||||
appimagetool="$workspace/Launcher/artifacts/appimagetool"
|
||||
# Cache path is arch-tagged so a workspace shared or synced across an x86_64 and an aarch64
|
||||
# machine never picks up the wrong architecture's cached binary.
|
||||
appimagetool="$workspace/Launcher/artifacts/appimagetool-$appimagetool_arch"
|
||||
if [[ ! -x "$appimagetool" ]]; then
|
||||
echo "Downloading appimagetool..."
|
||||
echo "Downloading appimagetool ($appimagetool_arch)..."
|
||||
mkdir -p "$(dirname "$appimagetool")"
|
||||
curl -fsSL "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" \
|
||||
curl -fsSL "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$appimagetool_arch.AppImage" \
|
||||
-o "$appimagetool"
|
||||
chmod +x "$appimagetool"
|
||||
fi
|
||||
@@ -169,5 +301,6 @@ mkdir -p "$output_dir"
|
||||
echo "Packaging..."
|
||||
# appimagetool detects the target architecture from the first ELF executable it finds in the
|
||||
# AppDir; AppRun here is a shell script, not ELF, so ARCH must be set explicitly.
|
||||
ARCH=x86_64 "$appimagetool" "$appdir" "$output_dir/WiiCompiled-Setup-x86_64.AppImage"
|
||||
echo "Built: $output_dir/WiiCompiled-Setup-x86_64.AppImage"
|
||||
output_name="WiiCompiled-Setup-$appimagetool_arch.AppImage"
|
||||
ARCH="$appimagetool_arch" "$appimagetool" "$appdir" "$output_dir/$output_name"
|
||||
echo "Built: $output_dir/$output_name"
|
||||
|
||||
Executable
+139
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
# Native macOS build automation: optionally extract -> translate -> compile -> publish .app.
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
default_workspace=$(cd "$script_dir/.." && pwd)
|
||||
|
||||
fail() { printf 'local-build-macos.command: error: %s\n' "$*" >&2; exit 1; }
|
||||
step() { printf 'MKWCBUILD:STEP:%s %s\n' "$1" "$2"; }
|
||||
assert_file() { [[ -f "$1" ]] || fail "$2 is missing: $1"; }
|
||||
sha256() { shasum -a 256 "$1" | awk '{ print $1 }'; }
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: local-build-macos.command --output-dir DIR [options]
|
||||
|
||||
--workspace DIR Repository root (default: this script's parent directory)
|
||||
--profile {base|retro-rewind|both} Product to build (default: base)
|
||||
--output-dir DIR Output .app directory (required; Retro Rewind for both)
|
||||
--base-output-dir DIR Base .app directory (required with --profile both)
|
||||
--game IMAGE --nodtool PATH Extract and verify a clean PAL RMCP01 disc image first
|
||||
--retro-rewind-package-dir DIR RetroRewind6 directory (required for Retro Rewind)
|
||||
--retro-wfc-offline-dir DIR Directory containing binary/payload.RMCPD00.bin
|
||||
--skip-retro-wfc-payload Build Retro Rewind without the shared Retro-WFC payload
|
||||
--force-clean-build Delete local generated and native-build-macos caches
|
||||
--parallel N Pin translation and build parallelism
|
||||
--cmake PATH --ninja PATH Override build tools
|
||||
--dotnet PATH Override dotnet
|
||||
--translator-bin PATH Use a self-contained Translator.Cli executable
|
||||
EOF
|
||||
}
|
||||
|
||||
workspace="$default_workspace"; profile=base; output_dir=""; base_output_dir=""
|
||||
game=""; nodtool=""; retro_root=""; retro_wfc=""; skip_retro_wfc=0; force_clean=0
|
||||
parallel=0; cmake_bin=cmake; ninja_bin=ninja; dotnet_bin=dotnet; translator_bin=""
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--workspace) workspace=${2:-}; shift 2 ;;
|
||||
--profile) profile=${2:-}; shift 2 ;;
|
||||
--output-dir) output_dir=${2:-}; shift 2 ;;
|
||||
--base-output-dir) base_output_dir=${2:-}; shift 2 ;;
|
||||
--game) game=${2:-}; shift 2 ;;
|
||||
--nodtool) nodtool=${2:-}; shift 2 ;;
|
||||
--retro-rewind-package-dir) retro_root=${2:-}; shift 2 ;;
|
||||
--retro-wfc-offline-dir) retro_wfc=${2:-}; shift 2 ;;
|
||||
--skip-retro-wfc-payload) skip_retro_wfc=1; shift ;;
|
||||
--force-clean-build) force_clean=1; shift ;;
|
||||
--parallel) parallel=${2:-}; shift 2 ;;
|
||||
--cmake) cmake_bin=${2:-}; shift 2 ;;
|
||||
--ninja) ninja_bin=${2:-}; shift 2 ;;
|
||||
--dotnet) dotnet_bin=${2:-}; shift 2 ;;
|
||||
--translator-bin) translator_bin=${2:-}; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ $(uname -s) == Darwin ]] || fail 'this build script is for macOS only'
|
||||
[[ $(uname -m) == arm64 ]] || fail 'the current macOS product target is Apple Silicon only'
|
||||
workspace=$(cd "$workspace" && pwd)
|
||||
[[ -n "$output_dir" ]] || fail '--output-dir is required'
|
||||
case "$profile" in base|retro-rewind|both) ;; *) fail '--profile must be base, retro-rewind, or both' ;; esac
|
||||
builds_retro=0; [[ "$profile" != base ]] && builds_retro=1
|
||||
if [[ "$profile" == both && -z "$base_output_dir" ]]; then fail '--base-output-dir is required with --profile both'; fi
|
||||
if [[ "$profile" != both && -n "$base_output_dir" ]]; then fail '--base-output-dir is valid only with --profile both'; fi
|
||||
if [[ -n "$game" || -n "$nodtool" ]]; then [[ -n "$game" && -n "$nodtool" ]] || fail '--game and --nodtool must be supplied together'; fi
|
||||
if (( builds_retro )); then
|
||||
[[ -n "$retro_root" ]] || fail '--retro-rewind-package-dir is required for Retro Rewind'
|
||||
[[ -n "$retro_wfc" ]] && (( skip_retro_wfc )) && fail 'choose only one Retro-WFC mode'
|
||||
[[ -n "$retro_wfc" || $skip_retro_wfc -eq 1 ]] || fail 'choose a Retro-WFC payload directory or --skip-retro-wfc-payload'
|
||||
fi
|
||||
for tool in "$cmake_bin" "$ninja_bin" clang clang++ shasum; do command -v "$tool" >/dev/null || fail "required tool not found: $tool"; done
|
||||
|
||||
project="$workspace/projects/mkwii/recomp.yml"; assets="$workspace/Assets"; generated="$workspace/generated"
|
||||
functions="$generated/functions"; metadata="$generated/base_translation_output.json"; manifest_dir="$workspace/build/base"
|
||||
manifest="$manifest_dir/mkwii_base_manifest.json"; shards="$generated/build_shards"; native_build="$workspace/native-build-macos"
|
||||
assert_file "$project" 'translation project'
|
||||
if [[ -n "$game" ]]; then "$script_dir/macos/extract-disc.command" --game "$game" --assets-dir "$assets" --nodtool "$nodtool"; fi
|
||||
assert_file "$assets/main.dol" 'extracted main.dol'; assert_file "$assets/StaticR.rel" 'extracted StaticR.rel'
|
||||
|
||||
if (( force_clean )); then
|
||||
step force-clean 'Discarding translation and native build caches'
|
||||
rm -rf "$generated" "$manifest_dir" "$native_build"
|
||||
fi
|
||||
|
||||
if [[ -n "$translator_bin" ]]; then
|
||||
assert_file "$translator_bin" 'Translator.Cli executable'
|
||||
translator() { "$translator_bin" "$@"; }
|
||||
else
|
||||
command -v "$dotnet_bin" >/dev/null || fail "required tool not found: $dotnet_bin"
|
||||
translator_dll="$workspace/translator/src/Translator.Cli/bin/Release/net8.0/Translator.Cli.dll"
|
||||
if [[ ! -f "$translator_dll" ]]; then
|
||||
step build-translator 'Building the translator'
|
||||
"$dotnet_bin" build "$workspace/translator/src/Translator.Cli/Translator.Cli.csproj" -c Release
|
||||
fi
|
||||
translator() { "$dotnet_bin" "$translator_dll" "$@"; }
|
||||
fi
|
||||
|
||||
entry_point=$(awk '/^translation:/{inside=1} inside && /^[[:space:]]*-[[:space:]]*0[xX][0-9a-fA-F]+[[:space:]]*$/{gsub(/^[[:space:]]*-[[:space:]]*/, ""); print; exit}' "$project")
|
||||
[[ -n "$entry_point" ]] || fail 'could not find the translation entry point'
|
||||
cpu=$(sysctl -n hw.ncpu); mem_gib=$(( $(sysctl -n hw.memsize) / 1024 / 1024 / 1024 )); (( mem_gib < 1 )) && mem_gib=1
|
||||
if (( parallel > 0 )); then translator_threads=$parallel; translated_jobs=$parallel; global_jobs=$parallel
|
||||
else translator_threads=$(( cpu < 16 ? cpu : 16 )); translated_jobs=$(( cpu < mem_gib / 2 ? cpu : mem_gib / 2 )); (( translated_jobs < 1 )) && translated_jobs=1; global_jobs=$cpu; fi
|
||||
|
||||
if (( builds_retro )); then
|
||||
retro_root=$(cd "$retro_root" && pwd)
|
||||
if [[ ! -f "$retro_root/Binaries/Code.pul" && -f "$retro_root/RetroRewind6/Binaries/Code.pul" ]]; then
|
||||
retro_root="$retro_root/RetroRewind6"
|
||||
fi
|
||||
assert_file "$retro_root/Binaries/Code.pul" 'Retro Rewind Code.pul'
|
||||
stage="$workspace/PulsarPacks/completed/RetroRewind/RetroRewind6/Binaries"
|
||||
mkdir -p "$stage"
|
||||
if [[ ! "$retro_root/Binaries/Code.pul" -ef "$stage/Code.pul" ]]; then
|
||||
cp -f "$retro_root/Binaries/Code.pul" "$stage/Code.pul"
|
||||
fi
|
||||
fi
|
||||
|
||||
step translate-base 'Translating the user-owned base game'
|
||||
rm -rf "$functions" "$metadata" "$manifest_dir"; mkdir -p "$functions" "$manifest_dir"
|
||||
translator translate-recursive "$entry_point" --project "$project" --outdir "$functions" --output-metadata "$metadata" --production-source-bundle "$generated/base_translation_sources.bin" --no-function-files --prune-stale --threads "$translator_threads"
|
||||
step emit-base-manifest 'Creating the local base translation manifest'
|
||||
translator emit-base-manifest --project "$project" --out "$manifest_dir" --functions-dir "$functions" --translation-output-metadata "$metadata" --region P
|
||||
if (( builds_retro )); then
|
||||
mod_out="$workspace/build/mods/retro_rewind_full_cpp"; args=(translate-mod --project "$project" --profile retro-rewind --base-manifest "$manifest" --base-translation-output-metadata "$metadata" --code-pul "$retro_root/Binaries/Code.pul" --mod-root "$retro_root" --mod-name 'Retro Rewind' --region P --out "$mod_out" --prefer-cached-inputs --emit-cpp --threads "$translator_threads")
|
||||
if (( skip_retro_wfc )); then args+=(--skip-retro-wfc); else offline_payload="$retro_wfc/binary/payload.RMCPD00.bin"; assert_file "$offline_payload" 'Offline Retro-WFC payload'; args+=(--retro-wfc-payload "$offline_payload"); fi
|
||||
step translate-mod 'Translating Retro Rewind'; translator "${args[@]}"
|
||||
fi
|
||||
step generate-data-init 'Generating local game data initialization'; translator generate-data-init --project "$project"
|
||||
args=(emit-build-shards --project "$project" --base-metadata "$metadata" --base-functions-dir "$functions" --native-source-dir "$workspace/runtime/src" --out "$shards")
|
||||
if (( builds_retro )); then args+=(--resolved-profile "$mod_out/resolved_dispatch_profile.json" --retro-cpp-dir "$mod_out/cpp"); fi
|
||||
step emit-build-shards 'Preparing native build shards'; translator "${args[@]}"
|
||||
|
||||
step configure-native 'Configuring the native toolchain'
|
||||
"$cmake_bin" -S "$workspace/runtime" -B "$native_build" -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_MAKE_PROGRAM="$ninja_bin" -DMKW_TRANSLATED_COMPILE_JOBS="$translated_jobs"
|
||||
targets=(); [[ "$profile" != retro-rewind ]] && targets+=(WiiCompiled); [[ "$profile" != base ]] && targets+=(RetroRewind)
|
||||
step compile "Compiling ${targets[*]} locally"; "$cmake_bin" --build "$native_build" --target "${targets[@]}" --parallel "$global_jobs"
|
||||
if [[ "$profile" != retro-rewind ]]; then "$script_dir/macos/publish-app.command" --build-dir "$native_build" --product WiiCompiled --output-dir "${base_output_dir:-$output_dir}"; fi
|
||||
if (( builds_retro )); then "$script_dir/macos/publish-app.command" --build-dir "$native_build" --product RetroRewind --output-dir "$output_dir"; fi
|
||||
printf 'MKWCBUILD:OUTPUT=%s\n' "$output_dir"
|
||||
+111
-12
@@ -2,11 +2,12 @@
|
||||
# Linux build automation: translate -> emit build shards -> configure -> compile -> publish.
|
||||
#
|
||||
# This is the native-Linux counterpart to Launcher/LocalBuild.ps1. It is a from-scratch parallel
|
||||
# implementation, not a port of NativeBuildFlags.ps1: that file's canonical flags and
|
||||
# prebuilt-package fingerprinting exist only for the Windows/mingw toolchain (a precompiled
|
||||
# aurora/third-party package, offline pinned dependencies) that this script does not build.
|
||||
# Linux always builds aurora from source, letting its own CMake auto-detect Vulkan + vendor
|
||||
# SDL3/Dawn via FetchContent - the same configuration already verified working by hand.
|
||||
# implementation, not a port of NativeBuildFlags.ps1: that file's canonical flags exist only for
|
||||
# the Windows/mingw toolchain's offline pinned dependencies, which this script does not use.
|
||||
# Without --native-prebuilt-dir, aurora is built from source, letting its own CMake auto-detect
|
||||
# Vulkan + vendor SDL3/Dawn via FetchContent - the same configuration already verified working by
|
||||
# hand. With it, aurora is not compiled at all - see Launcher/Prepare-NativePrebuilt.sh, which
|
||||
# harvests exactly that package (the Linux counterpart to Prepare-NativePrebuilt.ps1).
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -62,6 +63,9 @@ ninja_override=""
|
||||
dotnet_override=""
|
||||
translator_dll_override=""
|
||||
translator_bin_override=""
|
||||
fuse_ld_override=""
|
||||
native_prebuilt_dir=""
|
||||
sysroot=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
@@ -77,10 +81,15 @@ Usage: local-build.sh --output-dir DIR [options]
|
||||
--force-clean-build Discard every translation/build cache first
|
||||
--parallel N Pin translator threads, translated-shard job pool, and Ninja parallelism to N
|
||||
--cc PATH / --cxx PATH C/C++ compiler (default: cc/c++ on PATH)
|
||||
--fuse-ld NAME_OR_PATH Linker passed to clang as -fuse-ld=NAME_OR_PATH (default: clang's own default linker)
|
||||
--cmake PATH / --ninja PATH Build tools (default: on PATH)
|
||||
--dotnet PATH dotnet executable (default: on PATH)
|
||||
--translator-dll PATH Pre-built Translator.Cli.dll (skips building the translator; still needs --dotnet to run it)
|
||||
--translator-bin PATH Self-contained Translator.Cli executable (skips building AND needs no dotnet at all)
|
||||
--native-prebuilt-dir DIR Precompiled aurora/third-party package (see Prepare-NativePrebuilt.sh);
|
||||
skips compiling aurora-main from source entirely
|
||||
--sysroot PATH Passed to CMake as -DCMAKE_SYSROOT: where the compiler resolves
|
||||
standard headers/startup files
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -97,11 +106,14 @@ while [[ $# -gt 0 ]]; do
|
||||
--parallel) parallel_override=$2; shift 2 ;;
|
||||
--cc) cc_override=$2; shift 2 ;;
|
||||
--cxx) cxx_override=$2; shift 2 ;;
|
||||
--fuse-ld) fuse_ld_override=$2; shift 2 ;;
|
||||
--cmake) cmake_override=$2; shift 2 ;;
|
||||
--ninja) ninja_override=$2; shift 2 ;;
|
||||
--dotnet) dotnet_override=$2; shift 2 ;;
|
||||
--translator-dll) translator_dll_override=$2; shift 2 ;;
|
||||
--translator-bin) translator_bin_override=$2; shift 2 ;;
|
||||
--native-prebuilt-dir) native_prebuilt_dir=$2; shift 2 ;;
|
||||
--sysroot) sysroot=$2; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown argument: $1" ;;
|
||||
esac
|
||||
@@ -157,6 +169,10 @@ require_command "$ninja_bin" ninja
|
||||
require_command "$cc_bin" cc
|
||||
require_command "$cxx_bin" cxx
|
||||
|
||||
if [[ -n "$native_prebuilt_dir" ]]; then
|
||||
assert_file "$native_prebuilt_dir/native_prebuilt.cmake" "Native prebuilt package"
|
||||
fi
|
||||
|
||||
project=$workspace/projects/mkwii/recomp.yml
|
||||
assets=$workspace/Assets
|
||||
generated=$workspace/generated
|
||||
@@ -174,6 +190,30 @@ assert_file "$project" "Translation project"
|
||||
assert_file "$assets/main.dol" "Extracted main.dol (see translator/README.md - owning the game is required)"
|
||||
assert_file "$assets/StaticR.rel" "Extracted StaticR.rel (see translator/README.md - owning the game is required)"
|
||||
|
||||
# The AppImage bundles Clang, but Linux startup objects and the C/C++ link runtimes
|
||||
# still come from the host. Check them before the expensive translation so a missing
|
||||
# development package produces a useful error instead of CMake's generic exit 1.
|
||||
link_probe_dir=$(mktemp -d)
|
||||
link_probe_flags=()
|
||||
[[ -z "$sysroot" ]] || link_probe_flags+=(--sysroot="$sysroot")
|
||||
[[ -z "$fuse_ld_override" ]] || link_probe_flags+=(-fuse-ld="$fuse_ld_override")
|
||||
printf 'int main(void) { return 0; }\n' > "$link_probe_dir/probe.c"
|
||||
cat > "$link_probe_dir/probe.cpp" <<'EOF'
|
||||
#include <vector>
|
||||
int main() { std::vector<int> values{1}; return values.front() - 1; }
|
||||
EOF
|
||||
if ! "$cc_bin" "${link_probe_flags[@]}" "$link_probe_dir/probe.c" -o "$link_probe_dir/probe-c" > "$link_probe_dir/error" 2>&1; then
|
||||
cat "$link_probe_dir/error" >&2
|
||||
rm -rf "$link_probe_dir"
|
||||
fail "The C compiler cannot link a test program. Linux needs C development files (glibc startup objects and a compiler runtime) in addition to bundled Clang. Install your distribution's development packages, or on SteamOS run WiiCompiled through the Wheel Wizard Flatpak."
|
||||
fi
|
||||
if ! "$cxx_bin" "${link_probe_flags[@]}" "$link_probe_dir/probe.cpp" -o "$link_probe_dir/probe-cxx" > "$link_probe_dir/error" 2>&1; then
|
||||
cat "$link_probe_dir/error" >&2
|
||||
rm -rf "$link_probe_dir"
|
||||
fail "The C++ compiler cannot link a test program. Install your distribution's C++ development packages, or on SteamOS run WiiCompiled through the Wheel Wizard Flatpak."
|
||||
fi
|
||||
rm -rf "$link_probe_dir"
|
||||
|
||||
# Literal line matching against the manifest's fixed shape, not a YAML dependency - the same
|
||||
# approach NativeBuildFlags.ps1's Get-MkwProjectPins uses on Windows, kept here only for the one
|
||||
# field this script actually needs from the manifest.
|
||||
@@ -336,26 +376,83 @@ translator "${shard_args[@]}"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
keep_native_build=0
|
||||
stale_reason=""
|
||||
if [[ -f "$build/CMakeCache.txt" ]]; then
|
||||
expected_home=$workspace/runtime
|
||||
cache_home=$(grep '^CMAKE_HOME_DIRECTORY:INTERNAL=' "$build/CMakeCache.txt" | cut -d= -f2- || true)
|
||||
if [[ -n "$cache_home" && "$(cd "$cache_home" 2>/dev/null && pwd)" == "$expected_home" ]]; then
|
||||
keep_native_build=1
|
||||
# CMake auto-detects and caches auxiliary tool paths (CMAKE_AR/RANLIB/LINKER/ASM_COMPILER
|
||||
# and their per-language *_AR/*_RANLIB variants) only once, the first time a language's
|
||||
# compiler is checked - unlike CMAKE_C_COMPILER/CMAKE_CXX_COMPILER, which get overwritten by
|
||||
# the -D flags below on every configure, these are never refreshed on a plain reconfigure.
|
||||
# An AppImage's own AppRun works around this at the source by keeping --cc/--cxx/--cmake/
|
||||
# --ninja pointed at a stable symlink it re-targets at the current mount every launch
|
||||
# (see build-appimage.sh), so the *path string* CMake caches never actually changes run to
|
||||
# run - but this check stays as a general fallback for any tool path that goes stale some
|
||||
# other way (a moved/removed system toolchain, a relocated portable-tools directory, etc):
|
||||
# any :FILEPATH= cache entry whose recorded path no longer exists means this cache belongs
|
||||
# to a toolchain location that's gone - not just a workspace/path mismatch.
|
||||
while IFS= read -r tool_path; do
|
||||
[[ -n "$tool_path" ]] || continue
|
||||
# CMake's own sentinel for "this optional tool was legitimately never found" (e.g.
|
||||
# clang-scan-deps, not required here) - not a path at all, and not a sign of anything
|
||||
# stale. Without this exclusion, every configure wiped the cache unconditionally.
|
||||
[[ "$tool_path" != *-NOTFOUND ]] || continue
|
||||
if [[ ! -e "$tool_path" ]]; then
|
||||
keep_native_build=0
|
||||
stale_reason=" (cached tool path no longer exists: $tool_path)"
|
||||
break
|
||||
fi
|
||||
done < <(grep -o ':FILEPATH=.*' "$build/CMakeCache.txt" | sed 's/^:FILEPATH=//')
|
||||
fi
|
||||
fi
|
||||
if [[ -d "$build" && "$keep_native_build" -eq 0 ]]; then
|
||||
echo "MKWCBUILD: The native build cache does not belong to this workspace path; rebuilding from scratch"
|
||||
echo "MKWCBUILD: The native build cache does not belong to this workspace path or toolchain; rebuilding from scratch$stale_reason"
|
||||
rm -rf "$build"
|
||||
elif [[ "$keep_native_build" -eq 1 ]]; then
|
||||
echo "MKWCBUILD: Reusing the incremental native build directory"
|
||||
fi
|
||||
|
||||
configure_args=(-S "$workspace/runtime" -B "$build" -G Ninja
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_C_COMPILER="$cc_bin" -DCMAKE_CXX_COMPILER="$cxx_bin"
|
||||
-DCMAKE_MAKE_PROGRAM="$ninja_bin"
|
||||
-DMKW_TRANSLATED_COMPILE_JOBS="$translated_jobs")
|
||||
# CMAKE_C_COMPILER/CXX_COMPILER stay stable across AppImage runs on their own (they're exactly
|
||||
# what's passed via -D above, and AppRun points --cc/--cxx at a symlink it re-targets at the
|
||||
# current mount every launch - see build-appimage.sh). CMAKE_AR/RANLIB/LINKER/ASM_COMPILER do NOT
|
||||
# inherit that stability just because $cc_bin does: verified directly that even with a stable
|
||||
# --cc symlink, CMake's own auto-detection of these still resolved to the *real*, ephemeral mount
|
||||
# path underneath (clang's own driver locates its sibling llvm-ar/ld.lld tools by resolving its own
|
||||
# invoked path, symlinks included, rather than trusting the symlink CMake invoked it through) -
|
||||
# each subsequent run's differing command line then made Ninja rebuild every object from scratch
|
||||
# even though nothing had actually changed. Deriving these from $cc_bin (itself already stable)
|
||||
# and re-passing them explicitly every configure keeps them pinned to the same stable value too.
|
||||
if [[ "$cc_bin" == */* ]]; then
|
||||
toolchain_bin=$(dirname "$cc_bin")
|
||||
[[ -x "$toolchain_bin/llvm-ar" ]] && configure_args+=(-DCMAKE_AR="$toolchain_bin/llvm-ar" -DCMAKE_ASM_COMPILER_AR="$toolchain_bin/llvm-ar" -DCMAKE_C_COMPILER_AR="$toolchain_bin/llvm-ar" -DCMAKE_CXX_COMPILER_AR="$toolchain_bin/llvm-ar")
|
||||
[[ -x "$toolchain_bin/llvm-ranlib" ]] && configure_args+=(-DCMAKE_RANLIB="$toolchain_bin/llvm-ranlib" -DCMAKE_ASM_COMPILER_RANLIB="$toolchain_bin/llvm-ranlib" -DCMAKE_C_COMPILER_RANLIB="$toolchain_bin/llvm-ranlib" -DCMAKE_CXX_COMPILER_RANLIB="$toolchain_bin/llvm-ranlib")
|
||||
[[ -x "$toolchain_bin/ld.lld" ]] && configure_args+=(-DCMAKE_LINKER="$toolchain_bin/ld.lld")
|
||||
configure_args+=(-DCMAKE_ASM_COMPILER="$cc_bin")
|
||||
fi
|
||||
if [[ -n "$fuse_ld_override" ]]; then
|
||||
configure_args+=(-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=$fuse_ld_override")
|
||||
fi
|
||||
if [[ -n "$native_prebuilt_dir" ]]; then
|
||||
configure_args+=(-DMKW_NATIVE_PREBUILT_DIR="$native_prebuilt_dir")
|
||||
fi
|
||||
if [[ -n "$sysroot" ]]; then
|
||||
configure_args+=(-DCMAKE_SYSROOT="$sysroot")
|
||||
else
|
||||
# Explicitly clear any cached CMAKE_SYSROOT from a prior configure so an
|
||||
# incremental build that transitions from one sysroot to none does not
|
||||
# silently keep the stale cached path.
|
||||
configure_args+=(-UCMAKE_SYSROOT)
|
||||
fi
|
||||
|
||||
log_step configure-native "Configuring the native toolchain"
|
||||
"$cmake_bin" -S "$workspace/runtime" -B "$build" -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER="$cc_bin" -DCMAKE_CXX_COMPILER="$cxx_bin" \
|
||||
-DCMAKE_MAKE_PROGRAM="$ninja_bin" \
|
||||
-DMKW_TRANSLATED_COMPILE_JOBS="$translated_jobs"
|
||||
"$cmake_bin" "${configure_args[@]}"
|
||||
|
||||
case "$profile" in
|
||||
base) targets=(WiiCompiled) ;;
|
||||
@@ -384,7 +481,9 @@ publish_built_product() {
|
||||
local exe=$build/$target
|
||||
assert_file "$exe" "Locally compiled game executable"
|
||||
cp -f "$exe" "$destination/$target"
|
||||
for name in dsp_coef.bin initial_pipeline_cache.db; do
|
||||
# cacert.pem is the TLS root bundle the mbed TLS path looks up beside the executable
|
||||
# (runtime/src/hle/net/network_ssl.cpp); without it HTTPS fails at runtime.
|
||||
for name in dsp_coef.bin initial_pipeline_cache.db cacert.pem; do
|
||||
[[ -f "$build/$name" ]] && cp -f "$build/$name" "$destination/"
|
||||
done
|
||||
[[ -d "$build/wii_bootstrap" ]] && cp -rf "$build/wii_bootstrap" "$destination/"
|
||||
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bash
|
||||
# Maintainer release builder. It packages setup/source/tooling only -- never a
|
||||
# translated executable, extracted DATA tree, disc image, or Retro Rewind data.
|
||||
set -euo pipefail
|
||||
|
||||
fail() { printf 'build-setup-pkg.command: error: %s\n' "$*" >&2; exit 1; }
|
||||
# Release payloads must not inherit Finder metadata, resource forks, or a
|
||||
# downloaded-file quarantine bit from a maintainer's working volume.
|
||||
copy_clean() { DITTONORSRC=1 ditto --norsrc --noqtn "$@"; }
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: build-setup-pkg.command --nodtool PATH --translator PATH --cmake-root DIR --ninja PATH --output PKG [options]
|
||||
|
||||
Creates a game-code-free WiiCompiled Setup.pkg. The supplied tools must be
|
||||
maintainer-verified, redistributable macOS arm64 artifacts. The resulting pkg
|
||||
is unsigned unless --installer-identity is supplied; releases should sign and
|
||||
notarize it with a Developer ID Installer certificate.
|
||||
|
||||
--workspace DIR Repository root (default: script's grandparent)
|
||||
--version VERSION Bundle/package version (default: 0.1.0)
|
||||
--installer-identity NAME Developer ID Installer identity for productbuild
|
||||
EOF
|
||||
}
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
workspace=$(cd "$script_dir/../.." && pwd); nodtool=""; translator=""; cmake_root=""; ninja=""; output=""; version=0.1.0; identity=""
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--workspace) workspace=${2:-}; shift 2 ;;
|
||||
--nodtool) nodtool=${2:-}; shift 2 ;;
|
||||
--translator) translator=${2:-}; shift 2 ;;
|
||||
--cmake-root) cmake_root=${2:-}; shift 2 ;;
|
||||
--ninja) ninja=${2:-}; shift 2 ;;
|
||||
--output) output=${2:-}; shift 2 ;;
|
||||
--version) version=${2:-}; shift 2 ;;
|
||||
--installer-identity) identity=${2:-}; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
version=${version#v}
|
||||
[[ "$version" =~ ^[0-9]+(\.[0-9]+){0,2}$ ]] || fail '--version must contain one to three period-separated integers'
|
||||
IFS=. read -r version_major version_minor version_patch <<< "$version"
|
||||
short_version="$version_major.${version_minor:-0}.${version_patch:-0}"
|
||||
for tool in pkgbuild productbuild ditto codesign; do command -v "$tool" >/dev/null || fail "required macOS tool unavailable: $tool"; done
|
||||
[[ -x "$nodtool" ]] || fail '--nodtool must name an executable'
|
||||
[[ -x "$translator" ]] || fail '--translator must name an executable'
|
||||
[[ -x "$cmake_root/bin/cmake" ]] || fail '--cmake-root must contain bin/cmake'
|
||||
[[ -x "$ninja" ]] || fail '--ninja must name an executable'
|
||||
"$nodtool" --version >/dev/null || fail '--nodtool did not run successfully'
|
||||
workspace=$(cd "$workspace" && pwd); output=$(cd "$(dirname "$output")" && pwd)/$(basename "$output")
|
||||
stage=$(mktemp -d "${TMPDIR:-/tmp}/wiicompiled-pkg.XXXXXX")
|
||||
trap 'rm -rf "$stage"' EXIT
|
||||
app="$stage/root/Applications/WiiCompiled Setup.app"
|
||||
resources="$app/Contents/Resources"
|
||||
mkdir -p "$app/Contents/MacOS" "$resources/tools"
|
||||
cat > "$app/Contents/Info.plist" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0"><dict>
|
||||
<key>CFBundleExecutable</key><string>WiiCompiledSetup</string>
|
||||
<key>CFBundleIdentifier</key><string>org.wiicompiled.setup</string>
|
||||
<key>CFBundleName</key><string>WiiCompiled Setup</string>
|
||||
<key>CFBundlePackageType</key><string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key><string>$short_version</string>
|
||||
<key>CFBundleVersion</key><string>$version</string>
|
||||
<key>LSMinimumSystemVersion</key><string>14.0</string>
|
||||
</dict></plist>
|
||||
EOF
|
||||
cat > "$app/Contents/MacOS/WiiCompiledSetup" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
resources="$(cd "$(dirname "$0")/../Resources" && pwd)"
|
||||
|
||||
# Finder launches an app with no terminal attached. The setup work deliberately
|
||||
# writes human-readable build progress to stdout, so run its .command entry
|
||||
# point in Terminal instead of discarding that output behind an inert app icon.
|
||||
exec /usr/bin/osascript - "$resources/setup.command" "$@" <<'APPLESCRIPT'
|
||||
on run argv
|
||||
set commandLine to quoted form of (item 1 of argv)
|
||||
if (count of argv) > 1 then
|
||||
repeat with argumentIndex from 2 to (count of argv)
|
||||
set commandLine to commandLine & " " & quoted form of (item argumentIndex of argv)
|
||||
end repeat
|
||||
end if
|
||||
tell application "Terminal"
|
||||
activate
|
||||
do script commandLine
|
||||
end tell
|
||||
end run
|
||||
APPLESCRIPT
|
||||
EOF
|
||||
chmod +x "$app/Contents/MacOS/WiiCompiledSetup"
|
||||
copy_clean "$script_dir/setup.command" "$resources/setup.command"; chmod +x "$resources/setup.command"
|
||||
# Copy only the build inputs. This deliberately avoids a maintainer's ignored
|
||||
# output directories, local disc extraction, and developer-only packaging.
|
||||
mkdir -p "$resources/workspace"
|
||||
for source in aurora-main projects runtime translator; do
|
||||
[[ -d "$workspace/$source" ]] || fail "required workspace directory is missing: $source"
|
||||
copy_clean "$workspace/$source" "$resources/workspace/$source"
|
||||
done
|
||||
# Setup bundles contain materialized sources and must work without Git.
|
||||
find "$resources/workspace" -name .git -prune -exec rm -rf {} +
|
||||
mkdir -p "$resources/workspace/Launcher/macos"
|
||||
copy_clean "$workspace/Launcher/local-build-macos.command" "$resources/workspace/Launcher/local-build-macos.command"
|
||||
copy_clean "$workspace/Launcher/macos/extract-disc.command" "$resources/workspace/Launcher/macos/extract-disc.command"
|
||||
copy_clean "$workspace/Launcher/macos/publish-app.command" "$resources/workspace/Launcher/macos/publish-app.command"
|
||||
chmod +x "$resources/workspace/Launcher/local-build-macos.command" "$resources/workspace/Launcher/macos/"*.command
|
||||
mkdir -p "$resources/tools/cmake"
|
||||
copy_clean "$nodtool" "$resources/tools/nodtool"; chmod +x "$resources/tools/nodtool"
|
||||
copy_clean "$translator" "$resources/tools/Translator.Cli"; chmod +x "$resources/tools/Translator.Cli"
|
||||
copy_clean "$cmake_root" "$resources/tools/cmake"
|
||||
copy_clean "$ninja" "$resources/tools/ninja"; chmod +x "$resources/tools/ninja"
|
||||
copy_clean "$workspace/LICENSE" "$resources/LICENSE"
|
||||
copy_clean "$workspace/THIRD-PARTY-NOTICES.md" "$resources/THIRD-PARTY-NOTICES.md"
|
||||
codesign --force --deep --sign - "$app"
|
||||
pkg="$stage/WiiCompiled-Setup-unsigned.pkg"
|
||||
DITTONORSRC=1 COPYFILE_DISABLE=1 pkgbuild --root "$stage/root" --identifier org.wiicompiled.setup --version "$version" --install-location / "$pkg"
|
||||
if [[ -n "$identity" ]]; then productbuild --sign "$identity" --package "$pkg" "$output"; else ditto "$pkg" "$output"; fi
|
||||
printf 'Created game-code-free package: %s\n' "$output"
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# Extract a user-owned Mario Kart Wii PAL (RMCP01) disc image for a local build.
|
||||
# This script deliberately contains no game data and is intended for the macOS
|
||||
# setup application and for maintainers testing that setup path.
|
||||
set -euo pipefail
|
||||
|
||||
readonly EXPECTED_DOL_SHA256=80d18895b39c63bd80f457398bfcbb91b7d16ac116a41a88967e954080155b05
|
||||
readonly EXPECTED_REL_SHA256=16d9d146112541fefea701ecb5bc1a496f9d50e4a752fbb5b6778e7c6399f67d
|
||||
|
||||
fail() { printf 'extract-disc.command: error: %s\n' "$*" >&2; exit 1; }
|
||||
sha256() { shasum -a 256 "$1" | awk '{ print $1 }'; }
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: extract-disc.command --game IMAGE --assets-dir DIR --nodtool PATH
|
||||
|
||||
Extracts a user-owned Mario Kart Wii PAL RMCP01 image into DIR. The final
|
||||
layout is DIR/main.dol, DIR/StaticR.rel, and DIR/DATA. Existing data is left
|
||||
untouched unless the complete new extraction passes both content hash checks.
|
||||
EOF
|
||||
}
|
||||
|
||||
game=""
|
||||
assets_dir=""
|
||||
nodtool=""
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--game) game=${2:-}; shift 2 ;;
|
||||
--assets-dir) assets_dir=${2:-}; shift 2 ;;
|
||||
--nodtool) nodtool=${2:-}; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -f "$game" ]] || fail "disc image does not exist: $game"
|
||||
[[ -n "$assets_dir" ]] || fail "--assets-dir is required"
|
||||
[[ -x "$nodtool" ]] || fail "nodtool is not executable: $nodtool"
|
||||
|
||||
assets_dir=$(mkdir -p "$assets_dir" && cd "$assets_dir" && pwd)
|
||||
scratch=$(mktemp -d "${TMPDIR:-/tmp}/wiicompiled-disc.XXXXXX")
|
||||
cleanup() { rm -rf "$scratch"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
printf 'MKWCBUILD:STEP:validate-disc Checking the selected disc image\n'
|
||||
"$nodtool" info "$game" >/dev/null
|
||||
printf 'MKWCBUILD:STEP:extract-disc Extracting the user-owned disc image\n'
|
||||
"$nodtool" extract "$game" "$scratch/extracted"
|
||||
|
||||
dol=$(find "$scratch/extracted" -type f -path '*/sys/main.dol' -print -quit)
|
||||
rel=$(find "$scratch/extracted" -type f -path '*/files/rel/StaticR.rel' -print -quit)
|
||||
[[ -n "$dol" ]] || fail 'nodtool extraction did not contain sys/main.dol'
|
||||
[[ -n "$rel" ]] || fail 'nodtool extraction did not contain files/rel/StaticR.rel'
|
||||
[[ $(sha256 "$dol") == "$EXPECTED_DOL_SHA256" ]] || fail 'disc is not the supported clean PAL RMCP01 Mario Kart Wii image'
|
||||
[[ $(sha256 "$rel") == "$EXPECTED_REL_SHA256" ]] || fail 'disc has an unexpected StaticR.rel; use a clean PAL RMCP01 image'
|
||||
|
||||
data_root=$(dirname "$(dirname "$dol")")
|
||||
[[ -d "$data_root/files" ]] || fail 'nodtool extraction did not contain the Wii files directory'
|
||||
|
||||
# Stage beside the destination so the final replacement stays on one volume.
|
||||
stage="$assets_dir/.extract-stage-$$"
|
||||
rm -rf "$stage"
|
||||
mkdir -p "$stage"
|
||||
ditto "$data_root" "$stage/DATA"
|
||||
ditto "$dol" "$stage/main.dol"
|
||||
ditto "$rel" "$stage/StaticR.rel"
|
||||
|
||||
backup="$assets_dir/.previous-extraction-$(date +%Y%m%d-%H%M%S)"
|
||||
if [[ -e "$assets_dir/DATA" || -e "$assets_dir/main.dol" || -e "$assets_dir/StaticR.rel" ]]; then
|
||||
mkdir -p "$backup"
|
||||
for item in DATA main.dol StaticR.rel; do
|
||||
[[ -e "$assets_dir/$item" ]] && mv "$assets_dir/$item" "$backup/$item"
|
||||
done
|
||||
fi
|
||||
mv "$stage/DATA" "$assets_dir/DATA"
|
||||
mv "$stage/main.dol" "$assets_dir/main.dol"
|
||||
mv "$stage/StaticR.rel" "$assets_dir/StaticR.rel"
|
||||
rmdir "$stage"
|
||||
rm -rf "$backup"
|
||||
|
||||
printf 'MKWCBUILD:STEP:disc-ready Verified and extracted clean PAL RMCP01 game assets\n'
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
# Turn one locally compiled macOS product into a self-contained .app bundle.
|
||||
set -euo pipefail
|
||||
|
||||
fail() { printf 'publish-app.command: error: %s\n' "$*" >&2; exit 1; }
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: publish-app.command --build-dir DIR --product {WiiCompiled|RetroRewind} --output-dir DIR
|
||||
|
||||
Copies a locally built product and its runtime assets into OUTPUT-DIR/<product>.app.
|
||||
It bundles non-system dylibs, rewrites their install names, and ad-hoc signs the
|
||||
result. This is suitable for local use; a release must replace ad-hoc signing
|
||||
with the project's Developer ID signing and notarization process.
|
||||
EOF
|
||||
}
|
||||
|
||||
build_dir=""; product=""; output_dir=""
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--build-dir) build_dir=${2:-}; shift 2 ;;
|
||||
--product) product=${2:-}; shift 2 ;;
|
||||
--output-dir) output_dir=${2:-}; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
[[ "$product" == WiiCompiled || "$product" == RetroRewind ]] || fail '--product must be WiiCompiled or RetroRewind'
|
||||
for tool in codesign ditto install_name_tool otool; do command -v "$tool" >/dev/null || fail "required macOS tool is unavailable: $tool"; done
|
||||
[[ -x "$build_dir/$product" ]] || fail "missing compiled product: $build_dir/$product"
|
||||
for asset in dsp_coef.bin initial_pipeline_cache.db cacert.pem wii_bootstrap; do [[ -e "$build_dir/$asset" ]] || fail "missing runtime asset: $build_dir/$asset"; done
|
||||
|
||||
app="$output_dir/$product.app"
|
||||
macos="$app/Contents/MacOS"
|
||||
frameworks="$app/Contents/Frameworks"
|
||||
resources="$app/Contents/Resources"
|
||||
rm -rf "$app"
|
||||
mkdir -p "$macos" "$frameworks" "$resources"
|
||||
cat > "$app/Contents/Info.plist" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0"><dict>
|
||||
<key>CFBundleDevelopmentRegion</key><string>en</string>
|
||||
<key>CFBundleExecutable</key><string>$product</string>
|
||||
<key>CFBundleIdentifier</key><string>org.wiicompiled.$product</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
|
||||
<key>CFBundleName</key><string>$product</string>
|
||||
<key>CFBundlePackageType</key><string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key><string>0.1.0</string>
|
||||
<key>CFBundleVersion</key><string>1</string>
|
||||
<key>LSMinimumSystemVersion</key><string>14.0</string>
|
||||
<key>NSHighResolutionCapable</key><true/>
|
||||
</dict></plist>
|
||||
EOF
|
||||
ditto "$build_dir/$product" "$macos/$product"
|
||||
for asset in dsp_coef.bin initial_pipeline_cache.db cacert.pem wii_bootstrap; do
|
||||
ditto "$build_dir/$asset" "$resources/$asset"
|
||||
ln -s "../Resources/$asset" "$macos/$asset"
|
||||
done
|
||||
|
||||
# Build a closure of Homebrew dylibs. System libraries remain system references.
|
||||
queue=("$macos/$product")
|
||||
while ((${#queue[@]})); do
|
||||
current=${queue[0]}
|
||||
queue=("${queue[@]:1}")
|
||||
while IFS= read -r dependency; do
|
||||
[[ "$dependency" == /opt/homebrew/* || "$dependency" == /usr/local/* ]] || continue
|
||||
[[ -f "$dependency" ]] || continue
|
||||
name=$(basename "$dependency")
|
||||
if [[ ! -f "$frameworks/$name" ]]; then
|
||||
ditto "$dependency" "$frameworks/$name"
|
||||
install_name_tool -id "@rpath/$name" "$frameworks/$name"
|
||||
queue+=("$frameworks/$name")
|
||||
fi
|
||||
done < <(otool -L "$current" | tail -n +2 | awk '{print $1}')
|
||||
done
|
||||
while IFS= read -r binary; do
|
||||
while IFS= read -r old; do
|
||||
[[ "$old" == /opt/homebrew/* || "$old" == /usr/local/* ]] || continue
|
||||
name=$(basename "$old")
|
||||
[[ -f "$frameworks/$name" ]] || continue
|
||||
if [[ "$binary" == "$macos/$product" ]]; then
|
||||
install_name_tool -change "$old" "@executable_path/../Frameworks/$name" "$binary"
|
||||
else
|
||||
install_name_tool -change "$old" "@loader_path/$name" "$binary"
|
||||
fi
|
||||
done < <(otool -L "$binary" | tail -n +2 | awk '{print $1}')
|
||||
done < <(find "$frameworks" -type f -print; printf '%s\n' "$macos/$product")
|
||||
|
||||
find "$frameworks" -type f -exec codesign --force --sign - {} +
|
||||
codesign --force --deep --sign - "$app"
|
||||
codesign --verify --deep --strict "$app"
|
||||
printf 'MKWCBUILD:APP=%s\n' "$app"
|
||||
Executable
+154
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env bash
|
||||
# Entry point bundled in WiiCompiled Setup.app. The package contains source and
|
||||
# tools only; a user's own verified disc is extracted into Application Support.
|
||||
set -euo pipefail
|
||||
|
||||
resources=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
workspace_source="$resources/workspace"
|
||||
nodtool="$resources/tools/nodtool"
|
||||
translator="$resources/tools/Translator.Cli"
|
||||
cmake_bin="$resources/tools/cmake/bin/cmake"
|
||||
ninja_bin="$resources/tools/ninja"
|
||||
support_root="$HOME/Library/Application Support/WiiCompiled"
|
||||
workspace="$support_root/BuildWorkspace"
|
||||
products="$support_root/Products"
|
||||
|
||||
fail() { printf 'WiiCompiled Setup: %s\n' "$*" >&2; exit 1; }
|
||||
notice() { /usr/bin/osascript -e "display dialog \"${1//\"/\\\"}\" buttons {\"OK\"} default button \"OK\" with icon caution" >/dev/null; }
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: setup.command --game IMAGE [--retro-dir DIR] [--install-location {user|applications}]
|
||||
|
||||
Without arguments this script opens file pickers. It is normally launched by
|
||||
WiiCompiled Setup.app, not run directly.
|
||||
EOF
|
||||
}
|
||||
|
||||
game=""; retro_dir=""; install_location=applications
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--game) game=${2:-}; shift 2 ;;
|
||||
--retro-dir) retro_dir=${2:-}; shift 2 ;;
|
||||
--install-location) install_location=${2:-}; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) fail "unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
[[ "$install_location" == user || "$install_location" == applications ]] || fail '--install-location must be user or applications'
|
||||
|
||||
if [[ -z "$game" ]]; then
|
||||
game=$(/usr/bin/osascript <<'APPLESCRIPT'
|
||||
set selectedFile to choose file with prompt "Choose your clean Mario Kart Wii PAL (RMCP01) disc image"
|
||||
POSIX path of selectedFile
|
||||
APPLESCRIPT
|
||||
) || exit 0
|
||||
choice=$(/usr/bin/osascript -e 'button returned of (display dialog "Would you like to build Retro Rewind too?" buttons {"Base game only", "Choose Retro Rewind folder"} default button "Base game only")')
|
||||
if [[ "$choice" == 'Choose Retro Rewind folder' ]]; then
|
||||
retro_dir=$(/usr/bin/osascript <<'APPLESCRIPT'
|
||||
set selectedFolder to choose folder with prompt "Choose the RetroRewind6 folder (or its parent folder)"
|
||||
POSIX path of selectedFolder
|
||||
APPLESCRIPT
|
||||
) || exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ -x "$nodtool" ]] || fail 'the packaged nodtool is missing or not executable'
|
||||
[[ -x "$translator" ]] || fail 'the packaged Translator.Cli is missing or not executable'
|
||||
[[ -x "$cmake_bin" && -x "$ninja_bin" ]] || fail 'the packaged CMake or Ninja tool is missing'
|
||||
if ! /usr/bin/xcode-select -p >/dev/null 2>&1; then
|
||||
notice 'Xcode Command Line Tools are required once to compile WiiCompiled. Click OK, complete the Apple installer, then run WiiCompiled Setup again.'
|
||||
/usr/bin/xcode-select --install || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$support_root" "$products"
|
||||
if [[ ! -d "$workspace/.git" && ! -f "$workspace/projects/mkwii/recomp.yml" ]]; then
|
||||
printf 'Preparing the local build workspace...\n'
|
||||
rm -rf "$workspace"
|
||||
/usr/bin/ditto "$workspace_source" "$workspace"
|
||||
fi
|
||||
|
||||
profile=base
|
||||
build_args=(--workspace "$workspace" --game "$game" --nodtool "$nodtool" --output-dir "$products")
|
||||
if [[ -n "$retro_dir" ]]; then
|
||||
profile=both
|
||||
# Online play needs the shared Retro-WFC payload. Keep it in the per-user
|
||||
# support directory rather than the packaged app or build workspace, then
|
||||
# verify its pinned signature before publishing it into the local cache.
|
||||
retro_wfc_dir="$support_root/RetroWfcPayload"
|
||||
retro_wfc_payload="$retro_wfc_dir/binary/payload.RMCPD00.bin"
|
||||
cached_payload_valid=0
|
||||
if [[ -f "$retro_wfc_payload" ]]; then
|
||||
if "$translator" validate-retro-wfc-payload --directory "$retro_wfc_dir"; then
|
||||
cached_payload_valid=1
|
||||
else
|
||||
printf 'Discarding an invalid cached Retro-WFC payload...\n' >&2
|
||||
rm -f "$retro_wfc_payload"
|
||||
fi
|
||||
fi
|
||||
|
||||
# A signed cache may still be an older vulnerable revision, so always attempt to replace it
|
||||
# with the current signed snapshot. A transport failure may fall back to the verified cache;
|
||||
# a downloaded snapshot with an invalid signature remains a hard failure.
|
||||
printf 'Downloading the current Retro-WFC payload needed for online play...\n'
|
||||
mkdir -p "$retro_wfc_dir"
|
||||
payload_stage=$(mktemp -d "$retro_wfc_dir/.payload-download.XXXXXX")
|
||||
temporary_payload="$payload_stage/binary/payload.RMCPD00.bin"
|
||||
mkdir -p "$(dirname "$temporary_payload")"
|
||||
trap 'rm -rf "$payload_stage"' EXIT
|
||||
if /usr/bin/curl --fail --silent --show-error --connect-timeout 10 --max-time 30 \
|
||||
--retry 1 --output "$temporary_payload" \
|
||||
'https://rwfc.net/api/wfc/payload?g=RMCPD00'; then
|
||||
"$translator" validate-retro-wfc-payload --directory "$payload_stage" || \
|
||||
fail 'downloaded Retro-WFC payload failed signature validation'
|
||||
mkdir -p "$retro_wfc_dir/binary"
|
||||
mv "$temporary_payload" "$retro_wfc_payload"
|
||||
rmdir "$payload_stage/binary" "$payload_stage"
|
||||
trap - EXIT
|
||||
elif (( cached_payload_valid )); then
|
||||
printf 'Could not download the current Retro-WFC payload; using the previously verified cached payload.\n' >&2
|
||||
rm -rf "$payload_stage"
|
||||
trap - EXIT
|
||||
else
|
||||
fail 'could not download the current Retro-WFC payload and no valid cached payload is available'
|
||||
fi
|
||||
build_args+=(--profile both --base-output-dir "$products" --retro-rewind-package-dir "$retro_dir" --retro-wfc-offline-dir "$retro_wfc_dir")
|
||||
fi
|
||||
"$workspace/Launcher/local-build-macos.command" "${build_args[@]}" --profile "$profile" --cmake "$cmake_bin" --ninja "$ninja_bin" --translator-bin "$translator"
|
||||
|
||||
config="$support_root/Config.toml"
|
||||
toml_string() { printf '%s' "$1" | sed -e 's/\\\\/\\\\\\\\/g' -e 's/"/\\\\"/g'; }
|
||||
set_path() {
|
||||
local key=$1 value=$2 encoded line temporary
|
||||
encoded=$(toml_string "$value"); line="$key = \"$encoded\""; temporary="$config.tmp"
|
||||
touch "$config"
|
||||
if grep -q '^[[:space:]]*\[paths\][[:space:]]*$' "$config"; then
|
||||
awk -v key="$key" -v line="$line" '
|
||||
/^[[:space:]]*\[paths\][[:space:]]*$/ { print; print line; inside = 1; next }
|
||||
inside && /^[[:space:]]*\[/ { inside = 0 }
|
||||
inside && $0 ~ "^[[:space:]]*" key "[[:space:]]*=" { next }
|
||||
{ print }
|
||||
' "$config" > "$temporary"
|
||||
else
|
||||
{ cat "$config"; printf '\n[paths]\n%s\n' "$line"; } > "$temporary"
|
||||
fi
|
||||
mv "$temporary" "$config"
|
||||
}
|
||||
set_path dvd_root "$workspace/Assets/DATA"
|
||||
[[ -n "$retro_dir" ]] && set_path retro_rewind_root "$retro_dir"
|
||||
|
||||
destination="$HOME/Applications"
|
||||
if [[ "$install_location" == applications ]]; then destination=/Applications; fi
|
||||
install_app() {
|
||||
local app=$1
|
||||
[[ -d "$products/$app" ]] || return 0
|
||||
if [[ "$destination" == /Applications ]]; then
|
||||
command="mkdir -p /Applications && rm -rf '/Applications/$app' && ditto '$products/$app' '/Applications/$app'"
|
||||
/usr/bin/osascript -e "do shell script \"$command\" with administrator privileges"
|
||||
else
|
||||
mkdir -p "$destination"; rm -rf "$destination/$app"; /usr/bin/ditto "$products/$app" "$destination/$app"
|
||||
fi
|
||||
}
|
||||
install_app WiiCompiled.app
|
||||
[[ "$profile" == both ]] && install_app RetroRewind.app
|
||||
notice "Installation complete. Your apps are in $destination."
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env bash
|
||||
# Prepares a self-contained native-Linux build toolchain bundled into the AppImage by
|
||||
# build-appimage.sh, so a user needs no `clang`/`cmake`/`ninja` of their own to build the
|
||||
# translated game (mirrors why Windows bundles llvm-mingw + CMake + Ninja via
|
||||
# Prepare-PortableTools.ps1 - this is that script's Linux counterpart, for the same reason).
|
||||
#
|
||||
# clang/lld/llvm-ar: pruned from the official llvm.org GitHub release tarball (NOT llvm-mingw -
|
||||
# that project targets Windows/mingw, never native Linux) down to just what's needed to compile
|
||||
# and link: clang, lld, llvm-ar, the clang resource dir (builtin headers + compiler-rt), and
|
||||
# libc++/libc++abi/libunwind (so the toolchain never has to fall back to the host's system
|
||||
# libstdc++ headers). The raw release is ~1.9 GiB per arch (every LLVM backend, mlir, flang, lldb,
|
||||
# docs, tests); pruned it is ~500 MiB uncompressed / ~100 MiB compressed, verified against a real
|
||||
# build of this project.
|
||||
#
|
||||
# cmake: pruned from the official Kitware GitHub release tarball down to bin/cmake (not
|
||||
# ccmake/cmake-gui/cpack/ctest, which local-build.sh never invokes) plus the Modules/Templates
|
||||
# CMake needs at runtime (found relative to bin/cmake via CMAKE_ROOT auto-detection - Help/doc/man/
|
||||
# the desktop-integration files under share/ are documentation/GUI-only and dropped). Verified with
|
||||
# a real configure+build using the pruned cmake+ninja+clang together.
|
||||
#
|
||||
# ninja: the official ninja-build GitHub release zip, used as-is - it is already a single small
|
||||
# (~130 KiB compressed) static-ish binary with nothing to prune.
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
workspace=$(cd "$script_dir/.." && pwd)
|
||||
|
||||
llvm_version=22.1.8
|
||||
cmake_version=4.3.3
|
||||
ninja_version=1.13.2
|
||||
destination="$script_dir/artifacts/portable-tools"
|
||||
arch=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: prepare-portable-tools.sh --arch {x86_64|aarch64} [--destination DIR]
|
||||
|
||||
--arch ARCH Target architecture (required)
|
||||
--destination DIR Where the toolchain is written, as DIR/toolchain-ARCH
|
||||
(default: Launcher/artifacts/portable-tools)
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--arch) arch=$2; shift 2 ;;
|
||||
--destination) destination=$2; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "prepare-portable-tools.sh: unknown argument: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$arch" in
|
||||
x86_64) llvm_release_arch=X64; target_triple=x86_64-unknown-linux-gnu
|
||||
llvm_release_sha256=fccecb1906e7ddf5ec040aec5b646b650e2daaafa4423b41341c4717db5bdec0
|
||||
cmake_release_arch=x86_64
|
||||
cmake_sha256=927b2368a946c37269c3a66225ab00544e756459cdd0b5d0da438694fb9ff802
|
||||
ninja_asset=ninja-linux.zip
|
||||
ninja_sha256=5749cbc4e668273514150a80e387a957f933c6ed3f5f11e03fb30955e2bbead6 ;;
|
||||
aarch64) llvm_release_arch=ARM64; target_triple=aarch64-unknown-linux-gnu
|
||||
llvm_release_sha256=d431eff9f064c86ee7c4c94af570a8f74fcccd1f74c6f0da3af32ce34a1e1b05
|
||||
cmake_release_arch=aarch64
|
||||
cmake_sha256=9ea38356dbd3e32e51029a3e09a0f2f8e117ef4fbcaad7a21ffb36409bbd5cb4
|
||||
ninja_asset=ninja-linux-aarch64.zip
|
||||
ninja_sha256=fd2cacc8050a7f12a16a2e48f9e06fca5c14fc4c2bee2babb67b58be17a607fc ;;
|
||||
*) echo "prepare-portable-tools.sh: --arch must be x86_64 or aarch64" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
|
||||
destination=$(mkdir -p "$destination" && cd "$destination" && pwd)
|
||||
toolchain_dir="$destination/toolchain-$arch"
|
||||
downloads="$script_dir/artifacts/downloads"
|
||||
mkdir -p "$downloads"
|
||||
|
||||
sha256_of() { sha256sum "$1" | awk '{print $1}'; }
|
||||
|
||||
download_verified() {
|
||||
# $1 = destination path, $2 = URL, $3 = expected sha256
|
||||
local dest=$1 url=$2 expected=$3
|
||||
if [[ -f "$dest" ]] && [[ "$(sha256_of "$dest")" == "$expected" ]]; then return; fi
|
||||
echo "prepare-portable-tools.sh: downloading $(basename "$dest")..."
|
||||
local tmp="$dest.partial"
|
||||
rm -f "$tmp"
|
||||
curl -fL --progress-bar -o "$tmp" "$url"
|
||||
local actual
|
||||
actual=$(sha256_of "$tmp")
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
echo "prepare-portable-tools.sh: $(basename "$dest") hash mismatch: expected $expected, got $actual" >&2
|
||||
rm -f "$tmp"
|
||||
exit 1
|
||||
fi
|
||||
mv "$tmp" "$dest"
|
||||
}
|
||||
|
||||
if [[ -x "$toolchain_dir/bin/clang" && -x "$toolchain_dir/bin/ninja" && -x "$toolchain_dir/bin/cmake" ]]; then
|
||||
echo "prepare-portable-tools.sh: reusing existing toolchain at $toolchain_dir"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
work="$destination/.building-toolchain-$arch"
|
||||
rm -rf "$work"
|
||||
mkdir -p "$work/bin" "$work/lib/$target_triple" "$work/include/$target_triple/c++/v1"
|
||||
|
||||
# --- clang/lld/llvm-ar, pruned from the official LLVM release ---
|
||||
# built from PR https://github.com/llvm/llvm-project/pull/222821 on official LLVM Github Actions Runner
|
||||
# only switch to an official stable LLVM release again once:
|
||||
# - this PR has merged https://github.com/llvm/llvm-project/pull/221365 and been backported to LLVM stable branch
|
||||
# - this bug has been fixed with a workaround in the Wiicompiled translator https://github.com/patchzyy/Wiicompiled/issues/208 or in LLVM and been backported to LLVM stable branch
|
||||
llvm_archive_name="LLVM-PR222821-5ae1c7c43a11b4cdc5ce4dd483c28357bab7dae2-Linux-$llvm_release_arch.tar.xz"
|
||||
llvm_archive="$downloads/$llvm_archive_name"
|
||||
download_verified "$llvm_archive" \
|
||||
"https://github.com/theofficialgman/llvm-project/releases/download/llvmorg-22.1.8-patched/$llvm_archive_name" \
|
||||
"$llvm_release_sha256"
|
||||
|
||||
extract_root="$script_dir/artifacts/.extract-clang-$arch"
|
||||
rm -rf "$extract_root"
|
||||
mkdir -p "$extract_root"
|
||||
echo "prepare-portable-tools.sh: extracting $llvm_archive_name (this is the full ~1.9 GiB release; only a fraction is kept)..."
|
||||
tar -xf "$llvm_archive" -C "$extract_root"
|
||||
src="$extract_root/${llvm_archive_name%.tar.xz}"
|
||||
[[ -d "$src" ]] || { echo "prepare-portable-tools.sh: unexpected archive layout, expected $src" >&2; exit 1; }
|
||||
|
||||
echo "prepare-portable-tools.sh: pruning to the minimal compile+link toolchain..."
|
||||
|
||||
# clang: the real driver executable plus the clang/clang++ symlinks CMake/local-build.sh invoke.
|
||||
# Stripped: debug symbols are dead weight for a bundled compiler nobody will debug.
|
||||
cp -a "$src/bin/clang-22" "$work/bin/"
|
||||
strip "$work/bin/clang-22"
|
||||
ln -s clang-22 "$work/bin/clang"
|
||||
ln -s clang "$work/bin/clang++"
|
||||
|
||||
# lld: linked via -fuse-ld=lld, which clang resolves by looking for ld.lld next to itself first -
|
||||
# see local-build.sh's --fuse-ld option.
|
||||
cp -a "$src/bin/lld" "$work/bin/"
|
||||
strip "$work/bin/lld"
|
||||
ln -s lld "$work/bin/ld.lld"
|
||||
|
||||
# llvm-ar/llvm-ranlib: CMake's archiver for the many static libraries this project builds
|
||||
# (aurora, Crypto++, SDL3, Dawn's dependency closure, the translated game shards).
|
||||
cp -a "$src/bin/llvm-ar" "$work/bin/"
|
||||
strip "$work/bin/llvm-ar"
|
||||
ln -s llvm-ar "$work/bin/llvm-ranlib"
|
||||
|
||||
# Clang's resource directory: builtin headers (stddef.h, immintrin.h, ...) and compiler-rt
|
||||
# (builtins, sanitizer runtimes). `clang -print-resource-dir` must find this at lib/clang/<ver>/.
|
||||
cp -a "$src/lib/clang" "$work/lib/"
|
||||
|
||||
# libc++/libc++abi/libunwind: so this toolchain never has to fall back to whatever libstdc++ the
|
||||
# host distro happens to have installed. Not the default yet (local-build.sh still resolves the
|
||||
# system libstdc++ unless -stdlib=libc++ is passed), but bundled so that option exists.
|
||||
cp -a "$src/include/c++" "$work/include/"
|
||||
cp -a "$src/include/$target_triple/c++/v1/__config_site" "$work/include/$target_triple/c++/v1/"
|
||||
cp -a "$src/lib/$target_triple"/libc++.a "$src/lib/$target_triple"/libc++abi.a "$src/lib/$target_triple"/libunwind.a "$work/lib/$target_triple/"
|
||||
cp -a "$src/lib/$target_triple"/libc++.so* "$src/lib/$target_triple"/libc++abi.so* "$src/lib/$target_triple"/libunwind.so* "$work/lib/$target_triple/"
|
||||
|
||||
rm -rf "$extract_root"
|
||||
|
||||
# --- cmake, pruned from the official Kitware release ---
|
||||
|
||||
cmake_share_version=${cmake_version%.*}
|
||||
cmake_archive_name="cmake-$cmake_version-linux-$cmake_release_arch.tar.gz"
|
||||
cmake_archive="$downloads/$cmake_archive_name"
|
||||
download_verified "$cmake_archive" \
|
||||
"https://github.com/Kitware/CMake/releases/download/v$cmake_version/$cmake_archive_name" \
|
||||
"$cmake_sha256"
|
||||
|
||||
cmake_extract_root="$script_dir/artifacts/.extract-cmake-$arch"
|
||||
rm -rf "$cmake_extract_root"
|
||||
mkdir -p "$cmake_extract_root"
|
||||
echo "prepare-portable-tools.sh: extracting $cmake_archive_name..."
|
||||
tar -xzf "$cmake_archive" -C "$cmake_extract_root"
|
||||
|
||||
cmake_src="$cmake_extract_root/${cmake_archive_name%.tar.gz}"
|
||||
[[ -d "$cmake_src" ]] || { echo "prepare-portable-tools.sh: unexpected archive layout, expected $cmake_src" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$work/share/cmake-$cmake_share_version"
|
||||
cp -a "$cmake_src/bin/cmake" "$work/bin/"
|
||||
cp -a "$cmake_src/share/cmake-$cmake_share_version/Modules" "$cmake_src/share/cmake-$cmake_share_version/Templates" \
|
||||
"$work/share/cmake-$cmake_share_version/"
|
||||
rm -rf "$cmake_extract_root"
|
||||
|
||||
# --- ninja, used as-is ---
|
||||
|
||||
ninja_archive="$downloads/ninja-$ninja_version-$arch.zip"
|
||||
download_verified "$ninja_archive" \
|
||||
"https://github.com/ninja-build/ninja/releases/download/v$ninja_version/$ninja_asset" \
|
||||
"$ninja_sha256"
|
||||
echo "prepare-portable-tools.sh: staging ninja $ninja_version..."
|
||||
unzip -oq "$ninja_archive" -d "$work/bin"
|
||||
chmod +x "$work/bin/ninja"
|
||||
|
||||
cat > "$work/LICENSE.txt" <<EOF
|
||||
Portable build tools bundled by WiiCompiled
|
||||
|
||||
clang/lld/llvm-ar $llvm_version (pruned from the official LLVM release for Linux/$llvm_release_arch)
|
||||
https://github.com/llvm/llvm-project/releases/tag/llvmorg-$llvm_version
|
||||
Apache License v2.0 with LLVM Exceptions:
|
||||
https://github.com/llvm/llvm-project/blob/llvmorg-$llvm_version/LICENSE.TXT
|
||||
|
||||
CMake $cmake_version
|
||||
https://github.com/Kitware/CMake
|
||||
BSD 3-Clause License
|
||||
|
||||
Ninja $ninja_version
|
||||
https://github.com/ninja-build/ninja
|
||||
Apache License 2.0
|
||||
EOF
|
||||
|
||||
echo "prepare-portable-tools.sh: testing the toolchain..."
|
||||
test_dir=$(mktemp -d)
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
cat > "$test_dir/t.cpp" <<'EOF'
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
int main() {
|
||||
std::vector<int> v{1, 2, 3};
|
||||
int sum = 0;
|
||||
for (int x : v) sum += x;
|
||||
return sum == 6 ? 0 : 1;
|
||||
}
|
||||
EOF
|
||||
"$work/bin/clang++" -std=c++20 -fuse-ld=lld "$test_dir/t.cpp" -o "$test_dir/t"
|
||||
"$test_dir/t"
|
||||
|
||||
# Also exercised together through CMake+Ninja, exactly how local-build.sh drives them - a plain
|
||||
# clang++ invocation above would not catch a broken CMAKE_ROOT (Modules/Templates) or a Ninja that
|
||||
# can't find the compiler.
|
||||
cat > "$test_dir/CMakeLists.txt" <<'EOF'
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(test CXX)
|
||||
add_executable(test t.cpp)
|
||||
EOF
|
||||
"$work/bin/cmake" -S "$test_dir" -B "$test_dir/build" -G Ninja \
|
||||
-DCMAKE_MAKE_PROGRAM="$work/bin/ninja" -DCMAKE_CXX_COMPILER="$work/bin/clang++" >/dev/null
|
||||
"$work/bin/cmake" --build "$test_dir/build" >/dev/null
|
||||
"$test_dir/build/test"
|
||||
|
||||
rm -rf "$test_dir"
|
||||
trap - EXIT
|
||||
|
||||
rm -rf "$toolchain_dir"
|
||||
mv "$work" "$toolchain_dir"
|
||||
echo "prepare-portable-tools.sh: toolchain ready at $toolchain_dir ($(du -sh "$toolchain_dir" | cut -f1))"
|
||||
@@ -1,6 +1,19 @@
|
||||
<img width="4190" height="1232" alt="wiicomplogofinalfinalfinalev2MADEBY_INKWRECK_plzcredit" src="https://github.com/user-attachments/assets/df7a3f2e-5336-479a-b4c0-968dd578726d" />
|
||||
|
||||
# WiiCompiled
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/patchzyy/Wiicompiled/releases"><img alt="Windows 10 / 11, x64" src="https://img.shields.io/badge/Windows-10%20%2F%2011%20%C2%B7%20x64-0078D4"></a>
|
||||
<a href="https://github.com/patchzyy/Wiicompiled/releases"><img alt="Linux, x64 / ARM64" src="https://img.shields.io/badge/Linux-x64%20%2F%20ARM64-FCC624?logo=linux&logoColor=white"></a>
|
||||
<a href="https://github.com/patchzyy/Wiicompiled/releases"><img alt="macOS 14+, Apple Silicon" src="https://img.shields.io/badge/macOS-14%2B%20%C2%B7%20Apple%20Silicon-0A84FF?logo=apple&logoColor=white"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="#building-from-source"><img alt="PowerPC static recompilation" src="https://img.shields.io/badge/PowerPC-static%20recompilation-FF9F0A"></a>
|
||||
<a href="#retro-rewind"><img alt="Retro Rewind supported" src="https://img.shields.io/badge/Retro%20Rewind-supported-FF375F"></a>
|
||||
<a href="https://github.com/TeamWheelWizard/WheelWizard/releases"><img alt="Install with Wheel Wizard" src="https://img.shields.io/badge/install%20with-Wheel%20Wizard-8B5CF6"></a>
|
||||
<a href="LICENSE"><img alt="License: GPLv3" src="https://img.shields.io/badge/license-GPLv3-2EA44F?logo=gnu&logoColor=white"></a>
|
||||
</p>
|
||||
|
||||
A native PC port of Mario Kart Wii, made with static recompilation.
|
||||
|
||||
There's no emulator in the loop, no interpreter, no JIT, no PowerPC
|
||||
@@ -46,26 +59,45 @@ Press **F10** while the game window has focus:
|
||||
- Internal resolution
|
||||
- FPS counter
|
||||
- Controller assignment for all four ports
|
||||
- Full per-controller button mapping
|
||||
- Full per-controller button mapping, including the bumpers
|
||||
- Dolphin-syntax input expressions and GCPadNew.ini import
|
||||
- Controller vibration on/off
|
||||
- Volume, instant mute, and the music ducking toggle
|
||||
|
||||
Everything you change is saved to `Config.toml` on the spot and restored next launch.
|
||||
|
||||
**Real controller support.**
|
||||
Controllers are fed to the game as a GameCube controller.
|
||||
The port does NOT pretend to be a Wii Remote or Classic Controller.
|
||||
Mappings are positional (`south`, `east`, `west`, `north`) rather than Xbox-labelled, so the
|
||||
same config makes sense on Xbox, PlayStation, Nintendo and generic SDL pads alike, and extra
|
||||
inputs like paddles, touchpads and share buttons show up when the hardware reports them.
|
||||
**Dolphin-compatible input expressions.**
|
||||
Each GameCube control can carry an expression in Dolphin's input syntax, with the same operators
|
||||
and the same functions.
|
||||
A Dolphin `GCPadNew.ini` can be imported directly from the F10 bar.
|
||||
|
||||
**Vibration toggle.**
|
||||
Force feedback can be turned off for every port at once.
|
||||
The official Wii U / Switch GameCube adapter (WUP-028) works too; as with Dolphin, on Windows the
|
||||
adapter must be switched to the WinUSB driver once (Zadig).
|
||||
|
||||
**Real Wii Remotes over Bluetooth.**
|
||||
Pair a Wii Remote with Windows (Settings > Bluetooth > Add device, press 1+2 or SYNC, leave the
|
||||
PIN empty)
|
||||
|
||||
Known limitations of the Wii Remote path:
|
||||
- No IR pointer yet: menus are navigated with the D-pad and A (the game treats the remote as
|
||||
pointing away from the screen).
|
||||
- Battery level is not reported to the game and the remote's speaker is not implemented.
|
||||
- Only the Wii Remote's own accelerometer is calibrated; the Nunchuk's uses SDL's fixed zero point.
|
||||
- The Classic Controller's L/R triggers reach the game as digital (full pull on click): SDL does not
|
||||
expose their analog travel.
|
||||
- Turn the Wii Remote support off in that menu if you use a Mayflash DolphinBar, which already
|
||||
presents the remote as a regular gamepad.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Windows 10 or 11, 64-bit
|
||||
- GPU: GTX 1650 / RX 6400 / Arc A310 or higher
|
||||
- CPU: Intel Core i5-8400 / AMD Ryzen 5 2600 (4c/6c, ~3.5GHz+) or higher
|
||||
- About 20 GB of free disk space during installation (Final game size ~5 GB)
|
||||
- macOS 14 (Sonoma) or later on Apple Silicon
|
||||
- On macOS, Apple Xcode Command Line Tools (Setup opens Apple's installer when they are missing)
|
||||
- A clean, unmodified **PAL `RMCP01`** disc image of Mario Kart Wii, dumped by you. ISO, GCM,
|
||||
GCZ, CISO, WBFS, WIA and RVZ are accepted.
|
||||
|
||||
@@ -86,6 +118,7 @@ image under Settings, turn on **WiiCompiled (beta)**, and hit install from the H
|
||||
Wheel Wizard downloads the setup tool from this repo and walks you through install, updates and
|
||||
launching. The backend itself is deliberately command-line only, Wheel Wizard is a wrapper around it.
|
||||
|
||||
|
||||
> [!CAUTION]
|
||||
> Only take builds from this repository's
|
||||
> [Releases](https://github.com/patchzyy/Wiicompiled/releases) page. If someone's sharing an
|
||||
@@ -124,7 +157,9 @@ The default test suite needs no binaries and no host C++ compiler, so you can ha
|
||||
translator without any game data around.
|
||||
|
||||
For everything beyond that, feeding in your own `main.dol`/`StaticR.rel`, running the
|
||||
translation, generating the manifest and build graph, and compiling. see [`translator/README.md`](translator/README.md).
|
||||
translation, generating the manifest and build graph, and compiling, see [`translator/README.md`](translator/README.md).
|
||||
|
||||
For a step-by-step guide on compiling both WiiCompiled and Retro Rewind from source on macOS (Apple Silicon), see the [macOS Build Guide](docs/building-macos.md).
|
||||
|
||||
## FAQ
|
||||
|
||||
@@ -173,7 +208,7 @@ AI coding tools were used during development of this project.
|
||||
All translated output is verified against real hardware behavior and most importantly, physics accuracy is proven synced across Wii, Dolphin, and WiiCompiled (see FAQ).
|
||||
|
||||
## Credits
|
||||
|
||||
- **inkwreck** - making the logo
|
||||
- **[aurora](https://github.com/encounter/aurora)** - the GX rendering/windowing backend this
|
||||
project's whole graphics layer sits on. MIT licensed.
|
||||
- **[Dawn](https://dawn.googlesource.com/dawn)** - Google's WebGPU implementation, powering
|
||||
|
||||
@@ -26,10 +26,6 @@ Aurora itself vendors:
|
||||
(shagkur) and Dave Murphy (WinterMute). `aurora-main/lib/card/SRAM.hpp`.
|
||||
Source: <https://github.com/devkitPro/libogc>
|
||||
|
||||
> [!NOTE]
|
||||
> Upstream aurora ships `assets/screenshot.png`, a rendered frame from a different Nintendo
|
||||
> title. It is intentionally omitted from this repository.
|
||||
|
||||
### Dolphin Emulator data files - GPL-2.0-or-later
|
||||
|
||||
Copyright (c) 2003+ Dolphin Emulator Project.
|
||||
@@ -118,13 +114,16 @@ Source: <https://github.com/higan-emu/libco>. Full license text:
|
||||
|
||||
## Fetched at build time and redistributed in release builds
|
||||
|
||||
These are pinned in `aurora-main/extern/CMakeLists.txt`, `aurora-main/CMakeLists.txt` and
|
||||
`aurora-main/cmake/AuroraDawnProvider.cmake`. They are not stored in this repository; the build
|
||||
downloads them, and release installers carry the resulting binaries. Their license texts are
|
||||
included in the installer's `licenses/` folder.
|
||||
These are pinned in `aurora-main/extern/CMakeLists.txt`, `aurora-main/CMakeLists.txt`,
|
||||
`aurora-main/cmake/AuroraDawnProvider.cmake`, and (for Mbed TLS) `runtime/CMakeLists.txt`. They are
|
||||
not stored in this repository; the build downloads them - each fetch is pinned to an exact version
|
||||
with a checked SHA-256 - and links or redistributes the resulting binaries. Their license texts are
|
||||
included in the installer's `licenses/` folder. The Windows installer bundles the pinned source
|
||||
trees themselves (fetched by `Launcher/Prepare-Dependencies.ps1`) so end-user builds run offline.
|
||||
|
||||
| Component | Version | License | Upstream |
|
||||
| --- | --- | --- | --- |
|
||||
| Mbed TLS | 3.6.7 | Apache-2.0 / GPL-2.0-or-later | <https://github.com/Mbed-TLS/mbedtls> |
|
||||
| Dawn (WebGPU) | `v20260603.191052` prebuilt | BSD-3-Clause | <https://dawn.googlesource.com/dawn> |
|
||||
| Tint (part of Dawn) | with Dawn | BSD-3-Clause | <https://dawn.googlesource.com/dawn> |
|
||||
| DirectXShaderCompiler (`dxcompiler.dll`) | with Dawn | NCSA / University of Illinois Open Source | <https://github.com/microsoft/DirectXShaderCompiler> |
|
||||
@@ -133,7 +132,7 @@ included in the installer's `licenses/` folder.
|
||||
| Abseil | LTS 20240722.0 | Apache-2.0 | <https://github.com/abseil/abseil-cpp> |
|
||||
| Dear ImGui | 1.91.9b-docking | MIT | <https://github.com/ocornut/imgui> |
|
||||
| {fmt} | 11.1.4 | MIT | <https://github.com/fmtlib/fmt> |
|
||||
| xxHash | 0.8.3 | BSD-2-Clause | <https://github.com/Cyan4973/xxHash> |
|
||||
| xxHash | 0.8.4 | BSD-2-Clause | <https://github.com/Cyan4973/xxHash> |
|
||||
| zlib | 1.3.2 | zlib | <https://github.com/madler/zlib> |
|
||||
| libpng | 1.6.58 | PNG Reference Library License v2 | <https://github.com/pnggroup/libpng> |
|
||||
| FreeType | 2.14.3 | **FreeType License (FTL)** - see below | <https://freetype.org/> |
|
||||
|
||||
Submodule
+1
Submodule aurora-main added at 5506c5dc53
@@ -1,29 +0,0 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
ColumnLimit: 120
|
||||
UseTab: Never
|
||||
TabWidth: 2
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
IndentCaseLabels: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
Cpp11BracedListStyle: true
|
||||
NamespaceIndentation: None
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
SortIncludes: false
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
@@ -1,10 +0,0 @@
|
||||
.buildcache/
|
||||
.DS_Store
|
||||
.idea/
|
||||
.cache/
|
||||
.vscode/
|
||||
.vs/
|
||||
build/
|
||||
cmake-build-*/
|
||||
CMakeUserPresets.json
|
||||
out/
|
||||
@@ -1,85 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(aurora LANGUAGES C CXX)
|
||||
if (APPLE)
|
||||
enable_language(OBJC)
|
||||
endif()
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
option(AURORA_ENABLE_GX "Enable GX implementation and WebGPU renderer" ON)
|
||||
option(AURORA_ENABLE_DVD "Enable DVD implementation backed by nod" OFF) # TODO: need to fix tests
|
||||
option(AURORA_ENABLE_CARD "Enable CARD implementation based on kabufuda" ON)
|
||||
option(AURORA_CACHE_USE_ZSTD "Compress WebGPU cache entries with zstd" ON)
|
||||
|
||||
# Dependency versions
|
||||
set(AURORA_DAWN_VERSION "v20260603.191052" CACHE STRING "Dawn version tag (https://github.com/encounter/dawn-build/releases)")
|
||||
set(AURORA_SDL3_VERSION "3.4.4" CACHE STRING "SDL3 version tag (https://github.com/libsdl-org/SDL/releases)")
|
||||
set(AURORA_NOD_VERSION "v2.0.0-alpha.8" CACHE STRING "nod version tag (https://github.com/encounter/nod/releases)")
|
||||
set(AURORA_LIBUSB_VERSION "1.0.30" CACHE STRING "libusb version tag (https://github.com/libusb/libusb/releases)")
|
||||
|
||||
# Platform-specific defaults
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
# Cross-compiling: vendor everything, don't use system packages
|
||||
set(_default_provider "vendor")
|
||||
set(_default_linkage "static")
|
||||
else ()
|
||||
set(_default_provider "auto")
|
||||
if (WIN32)
|
||||
set(_default_linkage "shared")
|
||||
else ()
|
||||
set(_default_linkage "static")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Dawn/WebGPU (if AURORA_ENABLE_GX)
|
||||
set(AURORA_DAWN_PROVIDER "${_default_provider}" CACHE STRING
|
||||
"How to provide Dawn: auto, vendor (build from source), system (find_package/imported), package (download prebuilt)")
|
||||
set_property(CACHE AURORA_DAWN_PROVIDER PROPERTY STRINGS auto vendor system package)
|
||||
set(AURORA_DAWN_LINKAGE "${_default_linkage}" CACHE STRING "Dawn linkage type preference")
|
||||
set_property(CACHE AURORA_DAWN_LINKAGE PROPERTY STRINGS shared static)
|
||||
|
||||
# SDL3
|
||||
set(AURORA_SDL3_PROVIDER "${_default_provider}" CACHE STRING
|
||||
"How to provide SDL3: auto, vendor (build from source), system (find_package/imported), or package (download prebuilt)")
|
||||
set_property(CACHE AURORA_SDL3_PROVIDER PROPERTY STRINGS auto vendor system package)
|
||||
set(AURORA_SDL3_LINKAGE "${_default_linkage}" CACHE STRING "SDL3 linkage type preference")
|
||||
set_property(CACHE AURORA_SDL3_LINKAGE PROPERTY STRINGS shared static)
|
||||
option(AURORA_SDL3_LIBUSB "Build the vendored SDL3 with libusb on Windows (official GameCube adapter support)" ON)
|
||||
|
||||
# nod (if AURORA_ENABLE_DVD)
|
||||
set(AURORA_NOD_PROVIDER "${_default_provider}" CACHE STRING
|
||||
"How to provide nod: auto, vendor (build from source), system (find_package/imported), package (download prebuilt)")
|
||||
set_property(CACHE AURORA_NOD_PROVIDER PROPERTY STRINGS auto vendor system package)
|
||||
set(AURORA_NOD_LINKAGE "${_default_linkage}" CACHE STRING "nod linkage type preference")
|
||||
set_property(CACHE AURORA_NOD_LINKAGE PROPERTY STRINGS shared static)
|
||||
|
||||
add_subdirectory(extern)
|
||||
|
||||
include(cmake/aurora_core.cmake)
|
||||
include(cmake/aurora_os.cmake)
|
||||
if (AURORA_ENABLE_GX)
|
||||
include(cmake/aurora_gx.cmake)
|
||||
include(cmake/aurora_gd.cmake)
|
||||
endif ()
|
||||
include(cmake/aurora_pad.cmake)
|
||||
include(cmake/aurora_ms.cmake)
|
||||
include(cmake/aurora_si.cmake)
|
||||
include(cmake/aurora_main.cmake)
|
||||
include(cmake/aurora_mtx.cmake)
|
||||
include(cmake/aurora_vi.cmake)
|
||||
if(AURORA_ENABLE_CARD)
|
||||
include(cmake/aurora_card.cmake)
|
||||
endif()
|
||||
if (AURORA_ENABLE_DVD)
|
||||
include(cmake/aurora_dvd.cmake)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
add_subdirectory(examples)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_CROSSCOMPILING)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2022 Luke Street
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,46 +0,0 @@
|
||||
<div align="center">
|
||||
<img src="assets/aurora.png" alt="Logo" width="640">
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
Aurora is a source-level GameCube & Wii compatibility layer intended for use with game decompilation projects.
|
||||
|
||||
Originally developed for use in [Metaforce](https://github.com/AxioDL/metaforce), a Metroid Prime reverse engineering project.
|
||||
It now powers several completed source ports, including [Dusklight](https://github.com/TwilitRealm/dusklight).
|
||||
|
||||
### Features
|
||||
|
||||
- Application layer using SDL3
|
||||
- Runs on Windows, Linux, macOS, iOS, tvOS, Android
|
||||
- GX compatibility layer
|
||||
- Graphics API support: D3D12, Vulkan, Metal
|
||||
- Highly accurate and performant GX implementation
|
||||
- Robust pipeline cache system with "transferable" cache support for releases
|
||||
- Dolphin-compatible texture pack support
|
||||
- Widescreen & resolution scaling support
|
||||
- Custom APIs for offscreen rendering
|
||||
- PAD compatibility layer
|
||||
- Utilizes `SDL_Gamepad` for wide controller support, including GameCube controller adapters
|
||||
- Automatically saves and loads controller bindings and port mappings
|
||||
- Gyro & mouse support
|
||||
- DVD compatibility layer
|
||||
- Utilizes [nod](https://github.com/encounter/nod) to support all GameCube/Wii disc image types, including RVZ
|
||||
- CARD compatibility layer
|
||||
- Full compatibility with Dolphin `.gci` and `.raw` for game saves
|
||||
- [Dear ImGui](https://github.com/ocornut/imgui) built-in for simple debug UIs
|
||||
|
||||
### Graphics
|
||||
|
||||
The GX compatibility layer is built on top of [WebGPU](https://www.w3.org/TR/webgpu/), a cross-platform graphics API
|
||||
abstraction layer. WebGPU allows targeting all major platforms simultaneously with minimal overhead. The WebGPU
|
||||
implementation used is Chromium's [Dawn](https://dawn.googlesource.com/dawn/).
|
||||
|
||||

|
||||
|
||||
### Building
|
||||
|
||||
See [docs/building.md](docs/building.md) for build instructions, CMake integration, and configuration options.
|
||||
|
||||
### License
|
||||
|
||||
Aurora is licensed under the [MIT License](LICENSE).
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,55 +0,0 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# aurora_copy_runtime_dlls(<executable_target> [<additional_targets>...])
|
||||
#
|
||||
# POST_BUILD command that copies all TARGET_RUNTIME_DLLS from the given targets
|
||||
# next to the executable, plus any extra DLLs that Dawn loads dynamically
|
||||
# (dxcompiler.dll, dxil.dll).
|
||||
function(aurora_copy_runtime_dlls target)
|
||||
if (NOT WIN32)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
# Copy TARGET_RUNTIME_DLLS for each target
|
||||
foreach (_t IN ITEMS ${target} ${ARGN})
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${_t}> $<TARGET_FILE_DIR:${target}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
# Copy DXC DLLs that Dawn loads via LoadLibrary at runtime
|
||||
if (TARGET dawn::webgpu_dawn)
|
||||
get_target_property(_dawn_loc dawn::webgpu_dawn IMPORTED_LOCATION)
|
||||
if (NOT _dawn_loc)
|
||||
get_target_property(_dawn_loc dawn::webgpu_dawn IMPORTED_LOCATION_RELEASE)
|
||||
endif ()
|
||||
if (_dawn_loc)
|
||||
cmake_path(GET _dawn_loc PARENT_PATH _dawn_bin_dir)
|
||||
foreach (_dll IN ITEMS dxcompiler.dll dxil.dll)
|
||||
if (EXISTS "${_dawn_bin_dir}/${_dll}")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_dawn_bin_dir}/${_dll}" $<TARGET_FILE_DIR:${target}>
|
||||
)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
# aurora_install_runtime_dlls(<executable_target> <install_destination>)
|
||||
#
|
||||
# INSTALL rule that copies all DLLs already placed next to the built target
|
||||
# into the install destination.
|
||||
function(aurora_install_runtime_dlls target install_destination)
|
||||
if (NOT WIN32)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
install(CODE
|
||||
"file(GLOB _aurora_runtime_dlls \"$<TARGET_FILE_DIR:${target}>/*.dll\")\n\
|
||||
if(_aurora_runtime_dlls)\n\
|
||||
file(INSTALL DESTINATION \"${install_destination}\" TYPE FILE FILES \${_aurora_runtime_dlls})\n\
|
||||
endif()"
|
||||
)
|
||||
endfunction()
|
||||
@@ -1,255 +0,0 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# Resolve Dawn/WebGPU dependency based on AURORA_DAWN_PROVIDER and AURORA_DAWN_LINKAGE.
|
||||
#
|
||||
# After this module runs:
|
||||
# - dawn::webgpu_dawn target is available
|
||||
# - dawn::dawncpp_headers target is available (for tests)
|
||||
# - DAWN_ENABLE_* backend variables are set for the target platform
|
||||
# - AURORA_DAWN_IS_SHARED is set to TRUE/FALSE
|
||||
|
||||
# When using a non-vendored Dawn, we don't get DAWN_ENABLE_* from its build.
|
||||
# Infer from the target platform instead.
|
||||
function(_aurora_dawn_set_platform_backends)
|
||||
if (WIN32)
|
||||
set(DAWN_ENABLE_D3D12 ON CACHE INTERNAL "")
|
||||
# Disable D3D11 because this Aurora fork does not support it.
|
||||
set(DAWN_ENABLE_D3D11 OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_VULKAN ON CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_METAL OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_DESKTOP_GL OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_OPENGLES OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_NULL ON CACHE INTERNAL "")
|
||||
elseif (APPLE)
|
||||
set(DAWN_ENABLE_D3D12 OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_D3D11 OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_VULKAN OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_METAL ON CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_DESKTOP_GL OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_OPENGLES OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_NULL ON CACHE INTERNAL "")
|
||||
else () # Linux / other
|
||||
set(DAWN_ENABLE_D3D12 OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_D3D11 OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_VULKAN ON CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_METAL OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_DESKTOP_GL OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_OPENGLES OFF CACHE INTERNAL "")
|
||||
set(DAWN_ENABLE_NULL ON CACHE INTERNAL "")
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
# ── Auto: resolve provider based on platform availability ──
|
||||
set(_aurora_dawn_provider "${AURORA_DAWN_PROVIDER}")
|
||||
if (_aurora_dawn_provider STREQUAL "auto")
|
||||
# Prebuilt Dawn packages available for: windows-{amd64,arm64}, linux-{x86_64,aarch64}, darwin-{arm64,x86_64}
|
||||
set(_has_package FALSE)
|
||||
if (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64|x86_64|ARM64|aarch64)$")
|
||||
set(_has_package TRUE)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|aarch64)$")
|
||||
set(_has_package TRUE)
|
||||
elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|x86_64)$")
|
||||
set(_has_package TRUE)
|
||||
endif ()
|
||||
|
||||
if (_has_package)
|
||||
set(_aurora_dawn_provider "package")
|
||||
else ()
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(Dawn QUIET)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
if (Dawn_FOUND)
|
||||
set(_aurora_dawn_provider "system")
|
||||
else ()
|
||||
set(_aurora_dawn_provider "vendor")
|
||||
endif ()
|
||||
endif ()
|
||||
set(AURORA_DAWN_PROVIDER "${_aurora_dawn_provider}" CACHE STRING "" FORCE)
|
||||
message(STATUS "aurora: Dawn auto-resolved provider: ${_aurora_dawn_provider}")
|
||||
endif ()
|
||||
|
||||
if (_aurora_dawn_provider STREQUAL "vendor")
|
||||
# ── Vendor: FetchContent build from source ──
|
||||
if (NOT TARGET webgpu_dawn)
|
||||
message(STATUS "aurora: Fetching Dawn (provider=vendor, linkage=${AURORA_DAWN_LINKAGE})")
|
||||
|
||||
if (AURORA_DAWN_LINKAGE STREQUAL "shared")
|
||||
set(DAWN_BUILD_MONOLITHIC_LIBRARY SHARED CACHE INTERNAL
|
||||
"Bundle all dawn components into a single shared library.")
|
||||
else ()
|
||||
set(DAWN_BUILD_MONOLITHIC_LIBRARY STATIC CACHE INTERNAL
|
||||
"Bundle all dawn components into a single static library.")
|
||||
endif ()
|
||||
set(DAWN_BUILD_SAMPLES OFF CACHE INTERNAL "Disable Dawn sample applications")
|
||||
set(DAWN_BUILD_BENCHMARKS OFF CACHE INTERNAL "Disable Dawn benchmarks")
|
||||
set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING OFF CACHE INTERNAL "Disable Dawn GLFW windowing")
|
||||
set(DAWN_ENABLE_DESKTOP_GL OFF CACHE INTERNAL "Enable compilation of the OpenGL backend")
|
||||
set(DAWN_ENABLE_OPENGLES OFF CACHE INTERNAL "Enable compilation of the OpenGL ES backend")
|
||||
set(DAWN_FETCH_DEPENDENCIES ON CACHE INTERNAL
|
||||
"Use fetch_dawn_dependencies.py as an alternative to using depot_tools")
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
set(DAWN_USE_WAYLAND ON CACHE INTERNAL "Enable support for Wayland surface")
|
||||
endif ()
|
||||
set(TINT_BUILD_TESTS OFF CACHE INTERNAL "Build tests")
|
||||
set(TINT_BUILD_CMD_TOOLS OFF CACHE INTERNAL "Build the Tint command line tools")
|
||||
if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY OR CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$")
|
||||
set(ABSL_MSVC_STATIC_RUNTIME OFF CACHE INTERNAL "Link static runtime libraries")
|
||||
else ()
|
||||
set(ABSL_MSVC_STATIC_RUNTIME ON CACHE INTERNAL "Link static runtime libraries")
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(dawn
|
||||
URL "https://github.com/google/dawn/archive/refs/tags/${AURORA_DAWN_VERSION}.tar.gz"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(dawn)
|
||||
if (NOT TARGET webgpu_dawn)
|
||||
message(FATAL_ERROR "Failed to make dawn available")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing Dawn")
|
||||
endif ()
|
||||
|
||||
if (AURORA_DAWN_LINKAGE STREQUAL "shared")
|
||||
set(AURORA_DAWN_IS_SHARED TRUE PARENT_SCOPE)
|
||||
else ()
|
||||
set(AURORA_DAWN_IS_SHARED FALSE PARENT_SCOPE)
|
||||
endif ()
|
||||
|
||||
elseif (_aurora_dawn_provider STREQUAL "system")
|
||||
# ── System: find_package(Dawn) ──
|
||||
message(STATUS "aurora: Using system Dawn (provider=system)")
|
||||
if (NOT Dawn_FOUND)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(Dawn REQUIRED)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
endif ()
|
||||
if (NOT TARGET dawn::webgpu_dawn)
|
||||
message(FATAL_ERROR "find_package(Dawn) succeeded but dawn::webgpu_dawn target not found")
|
||||
endif ()
|
||||
_aurora_dawn_set_platform_backends()
|
||||
|
||||
get_target_property(_dawn_type dawn::webgpu_dawn TYPE)
|
||||
if (_dawn_type STREQUAL "SHARED_LIBRARY")
|
||||
set(AURORA_DAWN_IS_SHARED TRUE PARENT_SCOPE)
|
||||
else ()
|
||||
set(AURORA_DAWN_IS_SHARED FALSE PARENT_SCOPE)
|
||||
endif ()
|
||||
|
||||
elseif (_aurora_dawn_provider STREQUAL "package")
|
||||
# ── Package: download prebuilt Dawn install tree ──
|
||||
if (NOT AURORA_DAWN_PACKAGE_URL)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" _dawn_system)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _dawn_arch)
|
||||
if (_dawn_system STREQUAL "windows")
|
||||
if (_dawn_arch STREQUAL "x86_64")
|
||||
set(_dawn_arch "amd64")
|
||||
elseif (_dawn_arch STREQUAL "aarch64")
|
||||
set(_dawn_arch "arm64")
|
||||
endif ()
|
||||
endif ()
|
||||
set(AURORA_DAWN_PACKAGE_URL
|
||||
"https://github.com/encounter/dawn-build/releases/download/${AURORA_DAWN_VERSION}/dawn-${_dawn_system}-${_dawn_arch}.tar.gz")
|
||||
|
||||
# A release asset is mutable: the same tag has already served two different windows-amd64 archives,
|
||||
# and a cached extraction is never re-verified. Pin the digest for the combinations we ship.
|
||||
if (NOT AURORA_DAWN_PACKAGE_URL_HASH
|
||||
AND AURORA_DAWN_VERSION STREQUAL "v20260603.191052"
|
||||
AND _dawn_system STREQUAL "windows" AND _dawn_arch STREQUAL "amd64")
|
||||
set(AURORA_DAWN_PACKAGE_URL_HASH
|
||||
"SHA256=7785373d569b3b0237918ec9c523239f7d0667857c5ea8242e3cdfde95e6aeab")
|
||||
endif ()
|
||||
endif ()
|
||||
message(STATUS "aurora: Fetching prebuilt Dawn package from ${AURORA_DAWN_PACKAGE_URL}")
|
||||
|
||||
set(_dawn_prebuilt_hash_argument "")
|
||||
if (AURORA_DAWN_PACKAGE_URL_HASH)
|
||||
set(_dawn_prebuilt_hash_argument URL_HASH "${AURORA_DAWN_PACKAGE_URL_HASH}")
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(dawn_prebuilt
|
||||
URL "${AURORA_DAWN_PACKAGE_URL}"
|
||||
${_dawn_prebuilt_hash_argument}
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(dawn_prebuilt)
|
||||
|
||||
# Detect package layout: may be nested in a subdirectory
|
||||
set(_dawn_pkg_dir "${dawn_prebuilt_SOURCE_DIR}")
|
||||
file(GLOB _dawn_subdirs
|
||||
"${dawn_prebuilt_SOURCE_DIR}/dawn-*"
|
||||
"${dawn_prebuilt_SOURCE_DIR}/Dawn-*"
|
||||
)
|
||||
foreach (_sd IN LISTS _dawn_subdirs)
|
||||
if (IS_DIRECTORY "${_sd}")
|
||||
set(_dawn_pkg_dir "${_sd}")
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (IS_DIRECTORY "${dawn_prebuilt_SOURCE_DIR}/dawn-install")
|
||||
set(_dawn_pkg_dir "${dawn_prebuilt_SOURCE_DIR}/dawn-install")
|
||||
endif ()
|
||||
|
||||
# Static Dawn packages may link Threads::Threads
|
||||
find_package(Threads QUIET)
|
||||
|
||||
# Find DawnConfig.cmake in the package
|
||||
set(_dawn_cmake_found FALSE)
|
||||
foreach (_cmake_path
|
||||
"${_dawn_pkg_dir}/lib/cmake/Dawn"
|
||||
"${_dawn_pkg_dir}/lib64/cmake/Dawn"
|
||||
"${_dawn_pkg_dir}/cmake/Dawn"
|
||||
"${_dawn_pkg_dir}/cmake"
|
||||
)
|
||||
if (EXISTS "${_cmake_path}/DawnConfig.cmake")
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(Dawn REQUIRED CONFIG PATHS "${_cmake_path}" NO_DEFAULT_PATH)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
set(_dawn_cmake_found TRUE)
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if (NOT _dawn_cmake_found OR NOT TARGET dawn::webgpu_dawn)
|
||||
message(FATAL_ERROR
|
||||
"Dawn package does not contain DawnConfig.cmake.\n"
|
||||
"Searched: ${_dawn_pkg_dir}/{lib,lib64,cmake}/cmake/Dawn/\n"
|
||||
"The package must be a Dawn install tree built with DAWN_ENABLE_INSTALL=ON.")
|
||||
endif ()
|
||||
|
||||
_aurora_dawn_set_platform_backends()
|
||||
|
||||
get_target_property(_dawn_pkg_type dawn::webgpu_dawn TYPE)
|
||||
if (_dawn_pkg_type STREQUAL "SHARED_LIBRARY")
|
||||
set(AURORA_DAWN_IS_SHARED TRUE PARENT_SCOPE)
|
||||
|
||||
else ()
|
||||
set(AURORA_DAWN_IS_SHARED FALSE PARENT_SCOPE)
|
||||
endif ()
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Invalid AURORA_DAWN_PROVIDER: ${AURORA_DAWN_PROVIDER} "
|
||||
"(must be auto, vendor, system, or package)")
|
||||
endif ()
|
||||
|
||||
# Ensure dawn::dawncpp_headers target exists (needed by tests).
|
||||
# When Dawn is vendored, this target is created by Dawn's CMake.
|
||||
# For package/system providers, create it from the same include dirs.
|
||||
if (NOT TARGET dawn::dawncpp_headers)
|
||||
add_library(dawn_dawncpp_headers INTERFACE IMPORTED GLOBAL)
|
||||
get_target_property(_dawn_inc dawn::webgpu_dawn INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if (NOT _dawn_inc)
|
||||
if (TARGET dawn::dawn_public_config)
|
||||
get_target_property(_dawn_inc dawn::dawn_public_config INTERFACE_INCLUDE_DIRECTORIES)
|
||||
endif ()
|
||||
endif ()
|
||||
if (_dawn_inc)
|
||||
target_include_directories(dawn_dawncpp_headers INTERFACE ${_dawn_inc})
|
||||
else ()
|
||||
target_link_libraries(dawn_dawncpp_headers INTERFACE dawn::webgpu_dawn)
|
||||
endif ()
|
||||
add_library(dawn::dawncpp_headers ALIAS dawn_dawncpp_headers)
|
||||
endif ()
|
||||
@@ -1,43 +0,0 @@
|
||||
# libusb for SDL3's HIDAPI joystick drivers on Windows.
|
||||
#
|
||||
# The official GameCube adapter (WUP-028) is a vendor-specific USB device, not HID, so SDL3
|
||||
# can only reach it through libusb - which the official SDL3 packages leave out. The vendored
|
||||
# SDL3 build compiles libusb from the pinned upstream release and links it in statically.
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(libusb
|
||||
URL "https://github.com/libusb/libusb/releases/download/v${AURORA_LIBUSB_VERSION}/libusb-${AURORA_LIBUSB_VERSION}.tar.bz2"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
)
|
||||
# Upstream ships no CMakeLists.txt, so this only populates the source tree.
|
||||
FetchContent_MakeAvailable(libusb)
|
||||
|
||||
set(_libusb_root "${libusb_SOURCE_DIR}/libusb")
|
||||
add_library(usb-1.0 STATIC
|
||||
"${_libusb_root}/core.c"
|
||||
"${_libusb_root}/descriptor.c"
|
||||
"${_libusb_root}/hotplug.c"
|
||||
"${_libusb_root}/io.c"
|
||||
"${_libusb_root}/strerror.c"
|
||||
"${_libusb_root}/sync.c"
|
||||
"${_libusb_root}/os/events_windows.c"
|
||||
"${_libusb_root}/os/threads_windows.c"
|
||||
"${_libusb_root}/os/windows_common.c"
|
||||
"${_libusb_root}/os/windows_usbdk.c"
|
||||
"${_libusb_root}/os/windows_winusb.c"
|
||||
)
|
||||
target_include_directories(usb-1.0
|
||||
PUBLIC "${_libusb_root}"
|
||||
PRIVATE "${CMAKE_CURRENT_LIST_DIR}/libusb" "${_libusb_root}/os"
|
||||
)
|
||||
set_target_properties(usb-1.0 PROPERTIES UNITY_BUILD OFF)
|
||||
add_library(LibUSB::LibUSB ALIAS usb-1.0)
|
||||
|
||||
# SDL's FindLibUSB expects an installed copy. Satisfy its presence checks with this target
|
||||
# instead: the alias pre-empts the imported target it would otherwise create, and the link
|
||||
# probe is answered up front because the archive does not exist until build time.
|
||||
set(LibUSB_INCLUDE_PATH "${_libusb_root}" CACHE PATH "" FORCE)
|
||||
set(LibUSB_LIBRARY "usb-1.0" CACHE STRING "" FORCE)
|
||||
set(HAVE_LIBUSB_H 1 CACHE INTERNAL "" FORCE)
|
||||
set(SDL_HIDAPI_LIBUSB ON CACHE BOOL "" FORCE)
|
||||
set(SDL_HIDAPI_LIBUSB_SHARED OFF CACHE BOOL "" FORCE)
|
||||
@@ -1,150 +0,0 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# Resolve nod dependency based on AURORA_NOD_PROVIDER.
|
||||
#
|
||||
# After this module runs:
|
||||
# - nod::nod target is available
|
||||
#
|
||||
# AURORA_NOD_LINKAGE controls shared vs static linkage:
|
||||
# - "shared" (default): prefer nod::nod_shared
|
||||
# - "static": prefer nod::nod_static
|
||||
|
||||
# ── Auto: resolve provider based on platform availability ──
|
||||
set(_aurora_nod_provider "${AURORA_NOD_PROVIDER}")
|
||||
if (_aurora_nod_provider STREQUAL "auto")
|
||||
# Prebuilt nod packages available for: windows-x86_64, linux-x86_64, macos-arm64
|
||||
set(_has_package FALSE)
|
||||
if (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64)$")
|
||||
set(_has_package TRUE)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64)$")
|
||||
set(_has_package TRUE)
|
||||
elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64)$")
|
||||
set(_has_package TRUE)
|
||||
endif ()
|
||||
|
||||
if (_has_package)
|
||||
set(_aurora_nod_provider "package")
|
||||
else ()
|
||||
find_package(nod QUIET CONFIG)
|
||||
if (nod_FOUND)
|
||||
set(_aurora_nod_provider "system")
|
||||
else ()
|
||||
set(_aurora_nod_provider "vendor")
|
||||
endif ()
|
||||
endif ()
|
||||
set(AURORA_NOD_PROVIDER "${_aurora_nod_provider}" CACHE STRING "" FORCE)
|
||||
message(STATUS "aurora: nod auto-resolved provider: ${_aurora_nod_provider}")
|
||||
endif ()
|
||||
|
||||
if (_aurora_nod_provider STREQUAL "vendor")
|
||||
# ── Vendor: FetchContent + Corrosion build from source ──
|
||||
if (NOT TARGET nod::nod)
|
||||
message(STATUS "aurora: Building nod (provider=vendor, linkage=${AURORA_NOD_LINKAGE})")
|
||||
|
||||
# Corrosion may default to the host Rust target triple (commonly x86_64 on
|
||||
# Windows). Force Rust to i686 for true Win32 builds so nod and its vendored
|
||||
# compression libraries are built for the same architecture as the C/C++ build.
|
||||
if (WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(Rust_CARGO_TARGET "i686-pc-windows-msvc" CACHE STRING "Rust target triple" FORCE)
|
||||
set(Rust_RUSTUP_INSTALL_MISSING_TARGET ON CACHE BOOL "Allow Corrosion to install missing Rust targets" FORCE)
|
||||
message(STATUS "aurora: forcing Rust_CARGO_TARGET=${Rust_CARGO_TARGET} for Win32 nod build")
|
||||
endif ()
|
||||
|
||||
# Control whether nod builds shared, static, or both.
|
||||
# Save/restore BUILD_SHARED_LIBS to avoid leaking into other subdirectories.
|
||||
set(_aurora_nod_saved_bsl "${BUILD_SHARED_LIBS}")
|
||||
if (AURORA_NOD_LINKAGE STREQUAL "static")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else ()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(aurora_nod
|
||||
GIT_REPOSITORY "https://github.com/encounter/nod.git"
|
||||
GIT_TAG "${AURORA_NOD_VERSION}"
|
||||
GIT_SHALLOW TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(aurora_nod)
|
||||
set(BUILD_SHARED_LIBS "${_aurora_nod_saved_bsl}")
|
||||
unset(_aurora_nod_saved_bsl)
|
||||
if (NOT TARGET nod::nod)
|
||||
message(FATAL_ERROR "Failed to make nod available")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing nod")
|
||||
endif ()
|
||||
|
||||
elseif (_aurora_nod_provider STREQUAL "system")
|
||||
# ── System: find preinstalled nod ──
|
||||
message(STATUS "aurora: Using system nod (provider=system, linkage=${AURORA_NOD_LINKAGE})")
|
||||
|
||||
if (NOT nod_FOUND)
|
||||
set(_aurora_nod_saved_bsl "${BUILD_SHARED_LIBS}")
|
||||
if (AURORA_NOD_LINKAGE STREQUAL "static")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else ()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif ()
|
||||
|
||||
find_package(nod REQUIRED CONFIG)
|
||||
set(BUILD_SHARED_LIBS "${_aurora_nod_saved_bsl}")
|
||||
unset(_aurora_nod_saved_bsl)
|
||||
endif ()
|
||||
if (NOT TARGET nod::nod)
|
||||
message(FATAL_ERROR "find_package(nod) succeeded but nod::nod target not found")
|
||||
endif ()
|
||||
message(STATUS "aurora: Found nod via find_package(nod)")
|
||||
|
||||
elseif (_aurora_nod_provider STREQUAL "package")
|
||||
# ── Package: download prebuilt nod library ──
|
||||
if (NOT AURORA_NOD_PACKAGE_URL)
|
||||
if (WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_nod_platform "windows-x86_64")
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$")
|
||||
set(_nod_platform "linux-x86_64")
|
||||
elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)$")
|
||||
set(_nod_platform "macos-arm64")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"AURORA_NOD_PROVIDER=package requires AURORA_NOD_PACKAGE_URL on this platform.\n"
|
||||
"Prebuilt packages: https://github.com/encounter/nod/releases")
|
||||
endif ()
|
||||
set(AURORA_NOD_PACKAGE_URL
|
||||
"https://github.com/encounter/nod/releases/download/${AURORA_NOD_VERSION}/libnod-${_nod_platform}.tar.gz")
|
||||
endif ()
|
||||
message(STATUS "aurora: Fetching prebuilt nod package (provider=package, linkage=${AURORA_NOD_LINKAGE})")
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(nod_prebuilt
|
||||
URL "${AURORA_NOD_PACKAGE_URL}"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(nod_prebuilt)
|
||||
|
||||
# The prebuilt package ships a CMake config that creates nod::nod_shared,
|
||||
# nod::nod_static, and a default nod::nod (based on BUILD_SHARED_LIBS).
|
||||
# Set BUILD_SHARED_LIBS so the config selects the right default target.
|
||||
set(_aurora_nod_saved_bsl "${BUILD_SHARED_LIBS}")
|
||||
if (AURORA_NOD_LINKAGE STREQUAL "static")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else ()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif ()
|
||||
find_package(nod REQUIRED CONFIG
|
||||
PATHS "${nod_prebuilt_SOURCE_DIR}"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
set(BUILD_SHARED_LIBS "${_aurora_nod_saved_bsl}")
|
||||
unset(_aurora_nod_saved_bsl)
|
||||
if (NOT TARGET nod::nod)
|
||||
message(FATAL_ERROR "Prebuilt nod package did not provide nod::nod target")
|
||||
endif ()
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Invalid AURORA_NOD_PROVIDER: ${AURORA_NOD_PROVIDER} "
|
||||
"(must be auto, vendor, system, or package)")
|
||||
endif ()
|
||||
@@ -1,152 +0,0 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# Resolve SDL3 dependency based on AURORA_SDL3_PROVIDER and AURORA_SDL3_LINKAGE.
|
||||
#
|
||||
# After this module runs, the variable AURORA_SDL3_TARGET is set to the
|
||||
# appropriate target name for use in target_link_libraries() calls.
|
||||
|
||||
# Select the SDL3 target matching the requested linkage.
|
||||
function(_aurora_sdl3_select_target)
|
||||
if (AURORA_SDL3_LINKAGE STREQUAL "static")
|
||||
if (TARGET SDL3::SDL3-static)
|
||||
set(AURORA_SDL3_TARGET SDL3::SDL3-static CACHE INTERNAL "")
|
||||
message(STATUS "aurora: Using static SDL3")
|
||||
return()
|
||||
elseif (TARGET SDL3::SDL3)
|
||||
message(WARNING "aurora: Static SDL3 requested but only shared is available")
|
||||
set(AURORA_SDL3_TARGET SDL3::SDL3 CACHE INTERNAL "")
|
||||
message(STATUS "aurora: Using shared SDL3")
|
||||
return()
|
||||
endif ()
|
||||
else ()
|
||||
if (TARGET SDL3::SDL3)
|
||||
set(AURORA_SDL3_TARGET SDL3::SDL3 CACHE INTERNAL "")
|
||||
message(STATUS "aurora: Using shared SDL3")
|
||||
return()
|
||||
elseif (TARGET SDL3::SDL3-static)
|
||||
message(WARNING "aurora: Shared SDL3 requested but only static is available")
|
||||
set(AURORA_SDL3_TARGET SDL3::SDL3-static CACHE INTERNAL "")
|
||||
message(STATUS "aurora: Using static SDL3")
|
||||
return()
|
||||
endif ()
|
||||
endif ()
|
||||
message(FATAL_ERROR "No SDL3 target found (looked for SDL3::SDL3 and SDL3::SDL3-static)")
|
||||
endfunction()
|
||||
|
||||
# ── Auto: resolve provider based on platform availability ──
|
||||
set(_aurora_sdl3_provider "${AURORA_SDL3_PROVIDER}")
|
||||
if (_aurora_sdl3_provider STREQUAL "auto")
|
||||
# Prebuilt SDL3 packages are available for Windows (MSVC and MinGW)
|
||||
if (WIN32)
|
||||
set(_aurora_sdl3_provider "package")
|
||||
else ()
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(SDL3 QUIET)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
if (SDL3_FOUND)
|
||||
set(_aurora_sdl3_provider "system")
|
||||
else ()
|
||||
set(_aurora_sdl3_provider "vendor")
|
||||
endif ()
|
||||
endif ()
|
||||
set(AURORA_SDL3_PROVIDER "${_aurora_sdl3_provider}" CACHE STRING "" FORCE)
|
||||
message(STATUS "aurora: SDL3 auto-resolved provider: ${_aurora_sdl3_provider}")
|
||||
endif ()
|
||||
|
||||
if (_aurora_sdl3_provider STREQUAL "system")
|
||||
# ── System: find_package(SDL3) ──
|
||||
message(STATUS "aurora: Using system SDL3 (provider=system)")
|
||||
if (NOT SDL3_FOUND)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(SDL3 REQUIRED)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
endif ()
|
||||
_aurora_sdl3_select_target()
|
||||
|
||||
elseif (_aurora_sdl3_provider STREQUAL "package")
|
||||
# ── Package: download custom build or official SDL3 development package ──
|
||||
if (NOT AURORA_SDL3_PACKAGE_URL)
|
||||
if (MINGW)
|
||||
# WIN32 is also true for MinGW. Select the matching GNU-ABI package
|
||||
# before considering Visual C++ packages.
|
||||
set(AURORA_SDL3_PACKAGE_URL
|
||||
"https://github.com/libsdl-org/SDL/releases/download/release-${AURORA_SDL3_VERSION}/SDL3-devel-${AURORA_SDL3_VERSION}-mingw.tar.gz")
|
||||
elseif (WIN32)
|
||||
# We have custom builds of SDL3 for Win32 x86/AMD64 with libusb support included
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64|x86)$")
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _sdl3_arch)
|
||||
set(AURORA_SDL3_PACKAGE_URL
|
||||
"https://github.com/encounter/sdl3-build/releases/download/v${AURORA_SDL3_VERSION}/SDL3-windows-${_sdl3_arch}.tar.gz")
|
||||
else ()
|
||||
set(AURORA_SDL3_PACKAGE_URL
|
||||
"https://github.com/libsdl-org/SDL/releases/download/release-${AURORA_SDL3_VERSION}/SDL3-devel-${AURORA_SDL3_VERSION}-VC.zip")
|
||||
endif ()
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"AURORA_SDL3_PROVIDER=package requires AURORA_SDL3_PACKAGE_URL on non-Windows platforms.\n"
|
||||
"Official SDL3 packages: https://github.com/libsdl-org/SDL/releases")
|
||||
endif ()
|
||||
endif ()
|
||||
message(STATUS "aurora: Fetching prebuilt SDL3 package from ${AURORA_SDL3_PACKAGE_URL}")
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(sdl3_prebuilt
|
||||
URL "${AURORA_SDL3_PACKAGE_URL}"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(sdl3_prebuilt)
|
||||
|
||||
set(_sdl3_search_paths
|
||||
"${sdl3_prebuilt_SOURCE_DIR}/cmake"
|
||||
"${sdl3_prebuilt_SOURCE_DIR}/lib/cmake/SDL3"
|
||||
"${sdl3_prebuilt_SOURCE_DIR}"
|
||||
)
|
||||
file(GLOB _sdl3_subdirs "${sdl3_prebuilt_SOURCE_DIR}/SDL3-*")
|
||||
foreach (_sd IN LISTS _sdl3_subdirs)
|
||||
list(APPEND _sdl3_search_paths
|
||||
"${_sd}/cmake"
|
||||
"${_sd}/lib/cmake/SDL3"
|
||||
"${_sd}"
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(SDL3 REQUIRED CONFIG PATHS ${_sdl3_search_paths} NO_DEFAULT_PATH)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
_aurora_sdl3_select_target()
|
||||
|
||||
elseif (_aurora_sdl3_provider STREQUAL "vendor")
|
||||
# ── Vendor: FetchContent build from source ──
|
||||
if (NOT TARGET SDL3-static AND NOT TARGET SDL3-shared)
|
||||
message(STATUS "aurora: Fetching SDL3 (provider=vendor)")
|
||||
|
||||
if (AURORA_SDL3_LINKAGE STREQUAL "static")
|
||||
set(SDL_STATIC ON CACHE BOOL "Build SDL3 static library" FORCE)
|
||||
set(SDL_SHARED OFF CACHE BOOL "Build SDL3 shared library" FORCE)
|
||||
else ()
|
||||
set(SDL_STATIC OFF CACHE BOOL "Build SDL3 static library" FORCE)
|
||||
set(SDL_SHARED ON CACHE BOOL "Build SDL3 shared library" FORCE)
|
||||
endif ()
|
||||
if (WIN32)
|
||||
set(SDL_LIBC ON CACHE BOOL "Use the system C library" FORCE)
|
||||
if (AURORA_SDL3_LIBUSB)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/AuroraLibUSB.cmake")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(SDL
|
||||
URL "https://github.com/libsdl-org/SDL/releases/download/release-${AURORA_SDL3_VERSION}/SDL3-${AURORA_SDL3_VERSION}.tar.gz"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL)
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing SDL3")
|
||||
endif ()
|
||||
_aurora_sdl3_select_target()
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Invalid AURORA_SDL3_PROVIDER: ${AURORA_SDL3_PROVIDER} "
|
||||
"(must be auto, vendor, system, or package)")
|
||||
endif ()
|
||||
@@ -1,17 +0,0 @@
|
||||
add_library(aurora_card STATIC
|
||||
lib/card/BlockAllocationTable.cpp
|
||||
lib/card/CardRawFile.cpp
|
||||
lib/card/CardGciFolder.cpp
|
||||
lib/card/Directory.cpp
|
||||
lib/card/DolphinCardPath.cpp
|
||||
lib/card/File.cpp
|
||||
lib/card/FileIO.cpp
|
||||
lib/card/SRAM.cpp
|
||||
lib/card/Util.cpp
|
||||
lib/dolphin/card.cpp
|
||||
)
|
||||
add_library(aurora::card ALIAS aurora_card)
|
||||
set_target_properties(aurora_card PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_link_libraries(aurora_card PUBLIC aurora::core)
|
||||
target_include_directories(aurora_card PRIVATE include)
|
||||
@@ -1,64 +0,0 @@
|
||||
add_library(aurora_core STATIC
|
||||
lib/aurora.cpp
|
||||
lib/input.cpp
|
||||
lib/window.cpp
|
||||
lib/logging.cpp
|
||||
lib/system_info.cpp
|
||||
lib/system_info.hpp
|
||||
)
|
||||
add_library(aurora::core ALIAS aurora_core)
|
||||
set_target_properties(aurora_core PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_compile_definitions(aurora_core PUBLIC AURORA TARGET_PC)
|
||||
target_include_directories(aurora_core PUBLIC include)
|
||||
target_link_libraries(aurora_core PUBLIC fmt::fmt ${AURORA_SDL3_TARGET} xxhash)
|
||||
target_link_libraries(aurora_core PRIVATE absl::btree absl::flat_hash_map sqlite3 TracyClient)
|
||||
if (AURORA_ENABLE_GX AND AURORA_CACHE_USE_ZSTD)
|
||||
target_compile_definitions(aurora_core PRIVATE AURORA_CACHE_USE_ZSTD)
|
||||
target_link_libraries(aurora_core PRIVATE libzstd_static)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
# stuff for fetching system info.
|
||||
target_link_libraries(aurora_core PRIVATE ntdll dxgi advapi32 user32)
|
||||
elseif (APPLE)
|
||||
target_sources(aurora_core PRIVATE lib/system_info_mac.mm)
|
||||
endif ()
|
||||
|
||||
if (AURORA_ENABLE_GX)
|
||||
target_sources(aurora_core PRIVATE lib/imgui.cpp)
|
||||
target_link_libraries(aurora_core PUBLIC imgui)
|
||||
endif ()
|
||||
|
||||
if (AURORA_ENABLE_GX)
|
||||
target_compile_definitions(aurora_core PUBLIC AURORA_ENABLE_GX WEBGPU_DAWN)
|
||||
target_sources(aurora_core PRIVATE lib/webgpu/gpu.cpp lib/webgpu/gpu_cache.cpp lib/dawn/BackendBinding.cpp)
|
||||
target_link_libraries(aurora_core PRIVATE dawn::webgpu_dawn)
|
||||
if (DAWN_ENABLE_VULKAN)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_VULKAN)
|
||||
endif ()
|
||||
if (DAWN_ENABLE_METAL)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_METAL)
|
||||
target_sources(aurora_core PRIVATE lib/dawn/MetalBinding.mm)
|
||||
set_source_files_properties(lib/dawn/MetalBinding.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
target_link_options(aurora_core PUBLIC "LINKER:-weak_framework,Metal")
|
||||
endif ()
|
||||
if (DAWN_ENABLE_D3D11)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_D3D11)
|
||||
endif ()
|
||||
if (DAWN_ENABLE_D3D12)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_D3D12)
|
||||
endif ()
|
||||
if (DAWN_ENABLE_DESKTOP_GL OR DAWN_ENABLE_OPENGLES)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_OPENGL)
|
||||
if (DAWN_ENABLE_DESKTOP_GL)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_DESKTOP_GL)
|
||||
endif ()
|
||||
if (DAWN_ENABLE_OPENGLES)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_OPENGLES)
|
||||
endif ()
|
||||
endif ()
|
||||
if (DAWN_ENABLE_NULL)
|
||||
target_compile_definitions(aurora_core PRIVATE DAWN_ENABLE_BACKEND_NULL)
|
||||
endif ()
|
||||
endif ()
|
||||
@@ -1,10 +0,0 @@
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/AuroraNodProvider.cmake)
|
||||
|
||||
add_library(aurora_dvd STATIC lib/dolphin/dvd/dvd.cpp)
|
||||
add_library(aurora::dvd ALIAS aurora_dvd)
|
||||
set_target_properties(aurora_dvd PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_compile_definitions(aurora_dvd PUBLIC AURORA TARGET_PC)
|
||||
target_include_directories(aurora_dvd PUBLIC include)
|
||||
target_link_libraries(aurora_dvd PUBLIC nod::nod ${AURORA_SDL3_TARGET})
|
||||
target_link_libraries(aurora_dvd PRIVATE fmt::fmt)
|
||||
@@ -1,16 +0,0 @@
|
||||
add_library(aurora_gd STATIC
|
||||
lib/dolphin/gd/GDBase.cpp
|
||||
lib/dolphin/gd/GDGeometry.cpp
|
||||
lib/dolphin/gd/GDIndirect.cpp
|
||||
lib/dolphin/gd/GDLight.cpp
|
||||
lib/dolphin/gd/GDPixel.cpp
|
||||
lib/dolphin/gd/GDTev.cpp
|
||||
lib/dolphin/gd/GDTexture.cpp
|
||||
lib/dolphin/gd/GDTransform.cpp
|
||||
lib/dolphin/gd/gd.hpp
|
||||
lib/dolphin/gd/GDAurora.cpp
|
||||
)
|
||||
add_library(aurora::gd ALIAS aurora_gd)
|
||||
set_target_properties(aurora_gd PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_link_libraries(aurora_gd PUBLIC aurora::gx)
|
||||
@@ -1,47 +0,0 @@
|
||||
add_library(aurora_gx STATIC
|
||||
lib/gfx/clear.cpp
|
||||
lib/gfx/common.cpp
|
||||
lib/gfx/depth_peek.cpp
|
||||
lib/gfx/efb_ram_copy.cpp
|
||||
lib/gfx/efb_ram_encoder.cpp
|
||||
lib/gfx/pipeline_cache.cpp
|
||||
lib/gfx/dds_io.cpp
|
||||
lib/gfx/tex_copy_conv.cpp
|
||||
lib/gfx/tex_palette_conv.cpp
|
||||
lib/gfx/texture.cpp
|
||||
lib/gfx/texture_convert.cpp
|
||||
lib/gfx/texture_replacement.cpp
|
||||
lib/gx/command_processor.cpp
|
||||
lib/gx/fifo.cpp
|
||||
lib/gx/frame_interpolation.cpp
|
||||
lib/gx/gx.cpp
|
||||
lib/gx/pipeline.cpp
|
||||
lib/gx/shader.cpp
|
||||
lib/gx/shader_info.cpp
|
||||
lib/dolphin/gx/GXBump.cpp
|
||||
lib/dolphin/gx/GXCull.cpp
|
||||
lib/dolphin/gx/GXCpu2Efb.cpp
|
||||
lib/dolphin/gx/GXDispList.cpp
|
||||
lib/dolphin/gx/GXDraw.cpp
|
||||
lib/dolphin/gx/GXExtra.cpp
|
||||
lib/dolphin/gx/GXFifo.cpp
|
||||
lib/dolphin/gx/GXFrameBuffer.cpp
|
||||
lib/dolphin/gx/GXGeometry.cpp
|
||||
lib/dolphin/gx/GXGet.cpp
|
||||
lib/dolphin/gx/GXLighting.cpp
|
||||
lib/dolphin/gx/GXManage.cpp
|
||||
lib/dolphin/gx/GXPixel.cpp
|
||||
lib/dolphin/gx/GXTev.cpp
|
||||
lib/dolphin/gx/GXTexture.cpp
|
||||
lib/dolphin/gx/GXTransform.cpp
|
||||
lib/dolphin/gx/GXVert.cpp
|
||||
lib/dolphin/gx/GXAurora.cpp
|
||||
lib/gfx/png_io.cpp
|
||||
lib/gfx/png_io.hpp
|
||||
)
|
||||
add_library(aurora::gx ALIAS aurora_gx)
|
||||
set_target_properties(aurora_gx PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_link_libraries(aurora_gx PUBLIC aurora::core xxhash)
|
||||
target_link_libraries(aurora_gx PRIVATE absl::btree absl::flat_hash_map dawn::webgpu_dawn sqlite3 TracyClient PNG::PNG)
|
||||
target_compile_definitions(aurora_gx PRIVATE WEBGPU_DAWN)
|
||||
@@ -1,6 +0,0 @@
|
||||
add_library(aurora_main STATIC lib/main.cpp)
|
||||
add_library(aurora::main ALIAS aurora_main)
|
||||
set_target_properties(aurora_main PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_main PUBLIC include)
|
||||
target_link_libraries(aurora_main PUBLIC ${AURORA_SDL3_TARGET})
|
||||
@@ -1,7 +0,0 @@
|
||||
add_library(aurora_ms STATIC lib/dolphin/ms/mouse.cpp)
|
||||
add_library(aurora::ms ALIAS aurora_ms)
|
||||
set_target_properties(aurora_ms PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_ms PUBLIC include)
|
||||
target_link_libraries(aurora_ms PUBLIC aurora::core)
|
||||
target_link_libraries(aurora_ms PRIVATE absl::flat_hash_map)
|
||||
@@ -1,12 +0,0 @@
|
||||
add_library(aurora_mtx STATIC
|
||||
lib/dolphin/mtx/mtx.c
|
||||
lib/dolphin/mtx/mtxstack.c
|
||||
lib/dolphin/mtx/mtxvec.c
|
||||
lib/dolphin/mtx/mtx44.c
|
||||
lib/dolphin/mtx/vec.c
|
||||
lib/dolphin/mtx/quat.c
|
||||
)
|
||||
add_library(aurora::mtx ALIAS aurora_mtx)
|
||||
set_target_properties(aurora_mtx PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_mtx PUBLIC include)
|
||||
@@ -1,14 +0,0 @@
|
||||
add_library(aurora_os STATIC lib/dolphin/os/OSInit.cpp
|
||||
lib/dolphin/os/OSMemory.cpp
|
||||
lib/dolphin/os/internal.hpp
|
||||
lib/dolphin/os/OSBootInfo.cpp
|
||||
lib/dolphin/os/OSTime.cpp
|
||||
lib/dolphin/os/OSArena.cpp
|
||||
lib/dolphin/os/OSAlloc.cpp
|
||||
lib/dolphin/os/OSAddress.cpp
|
||||
lib/dolphin/AR.cpp)
|
||||
add_library(aurora::os ALIAS aurora_os)
|
||||
set_target_properties(aurora_os PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_os PUBLIC include)
|
||||
target_link_libraries(aurora_os PRIVATE aurora::core)
|
||||
@@ -1,7 +0,0 @@
|
||||
add_library(aurora_pad STATIC lib/dolphin/pad/pad.cpp)
|
||||
add_library(aurora::pad ALIAS aurora_pad)
|
||||
set_target_properties(aurora_pad PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_pad PUBLIC include)
|
||||
target_link_libraries(aurora_pad PUBLIC aurora::core aurora::si)
|
||||
target_link_libraries(aurora_pad PRIVATE absl::flat_hash_map)
|
||||
@@ -1,7 +0,0 @@
|
||||
add_library(aurora_si STATIC lib/dolphin/si/si.cpp)
|
||||
add_library(aurora::si ALIAS aurora_si)
|
||||
set_target_properties(aurora_si PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_include_directories(aurora_si PUBLIC include)
|
||||
target_link_libraries(aurora_si PUBLIC aurora::core)
|
||||
target_link_libraries(aurora_si PRIVATE absl::flat_hash_map)
|
||||
@@ -1,7 +0,0 @@
|
||||
add_library(aurora_vi STATIC
|
||||
lib/dolphin/vi/vi.cpp
|
||||
)
|
||||
add_library(aurora::vi ALIAS aurora_vi)
|
||||
set_target_properties(aurora_vi PROPERTIES FOLDER "aurora")
|
||||
|
||||
target_link_libraries(aurora_vi PUBLIC aurora::core)
|
||||
@@ -1,8 +0,0 @@
|
||||
/* libusb build configuration for the Windows backend (MinGW/Clang). */
|
||||
#pragma once
|
||||
|
||||
#define PLATFORM_WINDOWS 1
|
||||
#define ENABLE_LOGGING 1
|
||||
#define DEFAULT_VISIBILITY
|
||||
#define HAVE_STRUCT_TIMESPEC 1
|
||||
#define PRINTF_FORMAT(a, b) __attribute__((__format__(__printf__, a, b)))
|
||||
@@ -1,55 +0,0 @@
|
||||
# Building
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- CMake 3.25 or later
|
||||
- A C++20 compatible compiler (Clang, GCC, or MSVC)
|
||||
- Git (for cloning)
|
||||
|
||||
## Building the Examples
|
||||
|
||||
To build Aurora's included examples:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/encounter/aurora.git
|
||||
cd aurora
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build . --target simple
|
||||
```
|
||||
|
||||
The `simple` example demonstrates a minimal Aurora application with a blue screen. The built executable will be in `build/examples/simple`.
|
||||
|
||||
## Using Aurora in Your Project
|
||||
|
||||
Aurora is designed to be integrated as a library in GameCube/Wii decompilation projects.
|
||||
|
||||
**CMakeLists.txt example:**
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(your_game)
|
||||
|
||||
# Add Aurora as a subdirectory
|
||||
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
|
||||
|
||||
# Create your executable
|
||||
add_executable(your_game src/main.c)
|
||||
|
||||
# Link against Aurora components
|
||||
target_link_libraries(your_game PRIVATE
|
||||
aurora::core
|
||||
aurora::gx
|
||||
aurora::main
|
||||
aurora::vi
|
||||
)
|
||||
```
|
||||
|
||||
See [examples/simple.c](../examples/simple.c) for a minimal application template.
|
||||
|
||||
## CMake Options
|
||||
|
||||
- `AURORA_ENABLE_GX` (default: ON) - Enable GX implementation and WebGPU renderer
|
||||
- `AURORA_ENABLE_DVD` (default: OFF) - Enable DVD implementation backed by nod
|
||||
- `AURORA_ENABLE_CARD` (default: ON) - Enable CARD implementation based on kabufuda
|
||||
- `AURORA_CACHE_USE_ZSTD` (default: ON) - Compress WebGPU cache entries with zstd
|
||||
@@ -1,4 +0,0 @@
|
||||
if (AURORA_ENABLE_GX)
|
||||
add_executable(simple simple.c)
|
||||
target_link_libraries(simple PRIVATE aurora::core aurora::gx aurora::main aurora::vi)
|
||||
endif ()
|
||||
@@ -1,90 +0,0 @@
|
||||
#include <aurora/aurora.h>
|
||||
#include <aurora/event.h>
|
||||
#include <aurora/main.h>
|
||||
#include <dolphin/gx.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void log_callback(AuroraLogLevel level, const char* module, const char* message, unsigned int len) {
|
||||
const char* levelStr;
|
||||
FILE* out = stdout;
|
||||
switch (level) {
|
||||
case LOG_DEBUG:
|
||||
levelStr = "DEBUG";
|
||||
break;
|
||||
case LOG_INFO:
|
||||
levelStr = "INFO";
|
||||
break;
|
||||
case LOG_WARNING:
|
||||
levelStr = "WARNING";
|
||||
break;
|
||||
case LOG_ERROR:
|
||||
levelStr = "ERROR";
|
||||
out = stderr;
|
||||
break;
|
||||
case LOG_FATAL:
|
||||
levelStr = "FATAL";
|
||||
out = stderr;
|
||||
break;
|
||||
}
|
||||
fprintf(out, "[%s: %s;%s]\n", levelStr, module, message);
|
||||
if (level == LOG_FATAL) {
|
||||
fflush(out);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void draw() {
|
||||
GXSetCopyClear(
|
||||
(GXColor){
|
||||
.r = 0,
|
||||
.g = 0,
|
||||
.b = 100,
|
||||
.a = 255,
|
||||
},
|
||||
GX_MAX_Z24);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const AuroraConfig config = {
|
||||
.appName = "Demo",
|
||||
.logCallback = &log_callback,
|
||||
};
|
||||
AuroraInfo initInfo = aurora_initialize(argc, argv, &config);
|
||||
|
||||
bool exiting = false;
|
||||
bool paused = false;
|
||||
while (!exiting) {
|
||||
const AuroraEvent* event = aurora_update();
|
||||
while (event != NULL && event->type != AURORA_NONE) {
|
||||
switch (event->type) {
|
||||
case AURORA_EXIT:
|
||||
exiting = true;
|
||||
break;
|
||||
case AURORA_PAUSED:
|
||||
paused = true;
|
||||
break;
|
||||
case AURORA_UNPAUSED:
|
||||
paused = false;
|
||||
break;
|
||||
case AURORA_WINDOW_RESIZED:
|
||||
initInfo.windowSize = event->windowSize;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++event;
|
||||
}
|
||||
if (exiting || paused || !aurora_begin_frame()) {
|
||||
continue;
|
||||
}
|
||||
draw();
|
||||
aurora_end_frame();
|
||||
}
|
||||
|
||||
aurora_shutdown();
|
||||
return 0;
|
||||
}
|
||||
Vendored
-310
@@ -1,310 +0,0 @@
|
||||
include(FetchContent)
|
||||
|
||||
# Don't build tests for third party dependencies
|
||||
set(BUILD_TESTING OFF CACHE INTERNAL "Build tests")
|
||||
set(SKIP_INSTALL_ALL ON)
|
||||
if (NOT DEFINED BUILD_SHARED_LIBS)
|
||||
set(_USE_SHARED ON)
|
||||
else ()
|
||||
set(_USE_SHARED OFF)
|
||||
endif ()
|
||||
|
||||
function(aurora_find_package_global)
|
||||
set(_PREV_FIND_PACKAGE_TARGETS_GLOBAL ${CMAKE_FIND_PACKAGE_TARGETS_GLOBAL})
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
|
||||
find_package(${ARGV})
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ${_PREV_FIND_PACKAGE_TARGETS_GLOBAL})
|
||||
endfunction()
|
||||
|
||||
if (AURORA_ENABLE_GX)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/AuroraDawnProvider.cmake)
|
||||
endif ()
|
||||
|
||||
# Abseil is needed for core libraries. It normally comes via Dawn's vendor build.
|
||||
# Otherwise prefer a system package and only fetch it as a last resort.
|
||||
if (NOT TARGET absl::flat_hash_map OR NOT TARGET absl::btree)
|
||||
aurora_find_package_global(absl CONFIG QUIET GLOBAL)
|
||||
endif ()
|
||||
|
||||
if (TARGET absl::flat_hash_map AND TARGET absl::btree)
|
||||
message(STATUS "aurora: Using system/existing abseil")
|
||||
else ()
|
||||
message(STATUS "aurora: Fetching abseil-cpp (standalone)")
|
||||
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY OR CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$")
|
||||
set(ABSL_MSVC_STATIC_RUNTIME OFF CACHE INTERNAL "Link static runtime libraries")
|
||||
else()
|
||||
set(ABSL_MSVC_STATIC_RUNTIME ON CACHE INTERNAL "Link static runtime libraries")
|
||||
endif()
|
||||
set(ABSL_PROPAGATE_CXX_STD ON)
|
||||
FetchContent_Declare(abseil-cpp
|
||||
URL https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(abseil-cpp)
|
||||
if (NOT TARGET absl::flat_hash_map OR NOT TARGET absl::btree)
|
||||
message(FATAL_ERROR "Failed to make abseil-cpp available")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/AuroraSDL3Provider.cmake)
|
||||
|
||||
if (NOT TARGET xxhash)
|
||||
message(STATUS "aurora: Fetching xxhash")
|
||||
FetchContent_Declare(xxhash
|
||||
URL https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.3.tar.gz
|
||||
URL_HASH SHA256=aae608dfe8213dfd05d909a57718ef82f30722c392344583d3f39050c7f29a80
|
||||
SOURCE_SUBDIR cmake_unofficial
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
set(XXHASH_BUILD_XXHSUM OFF CACHE INTERNAL "Build the xxhsum binary")
|
||||
# xxhash uses CMAKE_DEPENDENT_OPTION(BUILD_SHARED_LIBS ...) which writes
|
||||
# a sticky CACHE INTERNAL entry on reconfigure. Undo it afterward.
|
||||
set(_aurora_xxhash_saved_bsl "${BUILD_SHARED_LIBS}")
|
||||
FetchContent_MakeAvailable(xxhash)
|
||||
unset(BUILD_SHARED_LIBS CACHE)
|
||||
set(BUILD_SHARED_LIBS "${_aurora_xxhash_saved_bsl}")
|
||||
unset(_aurora_xxhash_saved_bsl)
|
||||
if (NOT TARGET xxhash)
|
||||
message(FATAL_ERROR "Failed to make xxhash available")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing xxhash")
|
||||
endif ()
|
||||
|
||||
if (NOT TARGET fmt)
|
||||
message(STATUS "aurora: Fetching fmt")
|
||||
FetchContent_Declare(fmt
|
||||
URL https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz
|
||||
URL_HASH SHA256=ac366b7b4c2e9f0dde63a59b3feb5ee59b67974b14ee5dc9ea8ad78aa2c1ee1e
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
if (NOT TARGET fmt)
|
||||
message(FATAL_ERROR "Failed to make fmt available")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing fmt")
|
||||
endif ()
|
||||
|
||||
# fmt 11.1 drops its libc++ transitive includes but still calls malloc/free without <cstdlib>.
|
||||
# Force the missing header for fmt and its consumers until the pinned release is updated.
|
||||
if (MINGW AND TARGET fmt)
|
||||
target_compile_options(fmt PUBLIC
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-include>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:cstdlib>)
|
||||
endif ()
|
||||
|
||||
if (AURORA_ENABLE_GX)
|
||||
if (NOT TARGET ZLIB::ZLIB)
|
||||
aurora_find_package_global(ZLIB QUIET)
|
||||
endif ()
|
||||
if (NOT TARGET ZLIB::ZLIB)
|
||||
message(STATUS "aurora: Fetching zlib")
|
||||
set(_AURORA_ZLIB_SHARED ${_USE_SHARED})
|
||||
# ClangCL injects Clang's C headers into the MSVC resource compiler path, and zlib's DLL version
|
||||
# resource then hits syntax rc.exe cannot parse. Use the resource-free static target here.
|
||||
if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(_AURORA_ZLIB_SHARED OFF)
|
||||
endif ()
|
||||
set(ZLIB_BUILD_SHARED ${_AURORA_ZLIB_SHARED} CACHE BOOL "Enable building zlib shared library" FORCE)
|
||||
set(ZLIB_BUILD_TESTING OFF CACHE BOOL "Enable Zlib Examples as tests" FORCE)
|
||||
set(ZLIB_INSTALL OFF CACHE BOOL "Enable installation of zlib" FORCE)
|
||||
FetchContent_Declare(
|
||||
ZLIB
|
||||
URL https://github.com/madler/zlib/releases/download/v1.3.2/zlib-1.3.2.tar.gz
|
||||
URL_HASH SHA256=bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(ZLIB)
|
||||
if (NOT TARGET ZLIB::ZLIB AND TARGET ZLIB::ZLIBSTATIC)
|
||||
add_library(ZLIB::ZLIB ALIAS zlibstatic)
|
||||
endif ()
|
||||
if (NOT TARGET ZLIB::ZLIB)
|
||||
message(FATAL_ERROR "Failed to make zlib available")
|
||||
endif ()
|
||||
# libpng calls find_package(ZLIB) even when zlib was already provided by FetchContent.
|
||||
file(WRITE "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/ZLIBConfig.cmake"
|
||||
"set(ZLIB_FOUND TRUE)\n"
|
||||
"set(ZLIB_INCLUDE_DIR \"${zlib_SOURCE_DIR}\")\n"
|
||||
"set(ZLIB_INCLUDE_DIRS \"${zlib_BINARY_DIR};${zlib_SOURCE_DIR}\")\n"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (NOT TARGET PNG::PNG)
|
||||
if (TARGET png_shared AND _USE_SHARED)
|
||||
add_library(PNG::PNG ALIAS png_shared)
|
||||
elseif (TARGET png_static)
|
||||
add_library(PNG::PNG ALIAS png_static)
|
||||
else ()
|
||||
aurora_find_package_global(PNG QUIET)
|
||||
endif ()
|
||||
endif ()
|
||||
if (NOT TARGET PNG::PNG)
|
||||
message(STATUS "aurora: Fetching libpng")
|
||||
set(PNG_SHARED ${_USE_SHARED} CACHE BOOL "Build libpng as a shared library" FORCE)
|
||||
set(PNG_TESTS OFF CACHE BOOL "Build the libpng tests" FORCE)
|
||||
set(PNG_TOOLS OFF CACHE BOOL "Build the libpng tools" FORCE)
|
||||
FetchContent_Declare(
|
||||
PNG
|
||||
URL https://github.com/pnggroup/libpng/archive/refs/tags/v1.6.58.tar.gz
|
||||
URL_HASH SHA256=A9D4DF463D36A6E5F9C29BD6F4967312D17E996C1854F3511F833924EB1993CF
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(PNG)
|
||||
if (TARGET png_shared AND _USE_SHARED)
|
||||
add_library(PNG::PNG ALIAS png_shared)
|
||||
elseif (TARGET png_static)
|
||||
add_library(PNG::PNG ALIAS png_static)
|
||||
else ()
|
||||
message(FATAL_ERROR "Failed to make libpng available")
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing libpng")
|
||||
endif ()
|
||||
|
||||
aurora_find_package_global(Freetype QUIET)
|
||||
if (NOT TARGET Freetype::Freetype)
|
||||
message(STATUS "aurora: Fetching Freetype")
|
||||
set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_PNG ON CACHE BOOL "" FORCE)
|
||||
FetchContent_Declare(Freetype
|
||||
URL https://files.twilitrealm.dev/freetype-2.14.3.tar.gz
|
||||
URL_HASH SHA256=e61b31ab26358b946e767ed7eb7f4bb2e507da1cfefeb7a8861ace7fd5c899a1
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(Freetype)
|
||||
add_library(Freetype::Freetype ALIAS freetype)
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing Freetype")
|
||||
endif ()
|
||||
|
||||
if (NOT TARGET imgui)
|
||||
message(STATUS "aurora: Fetching imgui")
|
||||
FetchContent_Declare(imgui
|
||||
URL https://github.com/ocornut/imgui/archive/refs/tags/v1.91.9b-docking.tar.gz
|
||||
URL_HASH SHA256=466fdef9b18de15f0bb6e288e3d00ffa3d82200ec458ce5e4f724a161d9528a5
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(imgui)
|
||||
|
||||
add_library(imgui STATIC
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
${imgui_SOURCE_DIR}/misc/cpp/imgui_stdlib.cpp
|
||||
)
|
||||
target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR})
|
||||
|
||||
add_library(imgui_backends STATIC
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_wgpu.cpp
|
||||
)
|
||||
target_compile_definitions(imgui_backends PRIVATE IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||
target_link_libraries(imgui_backends PRIVATE imgui ${AURORA_SDL3_TARGET} dawn::webgpu_dawn)
|
||||
target_link_libraries(imgui PUBLIC imgui_backends)
|
||||
|
||||
if (TARGET Freetype::Freetype)
|
||||
target_sources(imgui PRIVATE ${imgui_SOURCE_DIR}/misc/freetype/imgui_freetype.cpp)
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_ENABLE_FREETYPE)
|
||||
target_link_libraries(imgui PRIVATE Freetype::Freetype)
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing imgui")
|
||||
endif ()
|
||||
|
||||
if (TARGET imgui)
|
||||
target_include_directories(imgui PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="aurora/imgui_config.h")
|
||||
target_sources(imgui PRIVATE ${PROJECT_SOURCE_DIR}/lib/imgui_config.cpp)
|
||||
target_link_libraries(imgui PRIVATE ${AURORA_SDL3_TARGET})
|
||||
endif ()
|
||||
|
||||
if (NOT TARGET sqlite3)
|
||||
message(STATUS "aurora: Fetching sqlite3")
|
||||
FetchContent_Declare(sqlite3
|
||||
URL https://sqlite.org/2026/sqlite-amalgamation-3510300.zip
|
||||
URL_HASH SHA256=acb1e6f5d832484bf6d32b681e858c38add8b2acdfd42ac5df24b8afb46552b4
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(sqlite3)
|
||||
|
||||
add_library(sqlite3 STATIC ${sqlite3_SOURCE_DIR}/sqlite3.c)
|
||||
target_include_directories(sqlite3 PUBLIC ${sqlite3_SOURCE_DIR})
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing sqlite3")
|
||||
endif ()
|
||||
|
||||
if (AURORA_CACHE_USE_ZSTD)
|
||||
if (NOT TARGET libzstd_static)
|
||||
message(STATUS "aurora: Fetching zstd")
|
||||
set(ZSTD_BUILD_STATIC ON)
|
||||
set(ZSTD_BUILD_SHARED OFF)
|
||||
set(ZSTD_BUILD_PROGRAMS OFF CACHE BOOL "BUILD PROGRAMS" FORCE)
|
||||
set(ZSTD_BUILD_TESTS OFF CACHE BOOL "BUILD TESTS" FORCE)
|
||||
|
||||
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(C_FLAG_WALL TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WALL TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WEXTRA TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WEXTRA TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WUNDEF TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WUNDEF TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WSHADOW TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WSHADOW TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WCAST_ALIGN TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WCAST_ALIGN TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WCAST_QUAL TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WCAST_QUAL TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WSTRICT_PROTOTYPES TRUE CACHE INTERNAL "")
|
||||
set(LD_FLAG_WL_Z_NOEXECSTACK FALSE CACHE INTERNAL "")
|
||||
set(C_FLAG_QUNUSED_ARGUMENTS TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_QUNUSED_ARGUMENTS TRUE CACHE INTERNAL "")
|
||||
set(C_FLAG_WA_NOEXECSTACK TRUE CACHE INTERNAL "")
|
||||
set(CXX_FLAG_WA_NOEXECSTACK TRUE CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
FetchContent_Declare(zstd
|
||||
URL https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz
|
||||
URL_HASH SHA256=eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
SOURCE_SUBDIR build/cmake
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(zstd)
|
||||
else ()
|
||||
message(STATUS "aurora: Using existing zstd")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT TARGET TracyClient)
|
||||
message(STATUS "aurora: Fetching Tracy")
|
||||
|
||||
# Default to off, users can enable the cache variable if they want to use it.
|
||||
set(TRACY_ENABLE OFF CACHE BOOL "Enable Tracy profiling")
|
||||
|
||||
FetchContent_Declare(
|
||||
tracy
|
||||
URL https://github.com/wolfpld/tracy/archive/a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz
|
||||
URL_HASH SHA256=24d342b5127d7f659dc3cf94f24347b348cc736f25b17a691fd7f69541937658
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(tracy)
|
||||
|
||||
if (NOT TARGET TracyClient)
|
||||
message(FATAL_ERROR "Failed to make TracyClient available")
|
||||
endif ()
|
||||
endif ()
|
||||
@@ -1,172 +0,0 @@
|
||||
#ifndef AURORA_AURORA_H
|
||||
#define AURORA_AURORA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
#else
|
||||
#include "stdbool.h"
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BACKEND_AUTO,
|
||||
BACKEND_D3D11,
|
||||
BACKEND_D3D12,
|
||||
BACKEND_METAL,
|
||||
BACKEND_VULKAN,
|
||||
BACKEND_OPENGL,
|
||||
BACKEND_OPENGLES,
|
||||
BACKEND_WEBGPU,
|
||||
BACKEND_NULL,
|
||||
} AuroraBackend;
|
||||
|
||||
typedef enum {
|
||||
LOG_DEBUG,
|
||||
LOG_INFO,
|
||||
LOG_WARNING,
|
||||
LOG_ERROR,
|
||||
LOG_FATAL,
|
||||
} AuroraLogLevel;
|
||||
|
||||
typedef enum {
|
||||
AURORA_DISPLAY_MODE_WINDOWED,
|
||||
AURORA_DISPLAY_MODE_BORDERLESS,
|
||||
AURORA_DISPLAY_MODE_EXCLUSIVE,
|
||||
} AuroraDisplayMode;
|
||||
|
||||
typedef struct {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} AuroraWindowPos;
|
||||
|
||||
typedef struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
/**
|
||||
* Width of the main GX framebuffer.
|
||||
*/
|
||||
uint32_t fb_width;
|
||||
|
||||
/**
|
||||
* Height of the main GX framebuffer.
|
||||
*/
|
||||
uint32_t fb_height;
|
||||
|
||||
/**
|
||||
* The size of the framebuffer used to present to the operating system.
|
||||
* May differ from fb_width if Aurora is instructed to force an aspect ratio or resolution configuration.
|
||||
*/
|
||||
uint32_t native_fb_width;
|
||||
|
||||
/**
|
||||
* The size of the framebuffer used to present to the operating system.
|
||||
* May differ from fb_height if Aurora is instructed to force an aspect ratio or resolution configuration.
|
||||
*/
|
||||
uint32_t native_fb_height;
|
||||
float scale;
|
||||
} AuroraWindowSize;
|
||||
|
||||
typedef struct SDL_Window SDL_Window;
|
||||
typedef struct AuroraEvent AuroraEvent;
|
||||
|
||||
typedef void (*AuroraLogCallback)(AuroraLogLevel level, const char* module, const char* message, unsigned int len);
|
||||
typedef void (*AuroraImGuiInitCallback)(const AuroraWindowSize* size);
|
||||
|
||||
typedef struct {
|
||||
const char* appName;
|
||||
const char* userPath;
|
||||
const char* cachePath;
|
||||
// Read-only application resources. Defaults to SDL_GetBasePath(), which is
|
||||
// where release builds place initial_pipeline_cache.db.
|
||||
const char* resourcesPath;
|
||||
AuroraBackend desiredBackend;
|
||||
uint32_t msaa;
|
||||
uint16_t maxTextureAnisotropy;
|
||||
// No vsync knob exists: the swapchain is always configured for a
|
||||
// non-blocking present mode (Immediate, else Mailbox). See best_present_mode.
|
||||
bool startFullscreen;
|
||||
bool allowJoystickBackgroundEvents;
|
||||
bool pauseOnFocusLost;
|
||||
bool allowTextureReplacements;
|
||||
bool allowTextureDumps;
|
||||
bool disableCopyFilter;
|
||||
// When false, Aurora centers the first window. When true, windowPosX/Y are restored verbatim,
|
||||
// including negative coordinates on monitors left of or above the primary display.
|
||||
bool hasWindowPosition;
|
||||
int32_t windowPosX;
|
||||
int32_t windowPosY;
|
||||
uint32_t windowWidth;
|
||||
uint32_t windowHeight;
|
||||
void* iconRGBA8;
|
||||
uint32_t iconWidth;
|
||||
uint32_t iconHeight;
|
||||
AuroraLogCallback logCallback;
|
||||
AuroraLogLevel logLevel;
|
||||
AuroraImGuiInitCallback imGuiInitCallback;
|
||||
|
||||
/*
|
||||
* The size of the GameCube's main memory, or MEM1 on the Wii.
|
||||
* Note that it will not be allocated at the exact 0x80000000 address, as that cannot be guaranteed.
|
||||
* This can be set to 0 to disable allocating this region.
|
||||
*/
|
||||
uint32_t mem1Size;
|
||||
|
||||
/*
|
||||
* The size of the GameCube's ARAM, or MEM2 on the Wii.
|
||||
* This can be set to 0 to disable allocating this region.
|
||||
*/
|
||||
uint32_t mem2Size;
|
||||
|
||||
// Optional directory for the portable GX pipeline database. When null, the
|
||||
// database is stored in cachePath with Dawn's machine-specific cache.
|
||||
const char* pipelineCachePath;
|
||||
} AuroraConfig;
|
||||
|
||||
typedef struct {
|
||||
AuroraBackend backend;
|
||||
const char* userPath;
|
||||
const char* cachePath;
|
||||
SDL_Window* window;
|
||||
AuroraWindowSize windowSize;
|
||||
} AuroraInfo;
|
||||
|
||||
AuroraInfo aurora_initialize(int argc, char* argv[], const AuroraConfig* config);
|
||||
void aurora_shutdown();
|
||||
const AuroraEvent* aurora_update();
|
||||
bool aurora_begin_frame();
|
||||
void aurora_end_frame();
|
||||
typedef void (*AuroraFrameWorkerWaitCallback)();
|
||||
// Called from the producer thread at bounded intervals while Aurora waits for
|
||||
// the asynchronous frame worker. The callback must not enter Aurora.
|
||||
void aurora_set_frame_worker_wait_callback(AuroraFrameWorkerWaitCallback callback);
|
||||
void aurora_wait_for_frame_worker();
|
||||
bool aurora_wait_for_frame_worker_for(uint32_t timeoutMicros);
|
||||
// Absolute schedule for the next sealed frame, on steady_clock: baseNanos anchors the group and
|
||||
// intervalNanos is the period, so slot k of N+1 fires at base + k*interval/(N+1). Zeros clear it.
|
||||
void aurora_set_present_schedule(uint64_t baseNanos, uint64_t intervalNanos);
|
||||
// Reports whether the frame about to be sealed met its display boundary. Interpolation sizes its
|
||||
// slot group from this, backing off after misses. Only paced presents may report.
|
||||
void aurora_report_producer_paced(bool paced);
|
||||
void aurora_request_frame_capture(uint32_t frame, const char* outputPath);
|
||||
bool aurora_flush_efb_copies_to_ram();
|
||||
bool aurora_flush_efb_copy_to_ram(void* dest);
|
||||
|
||||
void aurora_set_log_level(AuroraLogLevel level);
|
||||
void aurora_set_pause_on_focus_lost(bool value);
|
||||
void aurora_set_background_input(bool value);
|
||||
void aurora_set_display_mode(AuroraDisplayMode mode);
|
||||
AuroraDisplayMode aurora_get_display_mode();
|
||||
|
||||
AuroraBackend aurora_get_backend();
|
||||
const AuroraBackend* aurora_get_available_backends(size_t* count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef AURORA_DVD_H
|
||||
#define AURORA_DVD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <dolphin/types.h>
|
||||
|
||||
/**
|
||||
* Open a GC/Wii disc image for use by the DVD API.
|
||||
* Must be called before DVDInit().
|
||||
* Returns true on success, false on failure.
|
||||
*/
|
||||
bool aurora_dvd_open(const char* disc_path);
|
||||
|
||||
/**
|
||||
* Close the disc image and free all resources.
|
||||
*/
|
||||
void aurora_dvd_close(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef AURORA_EVENT_H
|
||||
#define AURORA_EVENT_H
|
||||
|
||||
#include "aurora.h"
|
||||
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_joystick.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
AURORA_NONE,
|
||||
AURORA_EXIT,
|
||||
AURORA_SDL_EVENT,
|
||||
AURORA_WINDOW_MOVED,
|
||||
AURORA_WINDOW_RESIZED,
|
||||
AURORA_CONTROLLER_ADDED,
|
||||
AURORA_CONTROLLER_REMOVED,
|
||||
AURORA_PAUSED,
|
||||
AURORA_UNPAUSED,
|
||||
AURORA_DISPLAY_SCALE_CHANGED,
|
||||
} AuroraEventType;
|
||||
|
||||
struct AuroraEvent {
|
||||
AuroraEventType type;
|
||||
union {
|
||||
SDL_Event sdl;
|
||||
AuroraWindowPos windowPos;
|
||||
AuroraWindowSize windowSize;
|
||||
SDL_JoystickID controller;
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
#ifndef AURORA_GFX_H
|
||||
#define AURORA_GFX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
#else
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define AURORA_GFX_DEBUG_GROUPS
|
||||
#endif
|
||||
|
||||
void aurora_push_debug_group(const char* label);
|
||||
void aurora_pop_debug_group();
|
||||
|
||||
typedef struct {
|
||||
uint32_t queuedPipelines;
|
||||
uint32_t createdPipelines;
|
||||
uint32_t drawCallCount;
|
||||
uint32_t mergedDrawCallCount;
|
||||
uint32_t lastVertSize;
|
||||
uint32_t lastUniformSize;
|
||||
uint32_t lastIndexSize;
|
||||
uint32_t lastStorageSize;
|
||||
uint32_t lastTextureUploadSize;
|
||||
uint32_t presentedFrameCount;
|
||||
uint32_t interpolatedFrameCount;
|
||||
} AuroraStats;
|
||||
|
||||
typedef struct {
|
||||
uint64_t totalPresentCount;
|
||||
uint32_t sampleCount;
|
||||
double framesPerSecond;
|
||||
double averageFrameTimeMs;
|
||||
double p95FrameTimeMs;
|
||||
double jitterMs;
|
||||
// framesPerSecond with duplicated presentation slots scaled out, so this is the rate of frames
|
||||
// that carried new motion. Equal to framesPerSecond when every slot replayed real interpolation.
|
||||
double effectiveFramesPerSecond;
|
||||
} AuroraPresentTiming;
|
||||
|
||||
const AuroraStats* aurora_get_stats();
|
||||
void aurora_get_present_timing(AuroraPresentTiming* timing);
|
||||
|
||||
// Interpolation health: the per-frame fields describe the last sealed frame, the counters
|
||||
// accumulate since it was configured. This answers "output FPS dropped but the game held 60".
|
||||
typedef struct {
|
||||
uint32_t targetFps; // configured target, 0 when interpolation is off
|
||||
uint32_t targetSamples; // slots the pacing controller currently aims for
|
||||
uint32_t activeSamples; // slots latched for the latest sealed frame
|
||||
uint32_t candidates; // perspective draws in the latest sealed frame
|
||||
uint32_t matchable; // candidates whose identity also existed last frame
|
||||
uint32_t matches; // draws matched to the previous frame
|
||||
uint32_t eligible; // latest frame inserted interpolated slots
|
||||
uint32_t replaySafe; // latest frame could replay its command stream
|
||||
uint64_t framesSealed;
|
||||
uint64_t framesLowMatch;
|
||||
uint64_t framesReplayUnsafe;
|
||||
uint64_t slotReductions;
|
||||
uint64_t lateSealDrops;
|
||||
} AuroraFrameInterpolationDiagnostics;
|
||||
|
||||
void aurora_get_frame_interpolation_diagnostics(AuroraFrameInterpolationDiagnostics* diagnostics);
|
||||
|
||||
// Generates transform-interpolated perspective frames between consecutive 60 Hz logical frames.
|
||||
// Supported targets are 0 (off), 120, 180 and 240. Guest simulation and VI timing are unchanged.
|
||||
void aurora_set_frame_interpolation_fps(uint32_t targetFps);
|
||||
uint32_t aurora_get_frame_interpolation_fps();
|
||||
|
||||
// Newly encountered GX pipelines compile on the bounded worker queue. Draws whose pipeline is not
|
||||
// ready are skipped rather than stalling submission, and pick it up once compilation finishes.
|
||||
void aurora_set_skip_unready_pipelines(bool enabled);
|
||||
bool aurora_get_skip_unready_pipelines();
|
||||
uint32_t aurora_get_queued_pipeline_count();
|
||||
|
||||
// Controls whether display copies bypass the Wii's vertical copy filter.
|
||||
void aurora_set_disable_copy_filter(bool disabled);
|
||||
bool aurora_get_disable_copy_filter();
|
||||
|
||||
// Guest-RAM write tracking. `generation` changes whenever guest RAM covering a host range was
|
||||
// written (or returns AURORA_GUEST_WRITE_UNTRACKED); `notify` reports writes aurora made itself.
|
||||
#define AURORA_GUEST_WRITE_UNTRACKED UINT64_MAX
|
||||
typedef uint64_t (*AuroraGuestWriteGenerationCallback)(const void* hostPtr, size_t size);
|
||||
typedef void (*AuroraGuestWriteNotifyCallback)(const void* hostPtr, size_t size);
|
||||
void aurora_set_guest_write_hooks(AuroraGuestWriteGenerationCallback generation,
|
||||
AuroraGuestWriteNotifyCallback notify);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef AURORA_IMGUI_H
|
||||
#define AURORA_IMGUI_H
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
ImTextureID aurora_imgui_add_texture(uint32_t width, uint32_t height, const void* rgba8);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS 1
|
||||
|
||||
typedef struct SDL_IOStream SDL_IOStream;
|
||||
typedef SDL_IOStream* ImFileHandle;
|
||||
typedef unsigned long long ImU64;
|
||||
|
||||
ImFileHandle ImFileOpen(const char* filename, const char* mode);
|
||||
bool ImFileClose(ImFileHandle file);
|
||||
ImU64 ImFileGetSize(ImFileHandle file);
|
||||
ImU64 ImFileRead(void* data, ImU64 size, ImU64 count, ImFileHandle file);
|
||||
ImU64 ImFileWrite(const void* data, ImU64 size, ImU64 count, ImFileHandle file);
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef AURORA_MAIN_H
|
||||
#define AURORA_MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int aurora_main(int argc, char* argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define main aurora_main
|
||||
|
||||
#endif
|
||||
@@ -1,254 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef AURORA_VEC2_EXTRA
|
||||
#define AURORA_VEC2_EXTRA
|
||||
#endif
|
||||
#ifndef AURORA_VEC3_EXTRA
|
||||
#define AURORA_VEC3_EXTRA
|
||||
#endif
|
||||
#ifndef AURORA_VEC4_EXTRA
|
||||
#define AURORA_VEC4_EXTRA
|
||||
#endif
|
||||
#ifndef AURORA_MAT4X4_EXTRA
|
||||
#define AURORA_MAT4X4_EXTRA
|
||||
#endif
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
#if __has_attribute(vector_size) && !defined(__clang__)
|
||||
#define USE_GCC_VECTOR_EXTENSIONS
|
||||
#endif
|
||||
|
||||
namespace aurora {
|
||||
template <typename T>
|
||||
struct Vec2 {
|
||||
T x{};
|
||||
T y{};
|
||||
|
||||
constexpr Vec2() = default;
|
||||
constexpr Vec2(T x, T y) : x(x), y(y) {}
|
||||
AURORA_VEC2_EXTRA
|
||||
|
||||
bool operator==(const Vec2& rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec3 {
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
|
||||
constexpr Vec3() = default;
|
||||
constexpr Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
AURORA_VEC3_EXTRA
|
||||
|
||||
bool operator==(const Vec3& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
|
||||
bool operator!=(const Vec3& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec4 {
|
||||
#ifdef USE_GCC_VECTOR_EXTENSIONS
|
||||
typedef T Vt __attribute__((vector_size(sizeof(T) * 4)));
|
||||
Vt m;
|
||||
#else
|
||||
using Vt = T[4];
|
||||
Vt m;
|
||||
#endif
|
||||
|
||||
constexpr Vec4() = default;
|
||||
constexpr Vec4(Vt m) : m(m) {}
|
||||
constexpr Vec4(T x, T y, T z, T w) : m{x, y, z, w} {}
|
||||
// For Vec3 with padding
|
||||
constexpr Vec4(T x, T y, T z) : m{x, y, z, {}} {}
|
||||
// For Vec3 -> Vec4
|
||||
constexpr Vec4(Vec3<T> v, T w) : m{v.x, v.y, v.z, w} {}
|
||||
AURORA_VEC4_EXTRA
|
||||
|
||||
inline Vec4& operator=(const Vec4& other) {
|
||||
memcpy(&m, &other.m, sizeof(Vt));
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline T& x() { return m[0]; }
|
||||
[[nodiscard]] inline T x() const { return m[0]; }
|
||||
[[nodiscard]] inline T& y() { return m[1]; }
|
||||
[[nodiscard]] inline T y() const { return m[1]; }
|
||||
[[nodiscard]] inline T& z() { return m[2]; }
|
||||
[[nodiscard]] inline T z() const { return m[2]; }
|
||||
[[nodiscard]] inline T& w() { return m[3]; }
|
||||
[[nodiscard]] inline T w() const { return m[3]; }
|
||||
[[nodiscard]] inline T& operator[](size_t i) { return m[i]; }
|
||||
[[nodiscard]] inline T operator[](size_t i) const { return m[i]; }
|
||||
|
||||
template <size_t x, size_t y, size_t z, size_t w>
|
||||
[[nodiscard]] constexpr Vec4 shuffle() const {
|
||||
static_assert(x < 4 && y < 4 && z < 4 && w < 4);
|
||||
#if defined(USE_GCC_VECTOR_EXTENSIONS) && __has_builtin(__builtin_shuffle)
|
||||
typedef int Vi __attribute__((vector_size(16)));
|
||||
return __builtin_shuffle(m, Vi{x, y, z, w});
|
||||
#else
|
||||
return {m[x], m[y], m[z], m[w]};
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator==(const Vec4& rhs) const {
|
||||
#if defined(USE_GCC_VECTOR_EXTENSIONS) && __has_builtin(__builtin_reduce_and)
|
||||
return __builtin_reduce_and(m == rhs.m) != 0;
|
||||
#else
|
||||
return m[0] == rhs.m[0] && m[1] == rhs.m[1] && m[2] == rhs.m[2] && m[3] == rhs.m[3];
|
||||
#endif
|
||||
}
|
||||
bool operator!=(const Vec4& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
template <typename T>
|
||||
[[nodiscard]] Vec4<T> operator+(const Vec4<T>& a, const Vec4<T>& b) {
|
||||
#ifdef USE_GCC_VECTOR_EXTENSIONS
|
||||
return a.m + b.m;
|
||||
#else
|
||||
return {a.m[0] + b.m[0], a.m[1] + b.m[1], a.m[2] + b.m[2], a.m[3] + b.m[3]};
|
||||
#endif
|
||||
}
|
||||
template <typename T>
|
||||
[[nodiscard]] Vec4<T> operator*(const Vec4<T>& a, const Vec4<T>& b) {
|
||||
#ifdef USE_GCC_VECTOR_EXTENSIONS
|
||||
return a.m * b.m;
|
||||
#else
|
||||
return {a.m[0] * b.m[0], a.m[1] * b.m[1], a.m[2] * b.m[2], a.m[3] * b.m[3]};
|
||||
#endif
|
||||
}
|
||||
template <typename T>
|
||||
struct Mat3x2 {
|
||||
Vec2<T> m0{};
|
||||
Vec2<T> m1{};
|
||||
Vec2<T> m2{};
|
||||
|
||||
constexpr Mat3x2() = default;
|
||||
constexpr Mat3x2(const Vec2<T>& m0, const Vec2<T>& m1, const Vec2<T>& m2) : m0(m0), m1(m1), m2(m2) {}
|
||||
|
||||
bool operator==(const Mat3x2& rhs) const { return m0 == rhs.m0 && m1 == rhs.m1 && m2 == rhs.m2; }
|
||||
bool operator!=(const Mat3x2& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
template <typename T>
|
||||
struct Mat4x2 {
|
||||
Vec2<T> m0{};
|
||||
Vec2<T> m1{};
|
||||
Vec2<T> m2{};
|
||||
Vec2<T> m3{};
|
||||
|
||||
constexpr Mat4x2() = default;
|
||||
constexpr Mat4x2(const Vec2<T>& m0, const Vec2<T>& m1, const Vec2<T>& m2, const Vec2<T>& m3)
|
||||
: m0(m0), m1(m1), m2(m2), m3(m3) {}
|
||||
|
||||
inline Mat4x2 transpose() const {
|
||||
return {
|
||||
{m0.x, m2.x},
|
||||
{m0.y, m2.y},
|
||||
{m1.x, m3.x},
|
||||
{m1.y, m3.y},
|
||||
};
|
||||
}
|
||||
|
||||
bool operator==(const Mat4x2& rhs) const { return m0 == rhs.m0 && m1 == rhs.m1 && m2 == rhs.m2 && m3 == rhs.m3; }
|
||||
bool operator!=(const Mat4x2& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
template <typename T>
|
||||
struct Mat2x4 {
|
||||
Vec4<T> m0{};
|
||||
Vec4<T> m1{};
|
||||
|
||||
constexpr Mat2x4() = default;
|
||||
constexpr Mat2x4(const Vec4<T>& m0, const Vec4<T>& m1, const Vec4<T>& m2) : m0(m0), m1(m1) {}
|
||||
|
||||
bool operator==(const Mat2x4& rhs) const { return m0 == rhs.m0 && m1 == rhs.m1; }
|
||||
bool operator!=(const Mat2x4& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
static_assert(sizeof(Mat2x4<float>) == 32);
|
||||
template <typename T>
|
||||
struct Mat4x4;
|
||||
template <typename T>
|
||||
struct Mat3x4 {
|
||||
Vec4<T> m0{};
|
||||
Vec4<T> m1{};
|
||||
Vec4<T> m2{};
|
||||
|
||||
constexpr Mat3x4() = default;
|
||||
constexpr Mat3x4(const Vec4<T>& m0, const Vec4<T>& m1, const Vec4<T>& m2) : m0(m0), m1(m1), m2(m2) {}
|
||||
|
||||
[[nodiscard]] Mat4x4<T> to4x4() const;
|
||||
[[nodiscard]] Mat4x4<T> toTransposed4x4() const;
|
||||
|
||||
bool operator==(const Mat3x4& rhs) const { return m0 == rhs.m0 && m1 == rhs.m1 && m2 == rhs.m2; }
|
||||
bool operator!=(const Mat3x4& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
static_assert(sizeof(Mat3x4<float>) == 48);
|
||||
template <typename T>
|
||||
struct Mat4x4 {
|
||||
Vec4<T> m0{};
|
||||
Vec4<T> m1{};
|
||||
Vec4<T> m2{};
|
||||
Vec4<T> m3{};
|
||||
|
||||
constexpr Mat4x4() = default;
|
||||
constexpr Mat4x4(const Vec4<T>& m0, const Vec4<T>& m1, const Vec4<T>& m2, const Vec4<T>& m3)
|
||||
: m0(m0), m1(m1), m2(m2), m3(m3) {}
|
||||
AURORA_MAT4X4_EXTRA
|
||||
|
||||
[[nodiscard]] Mat4x4 transpose() const {
|
||||
return {
|
||||
{m0[0], m1[0], m2[0], m3[0]},
|
||||
{m0[1], m1[1], m2[1], m3[1]},
|
||||
{m0[2], m1[2], m2[2], m3[2]},
|
||||
{m0[3], m1[3], m2[3], m3[3]},
|
||||
};
|
||||
}
|
||||
Mat4x4& operator=(const Mat4x4& other) = default;
|
||||
|
||||
Vec4<T>& operator[](size_t i) { return *(&m0 + i); }
|
||||
const Vec4<T>& operator[](size_t i) const { return *(&m0 + i); }
|
||||
|
||||
bool operator==(const Mat4x4& rhs) const { return m0 == rhs.m0 && m1 == rhs.m1 && m2 == rhs.m2 && m3 == rhs.m3; }
|
||||
bool operator!=(const Mat4x4& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
static_assert(sizeof(Mat4x4<float>) == 64);
|
||||
template <typename T>
|
||||
[[nodiscard]] Mat4x4<T> operator*(const Mat4x4<T>& a, const Mat4x4<T>& b) {
|
||||
Mat4x4<T> out;
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
*(&out.m0 + i) = a.m0 * b[i].template shuffle<0, 0, 0, 0>() + a.m1 * b[i].template shuffle<1, 1, 1, 1>() +
|
||||
a.m2 * b[i].template shuffle<2, 2, 2, 2>() + a.m3 * b[i].template shuffle<3, 3, 3, 3>();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename T>
|
||||
[[nodiscard]] Mat4x4<T> Mat3x4<T>::to4x4() const {
|
||||
return {
|
||||
{m0[0], m0[1], m0[2], 0.f},
|
||||
{m1[0], m1[1], m1[2], 0.f},
|
||||
{m2[0], m2[1], m2[2], 0.f},
|
||||
{m0[3], m1[3], m2[3], 1.f},
|
||||
};
|
||||
}
|
||||
template <typename T>
|
||||
[[nodiscard]] Mat4x4<T> Mat3x4<T>::toTransposed4x4() const {
|
||||
return Mat4x4<T>{
|
||||
{m0[0], m1[0], m2[0], 0.f},
|
||||
{m0[1], m1[1], m2[1], 0.f},
|
||||
{m0[2], m1[2], m2[2], 0.f},
|
||||
{m0[3], m1[3], m2[3], 1.f},
|
||||
};
|
||||
}
|
||||
constexpr Mat4x4 Mat4x4_Identity{
|
||||
Vec4{1.f, 0.f, 0.f, 0.f},
|
||||
Vec4{0.f, 1.f, 0.f, 0.f},
|
||||
Vec4{0.f, 0.f, 1.f, 0.f},
|
||||
Vec4{0.f, 0.f, 0.f, 1.f},
|
||||
};
|
||||
} // namespace aurora
|
||||
@@ -1,81 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace aurora::render_size_limits {
|
||||
|
||||
struct Size {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
// The canvas follows the window aspect however wide it gets, since the presenter stretches it and
|
||||
// a cap would distort the UI. Only the portrait side clamps, where the guest cannot fill taller.
|
||||
inline constexpr float kMaxDynamicPortraitExpansion = 6.f;
|
||||
inline constexpr float kMinDynamicAspect = (16.f / 9.f) / kMaxDynamicPortraitExpansion;
|
||||
|
||||
// The adapter limit is an API ceiling, not an allocation budget: a 16384-wide RGBA attachment is
|
||||
// near 100 MiB. 8192 plus an 8K-UHD pixel budget keeps 8x 16:9 while avoiding device removal.
|
||||
inline constexpr uint32_t kMaxFramebufferDimension = 8192;
|
||||
inline constexpr uint64_t kMaxFramebufferPixels = 7680ull * 4320ull;
|
||||
|
||||
inline float clamp_dynamic_aspect(float aspect) noexcept {
|
||||
if (!std::isfinite(aspect) || aspect <= 0.f) {
|
||||
return 1.f;
|
||||
}
|
||||
return std::max(aspect, kMinDynamicAspect);
|
||||
}
|
||||
|
||||
inline Size scale_framebuffer_to_aspect(uint32_t width, uint32_t height, float scale, float requestedAspect) noexcept {
|
||||
if (width == 0 || height == 0 || !std::isfinite(scale) || scale <= 0.f) {
|
||||
return {std::max(width, 1u), std::max(height, 1u)};
|
||||
}
|
||||
|
||||
const auto scaledWidth = std::max(1u, static_cast<uint32_t>(std::lround(static_cast<double>(width) * scale)));
|
||||
const auto scaledHeight = std::max(1u, static_cast<uint32_t>(std::lround(static_cast<double>(height) * scale)));
|
||||
const float aspect = clamp_dynamic_aspect(requestedAspect);
|
||||
if (aspect >= static_cast<float>(width) / static_cast<float>(height)) {
|
||||
return {
|
||||
std::max(1u, static_cast<uint32_t>(std::lround(static_cast<double>(scaledHeight) * aspect))),
|
||||
scaledHeight,
|
||||
};
|
||||
}
|
||||
return {
|
||||
scaledWidth,
|
||||
std::max(1u, static_cast<uint32_t>(std::lround(static_cast<double>(scaledWidth) / aspect))),
|
||||
};
|
||||
}
|
||||
|
||||
inline Size fit_framebuffer_to_budget(uint32_t width, uint32_t height, uint32_t adapterMaxDimension) noexcept {
|
||||
if (width == 0 || height == 0) {
|
||||
return {width, height};
|
||||
}
|
||||
|
||||
uint32_t dimensionLimit = kMaxFramebufferDimension;
|
||||
if (adapterMaxDimension != 0 && adapterMaxDimension != std::numeric_limits<uint32_t>::max()) {
|
||||
dimensionLimit = std::min(dimensionLimit, adapterMaxDimension);
|
||||
}
|
||||
dimensionLimit = std::max(dimensionLimit, 1u);
|
||||
|
||||
double fitScale = 1.0;
|
||||
fitScale = std::min(fitScale, static_cast<double>(dimensionLimit) / static_cast<double>(width));
|
||||
fitScale = std::min(fitScale, static_cast<double>(dimensionLimit) / static_cast<double>(height));
|
||||
|
||||
const double requestedPixels = static_cast<double>(width) * static_cast<double>(height);
|
||||
if (requestedPixels > static_cast<double>(kMaxFramebufferPixels)) {
|
||||
fitScale = std::min(fitScale, std::sqrt(static_cast<double>(kMaxFramebufferPixels) / requestedPixels));
|
||||
}
|
||||
|
||||
if (fitScale >= 1.0) {
|
||||
return {width, height};
|
||||
}
|
||||
return {
|
||||
std::max(1u, static_cast<uint32_t>(std::floor(static_cast<double>(width) * fitScale))),
|
||||
std::max(1u, static_cast<uint32_t>(std::floor(static_cast<double>(height) * fitScale))),
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace aurora::render_size_limits
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef _DOLPHIN_AI_H_
|
||||
#define _DOLPHIN_AI_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*AISCallback)(u32 count);
|
||||
typedef void (*AIDCallback)();
|
||||
|
||||
#define AI_STREAM_START 1
|
||||
#define AI_STREAM_STOP 0
|
||||
|
||||
#define AI_SAMPLERATE_32KHZ 0
|
||||
#define AI_SAMPLERATE_48KHZ 1
|
||||
|
||||
AIDCallback AIRegisterDMACallback(AIDCallback callback);
|
||||
void AIInitDMA(u32 start_addr, u32 length);
|
||||
BOOL AIGetDMAEnableFlag(void);
|
||||
void AIStartDMA(void);
|
||||
void AIStopDMA(void);
|
||||
u32 AIGetDMABytesLeft(void);
|
||||
u32 AIGetDMAStartAddr(void);
|
||||
u32 AIGetDMALength(void);
|
||||
BOOL AICheckInit(void);
|
||||
AISCallback AIRegisterStreamCallback(AISCallback callback);
|
||||
u32 AIGetStreamSampleCount(void);
|
||||
void AIResetStreamSampleCount(void);
|
||||
void AISetStreamTrigger(u32 trigger);
|
||||
u32 AIGetStreamTrigger(void);
|
||||
void AISetStreamPlayState(u32 state);
|
||||
u32 AIGetStreamPlayState(void);
|
||||
void AISetDSPSampleRate(u32 rate);
|
||||
u32 AIGetDSPSampleRate(void);
|
||||
void AISetStreamSampleRate(u32 rate);
|
||||
u32 AIGetStreamSampleRate(void);
|
||||
void AISetStreamVolLeft(u8 vol);
|
||||
u8 AIGetStreamVolLeft(void);
|
||||
void AISetStreamVolRight(u8 vol);
|
||||
u8 AIGetStreamVolRight(void);
|
||||
void AIInit(u8* stack);
|
||||
void AIReset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
#ifndef _DOLPHIN_AR_H_
|
||||
#define _DOLPHIN_AR_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*ARQCallback)(uintptr_t pointerToARQRequest);
|
||||
|
||||
struct ARQRequest {
|
||||
/* 0x00 */ struct ARQRequest *next;
|
||||
/* 0x04 */ u32 owner;
|
||||
/* 0x08 */ u32 type;
|
||||
/* 0x0C */ u32 priority;
|
||||
/* 0x10 */ u32 source;
|
||||
/* 0x14 */ u32 dest;
|
||||
/* 0x18 */ u32 length;
|
||||
/* 0x1C */ ARQCallback callback;
|
||||
};
|
||||
|
||||
#define ARQ_DMA_ALIGNMENT 32
|
||||
|
||||
#define ARAM_DIR_MRAM_TO_ARAM 0x00
|
||||
#define ARAM_DIR_ARAM_TO_MRAM 0x01
|
||||
|
||||
#define ARStartDMARead(mmem, aram, len) \
|
||||
ARStartDMA(ARAM_DIR_ARAM_TO_MRAM, mmem, aram, len)
|
||||
#define ARStartDMAWrite(mmem, aram, len) \
|
||||
ARStartDMA(ARAM_DIR_MRAM_TO_ARAM, mmem, aram, len)
|
||||
|
||||
typedef struct ARQRequest ARQRequest;
|
||||
|
||||
#define ARQ_TYPE_MRAM_TO_ARAM ARAM_DIR_MRAM_TO_ARAM
|
||||
#define ARQ_TYPE_ARAM_TO_MRAM ARAM_DIR_ARAM_TO_MRAM
|
||||
|
||||
#define ARQ_PRIORITY_LOW 0
|
||||
#define ARQ_PRIORITY_HIGH 1
|
||||
|
||||
// AR
|
||||
ARQCallback ARRegisterDMACallback(ARQCallback callback);
|
||||
u32 ARGetDMAStatus(void);
|
||||
void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length);
|
||||
u32 ARAlloc(u32 length);
|
||||
u32 ARFree(u32* length);
|
||||
BOOL ARCheckInit(void);
|
||||
u32 ARInit(u32* stack_index_addr, u32 num_entries);
|
||||
void ARReset(void);
|
||||
void ARSetSize(void);
|
||||
u32 ARGetBaseAddress(void);
|
||||
u32 ARGetSize(void);
|
||||
u32 ARGetInternalSize(void);
|
||||
void ARClear(u32 flag);
|
||||
|
||||
/**
|
||||
* Aurora extension: gets the memory address where ARAM is stored, for direct access.
|
||||
*/
|
||||
void* ARGetStorageAddress();
|
||||
|
||||
// ARQ
|
||||
void ARQInit(void);
|
||||
void ARQReset(void);
|
||||
void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, uintptr_t source, uintptr_t dest, u32 length, ARQCallback callback);
|
||||
void ARQRemoveRequest(ARQRequest* request);
|
||||
void ARQRemoveOwnerRequest(u32 owner);
|
||||
void ARQFlushQueue(void);
|
||||
void ARQSetChunkSize(u32 size);
|
||||
u32 ARQGetChunkSize(void);
|
||||
BOOL ARQCheckInit(void);
|
||||
|
||||
u16 __ARGetInterruptStatus(void);
|
||||
void __ARClearInterrupt(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,542 +0,0 @@
|
||||
#ifndef _DOLPHIN_PPCARCH
|
||||
#define _DOLPHIN_PPCARCH
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CTR 9
|
||||
#define XER 1
|
||||
#define LR 8
|
||||
|
||||
#define UPMC1 937
|
||||
#define UPMC2 938
|
||||
#define UPMC3 941
|
||||
#define UPMC4 942
|
||||
|
||||
#define USIA 939
|
||||
|
||||
#define UMMCR0 936
|
||||
#define UMMCR1 940
|
||||
|
||||
#define HID0 1008
|
||||
#define HID1 1009
|
||||
|
||||
#define PVR 287
|
||||
|
||||
#define IBAT0U 528
|
||||
#define IBAT0L 529
|
||||
#define IBAT1U 530
|
||||
#define IBAT1L 531
|
||||
#define IBAT2U 532
|
||||
#define IBAT2L 533
|
||||
#define IBAT3U 534
|
||||
#define IBAT3L 535
|
||||
|
||||
#define DBAT0U 536
|
||||
#define DBAT0L 537
|
||||
#define DBAT1U 538
|
||||
#define DBAT1L 539
|
||||
#define DBAT2U 540
|
||||
#define DBAT2L 541
|
||||
#define DBAT3U 542
|
||||
#define DBAT3L 543
|
||||
|
||||
#define SDR1 25
|
||||
|
||||
#define SPRG0 272
|
||||
#define SPRG1 273
|
||||
#define SPRG2 274
|
||||
#define SPRG3 275
|
||||
|
||||
#define DAR 19
|
||||
#define DSISR 18
|
||||
|
||||
#define SRR0 26
|
||||
#define SRR1 27
|
||||
|
||||
#define EAR 282
|
||||
|
||||
#define DABR 1013
|
||||
|
||||
#define TBL 284
|
||||
#define TBU 285
|
||||
|
||||
#define L2CR 1017
|
||||
|
||||
#define DEC 22
|
||||
|
||||
#define IABR 1010
|
||||
|
||||
#define PMC1 953
|
||||
#define PMC2 954
|
||||
#define PMC3 957
|
||||
#define PMC4 958
|
||||
|
||||
#define SIA 955
|
||||
|
||||
#define MMCR0 952
|
||||
#define MMCR1 956
|
||||
|
||||
#define THRM1 1020
|
||||
#define THRM2 1021
|
||||
#define THRM3 1022
|
||||
|
||||
#define ICTC 1019
|
||||
|
||||
#define GQR0 912
|
||||
#define GQR1 913
|
||||
#define GQR2 914
|
||||
#define GQR3 915
|
||||
#define GQR4 916
|
||||
#define GQR5 917
|
||||
#define GQR6 918
|
||||
#define GQR7 919
|
||||
|
||||
#define HID2 920
|
||||
|
||||
#define WPAR 921
|
||||
|
||||
#define DMA_U 922
|
||||
#define DMA_L 923
|
||||
|
||||
#define MSR_POW 0x00040000 // Power Management
|
||||
#define MSR_ILE 0x00010000 // Interrupt Little Endian
|
||||
#define MSR_EE 0x00008000 // external interrupt
|
||||
#define MSR_PR 0x00004000 // privilege level(should be 0)
|
||||
#define MSR_FP 0x00002000 // floating point available
|
||||
#define MSR_ME 0x00001000 // machine check enable
|
||||
#define MSR_FE0 0x00000800 // floating point exception enable
|
||||
#define MSR_SE 0x00000400 // single step trace enable
|
||||
#define MSR_BE 0x00000200 // branch trace enable
|
||||
#define MSR_FE1 0x00000100 // floating point exception enable
|
||||
#define MSR_IP 0x00000040 // Exception prefix
|
||||
#define MSR_IR 0x00000020 // instruction relocate
|
||||
#define MSR_DR 0x00000010 // data relocate
|
||||
#define MSR_PM 0x00000004 // Performance monitor marked mode
|
||||
#define MSR_RI 0x00000002 // Recoverable interrupt
|
||||
#define MSR_LE 0x00000001 // Little Endian
|
||||
|
||||
#define MSR_POW_BIT 13 // Power Management
|
||||
#define MSR_ILE_BIT 15 // Interrupt Little Endian
|
||||
#define MSR_EE_BIT 16 // external interrupt
|
||||
#define MSR_PR_BIT 17 // privilege level (should be 0)
|
||||
#define MSR_FP_BIT 18 // floating point available
|
||||
#define MSR_ME_BIT 19 // machine check enable
|
||||
#define MSR_FE0_BIT 20 // floating point exception enable
|
||||
#define MSR_SE_BIT 21 // single step trace enable
|
||||
#define MSR_BE_BIT 22 // branch trace enable
|
||||
#define MSR_FE1_BIT 23 // floating point exception enable
|
||||
#define MSR_IP_BIT 25 // Exception prefix
|
||||
#define MSR_IR_BIT 26 // instruction relocate
|
||||
#define MSR_DR_BIT 27 // data relocate
|
||||
#define MSR_PM_BIT 29 // Performance monitor marked mode
|
||||
#define MSR_RI_BIT 30 // Recoverable interrupt
|
||||
#define MSR_LE_BIT 31 // Little Endian
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
HID0 bits
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define HID0_EMCP 0x80000000u // Enable MCP
|
||||
#define HID0_DBP 0x40000000u // Enable 60x bus address and data parity chk
|
||||
#define HID0_EBA 0x20000000u // Enable 60x address parity checking
|
||||
#define HID0_EBD 0x10000000u // Enable 60x data parity checking
|
||||
#define HID0_BCLK 0x08000000u // CLK_OUT output enable and clk selection
|
||||
#define HID0_ECLK 0x02000000u // CLK_OUT output enable and clk selection
|
||||
#define HID0_PAR 0x01000000u // Disable !ARTRY precharge
|
||||
#define HID0_DOZE 0x00800000u // Doze mode enable
|
||||
#define HID0_NAP 0x00400000u // Nap mode enable
|
||||
#define HID0_SLEEP 0x00200000u // Sleep mode enable
|
||||
#define HID0_DPM 0x00100000u // Dynamic power management enable
|
||||
#define HID0_NHR 0x00010000u // Not hard reset (0 hard reset if s/w set it)
|
||||
#define HID0_ICE 0x00008000u // Instruction cache enable
|
||||
#define HID0_DCE 0x00004000u // Data cache enable
|
||||
#define HID0_ILOCK 0x00002000u // ICache lock
|
||||
#define HID0_DLOCK 0x00001000u // DCache lock
|
||||
#define HID0_ICFI 0x00000800u // ICache flash invalidate
|
||||
#define HID0_DCFI 0x00000400u // DCache flash invalidate
|
||||
#define HID0_SPD 0x00000200u // Speculative cache access enable (0 enable)
|
||||
#define HID0_IFEM 0x00000100u // Enable M bit on bus for Ifetch
|
||||
#define HID0_SGE 0x00000080u // Store gathering enable
|
||||
#define HID0_DCFA 0x00000040u // DCache flush assist - set before a flush
|
||||
#define HID0_BTIC 0x00000020u // Branch target icache enable
|
||||
#define HID0_ABE 0x00000008u // Address bcast enable
|
||||
#define HID0_BHT 0x00000004u // Branch history table enable
|
||||
#define HID0_NOOPTI 0x00000001u // No-op Dcache touch instructions
|
||||
|
||||
#define HID0_ICE_BIT 16 // Instruction cache enable
|
||||
#define HID0_DCE_BIT 17 // Data cache enable
|
||||
#define HID0_ILOCK_BIT 18 // ICache lock
|
||||
#define HID0_DLOCK_BIT 19 // DCache lock
|
||||
|
||||
#define HID2_LSQE 0x80000000 // L/S quantize enable
|
||||
#define HID2_WPE 0x40000000 // Write pipe enable
|
||||
#define HID2_PSE 0x20000000 // Paired single enable
|
||||
#define HID2_LCE 0x10000000 // Locked cache enable
|
||||
|
||||
#define HID2_DCHERR 0x00800000 // ERROR: dcbz_l cache hit
|
||||
#define HID2_DNCERR 0x00400000 // ERROR: DMA access to normal cache
|
||||
#define HID2_DCMERR 0x00200000 // ERROR: DMA cache miss error
|
||||
#define HID2_DQOERR 0x00100000 // ERROR: DMA queue overflow
|
||||
#define HID2_DCHEE 0x00080000 // dcbz_l cache hit error enable
|
||||
#define HID2_DNCEE 0x00040000 // DMA access to normal cache error enable
|
||||
#define HID2_DCMEE 0x00020000 // DMA cache miss error error enable
|
||||
#define HID2_DQOEE 0x00010000 // DMA queue overflow error enable
|
||||
|
||||
#define HID2_DMAQL_MASK 0x0F000000 // DMA queue length mask
|
||||
#define HID2_DMAQL_SHIFT 24 // DMA queue shift
|
||||
|
||||
#define HID2_LSQE_BIT 0
|
||||
#define HID2_WPE_BIT 1
|
||||
#define HID2_PSE_BIT 2
|
||||
#define HID2_LCE_BIT 3
|
||||
|
||||
#define HID2_DCHERR_BIT 8
|
||||
#define HID2_DNCERR_BIT 9
|
||||
#define HID2_DCMERR_BIT 10
|
||||
#define HID2_DQOERR_BIT 11
|
||||
#define HID2_DCHEE_BIT 12
|
||||
#define HID2_DNCEE_BIT 13
|
||||
#define HID2_DCMEE_BIT 14
|
||||
#define HID2_DQOEE_BIT 15
|
||||
|
||||
#define GQR_LOAD_SCALE_MASK 0x3F000000 // load scale field
|
||||
#define GQR_LOAD_TYPE_MASK 0x00070000 // load type field
|
||||
#define GQR_STORE_SCALE_MASK 0x00003F00 // store scale field
|
||||
#define GQR_STORE_TYPE_MASK 0x00000007 // store type field
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 _pad0 :2;
|
||||
u32 loadScale :6;
|
||||
u32 _pad1 :5;
|
||||
u32 loadType :3;
|
||||
u32 _pad2 :2;
|
||||
u32 storeScale :6;
|
||||
u32 _pad3 :5;
|
||||
u32 storeType :3;
|
||||
} PPC_GQR_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 val;
|
||||
PPC_GQR_t f;
|
||||
} PPC_GQR_u;
|
||||
|
||||
|
||||
#define DMA_U_ADDR_MASK 0xFFFFFFE0 // Start addr in memory
|
||||
#define DMA_U_LEN_U_MASK 0x0000001F // lines to transfer (U)
|
||||
|
||||
#define DMA_L_LC_ADDR_MASK 0xFFFFFFE0 // Start addr in LC
|
||||
#define DMA_L_LOAD 0x00000010 // 0 - store, 1 - load
|
||||
#define DMA_L_STORE 0x00000000 // 0 - store, 1 - load
|
||||
#define DMA_L_LEN_MASK 0x0000000C // lines to transfer (L)
|
||||
#define DMA_L_TRIGGER 0x00000002 // 0 - cmd inactive, 1 - cmd rdy
|
||||
#define DMA_L_FLUSH 0x00000001 // 1 - Flush DMA queue
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 memAddr :27;
|
||||
u32 dmaLenU :5;
|
||||
} PPC_DMA_U_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 val;
|
||||
PPC_DMA_U_t f;
|
||||
} PPC_DMA_U_u;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 lcAddr :27;
|
||||
u32 dmaLd :1;
|
||||
u32 dmaLenL :2;
|
||||
u32 dmaTrigger :1;
|
||||
u32 dmaFlush :1;
|
||||
} PPC_DMA_L_t;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
u32 val;
|
||||
PPC_DMA_L_t f;
|
||||
} PPC_DMA_L_u;
|
||||
|
||||
|
||||
#define WPAR_ADDR 0xFFFFFFE0 // 32byte gather address
|
||||
#define WPAR_BNE 0x00000001 // Buffer not empty (R)
|
||||
|
||||
#define SRR1_DMA_BIT 0x00200000
|
||||
#define SRR1_L2DP_BIT 0x00100000
|
||||
|
||||
#define L2CR_L2E 0x80000000 // L2 Enable
|
||||
#define L2CR_L2PE 0x40000000 // L2 data parity generation and checking enable
|
||||
|
||||
#define L2CR_L2SIZ_256K 0x10000000 // L2 size 256K
|
||||
#define L2CR_L2SIZ_512K 0x20000000 // L2 size 512
|
||||
#define L2CR_L2SIZ_1M 0x30000000 // L2 size 1M
|
||||
|
||||
#define L2CR_L2CLK_1_0 0x02000000 // L2 clock ratio 1
|
||||
#define L2CR_L2CLK_1_5 0x04000000 // L2 clock ratio 1.5
|
||||
#define L2CR_L2CLK_2_0 0x08000000 // L2 clock ratio 2
|
||||
#define L2CR_L2CLK_2_5 0x0A000000 // L2 clock ratio 2.5
|
||||
#define L2CR_L2CLK_3_0 0x0C000000 // L2 clock ratio 3
|
||||
|
||||
#define L2CR_RAM_FLOW_THRU_BURST 0x00000000 // L2 RAM type flow-through sync. burst SRAM
|
||||
#define L2CR_RAM_PIPELINE_BURST 0x01000000 // L2 RAM type pipelined sync. burst SRAM
|
||||
#define L2CR_RAM_PIPELINE_LATE 0x01800000 // L2 RAM type pipelined sync. late-write SRAM
|
||||
|
||||
#define L2CR_L2DO 0x00400000 // Data only
|
||||
#define L2CR_L2I 0x00200000 // Global invalidate
|
||||
#define L2CR_L2CTL 0x00100000 // ZZ enable
|
||||
#define L2CR_L2WT 0x00080000 // L2 write through
|
||||
#define L2CR_L2TS 0x00040000 // L2 test support
|
||||
|
||||
#define L2CR_L2OH_0_5 0x00000000 // L2 output hold 0.5 ns
|
||||
#define L2CR_L2OH_1_0 0x00010000 // L2 output hold 1.0 ns
|
||||
|
||||
#define L2CR_L2SL 0x00008000 // L2 DLL slow
|
||||
#define L2CR_L2DF 0x00004000 // L2 differential clock
|
||||
#define L2CR_L2BYP 0x00002000 // L2 DLL bypass
|
||||
#define L2CR_L2CS 0x00000200 // L2 clock stop
|
||||
#define L2CR_L2DRO 0x00000100 // L2 DLL rollover checkstop enable
|
||||
#define L2CR_L2CTR_MASK 0x000000FE // L2 counter value mask
|
||||
#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress
|
||||
|
||||
#define MMCR0_DIS 0x80000000 // Disables counting unconditionally
|
||||
#define MMCR0_DP 0x40000000 // Disables counting while in supervisor mode
|
||||
#define MMCR0_DU 0x20000000 // Disables counting while in user mode
|
||||
#define MMCR0_DMS 0x10000000 // Disables counting while MSR[PM] is set
|
||||
#define MMCR0_DMR 0x08000000 // Disables counting while MSR[PM] is zero
|
||||
#define MMCR0_ENINT 0x04000000 // Enables performance monitor interrupt signaling
|
||||
#define MMCR0_DISCOUNT 0x02000000 // Disables counting of PMCn when a performance monitor interrupt is signaled or...
|
||||
#define MMCR0_RTCSELECT_MASK 0x01800000 // 64-bit time base, bit selection enable
|
||||
#define MMCR0_RTCSELECT_63 0x00000000 // Pick bit 63 to count
|
||||
#define MMCR0_RTCSELECT_55 0x00800000 // Pick bit 55 to count
|
||||
#define MMCR0_RTCSELECT_51 0x01000000 // Pick bit 51 to count
|
||||
#define MMCR0_RTCSELECT_47 0x01800000 // Pick bit 47 to count
|
||||
#define MMCR0_INTONBITTRANS 0x00400000 // Causes interrupt signaling on bit transition from off to on
|
||||
#define MMCR0_THRESHOLD_MASK 0x003F0000 // Threshold value
|
||||
#define MMCR0_THRESHOLD(n) ((n) << 16) // Threshold value (0 - 63)
|
||||
#define MMCR0_PMC1INTCONTROL 0x00008000 // Enables interrupt signaling due to PMC1 counter overflow
|
||||
#define MMCR0_PMC2INTCONTROL 0x00004000 // Enables interrupt signaling due to PMC2-PMC4 counter overflow
|
||||
#define MMCR0_PMCTRIGGER 0x00002000 // Can be used to trigger counting of PMC2-PMC4 after PMC1 has overflowed or...
|
||||
#define MMCR0_PMC1SELECT_MASK 0x00001FC0 // PMC1 input selector
|
||||
#define MMCR0_PMC2SELECT_MASK 0x0000003F // PMC2 input selector
|
||||
|
||||
#define MMCR1_PMC3SELECT_MASK 0xF8000000 // PMC3 input selector
|
||||
#define MMCR1_PMC4SELECT_MASK 0x07C00000 // PMC4 input selector
|
||||
|
||||
#define PMC1_OV 0x80000000 // Overflow
|
||||
#define PMC1_COUNTER 0x7FFFFFFF // Counter value
|
||||
#define PMC2_OV 0x80000000 // Overflow
|
||||
#define PMC2_COUNTER 0x7FFFFFFF // Counter value
|
||||
#define PMC3_OV 0x80000000 // Overflow
|
||||
#define PMC3_COUNTER 0x7FFFFFFF // Counter value
|
||||
#define PMC4_OV 0x80000000 // Overflow
|
||||
#define PMC4_COUNTER 0x7FFFFFFF // Counter value
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
PMC1 Events
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define MMCR0_PMC1_HOLD 0x00000000 // Register holds current value
|
||||
#define MMCR0_PMC1_CYCLE 0x00000040 // Processor cycles
|
||||
#define MMCR0_PMC1_INSTRUCTION 0x00000080 // # of instructions completed.
|
||||
#define MMCR0_PMC1_TRANSITION 0x000000C0 // # of transitions for 0 to 1
|
||||
#define MMCR0_PMC1_DISPATCHED 0x00000100 // # of instructions dispatched
|
||||
#define MMCR0_PMC1_EIEIO 0x00000140 // # of eieio instructions completed
|
||||
#define MMCR0_PMC1_ITLB_CYCLE 0x00000180 // # of cycles spent performing table search op. for the ITLB
|
||||
#define MMCR0_PMC1_L2_HIT 0x000001C0 // # of access that hit the L2.
|
||||
#define MMCR0_PMC1_EA 0x00000200 // # of valid instruction EAs delivered to the memory subsystem
|
||||
#define MMCR0_PMC1_IABR 0x00000240 // # of time the address of an instruction matches the IABR
|
||||
#define MMCR0_PMC1_L1_MISS 0x00000280 // # of loads that miss the L1
|
||||
#define MMCR0_PMC1_Bx_UNRESOLVED 0x000002C0 // # of branches that are unresolved when processed
|
||||
#define MMCR0_PMC1_Bx_STALL_CYCLE 0x00000300 // # of cycles that dispatcher stalls due to a second
|
||||
// unresolved branch in the instruction stream
|
||||
#define MMCR0_PMC1_IC_FETCH_MISS 0x00000340 // # of times an instruction fetch missed the L1 Icache
|
||||
#define MMCR0_PMC2_HOLD 0x00000000 // Register holds current value
|
||||
#define MMCR0_PMC2_CYCLE 0x00000001 // Processor cycles
|
||||
#define MMCR0_PMC2_INSTRUCTION 0x00000002 // # of instructions completed
|
||||
#define MMCR0_PMC2_TRANSITION 0x00000003 // # of time-base (lower) bit transitions
|
||||
#define MMCR0_PMC2_DISPATCHED 0x00000004 // # of instructions dispatched
|
||||
#define MMCR0_PMC2_IC_MISS 0x00000005 // # of L1 instruction cache misses
|
||||
#define MMCR0_PMC2_ITLB_MISS 0x00000006 // # of ITLB misses
|
||||
#define MMCR0_PMC2_L2_I_MISS 0x00000007 // # of L2 instruction misses
|
||||
#define MMCR0_PMC2_Bx_FALL_TROUGH 0x00000008 // # of fall-through branches
|
||||
#define MMCR0_PMC2_PR_SWITCH 0x00000009 // # of MSR[PR] bit toggles
|
||||
#define MMCR0_PMC2_RESERVED_LOAD 0x0000000A // # of reserved loads completed
|
||||
#define MMCR0_PMC2_LOAD_STORE 0x0000000B // # of completed loads and stores
|
||||
#define MMCR0_PMC2_SNOOP 0x0000000C // # of snoops
|
||||
#define MMCR0_PMC2_L1_CASTOUT 0x0000000D // # of L1 castouts to L2
|
||||
#define MMCR0_PMC2_SYSTEM 0x0000000E // # of completed system unit instructions
|
||||
#define MMCR0_PMC2_IC_FETCH_MISS 0x0000000F // # of instruction fetch misses in the L1
|
||||
#define MMCR0_PMC2_Bx_OUT_OF_ORDER 0x00000010 // # of branches allowing out-of-order execution
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
PMC3 Events
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define MMCR1_PMC3_HOLD 0x00000000 // Register holds current value
|
||||
#define MMCR1_PMC3_CYCLE 0x08000000 // Processor cycles
|
||||
#define MMCR1_PMC3_INSTRUCTION 0x10000000 // # of instructions completed
|
||||
#define MMCR1_PMC3_TRANSITION 0x18000000 // # of time-base (lower) bit transitions
|
||||
#define MMCR1_PMC3_DISPATCHED 0x20000000 // # of instructions dispatched
|
||||
#define MMCR1_PMC3_DC_MISS 0x28000000 // # of L1 data cache misses
|
||||
#define MMCR1_PMC3_DTLB_MISS 0x30000000 // # of DTLB misses
|
||||
#define MMCR1_PMC3_L2_D_MISS 0x38000000 // # of L2 data misses
|
||||
#define MMCR1_PMC3_Bx_TAKEN 0x40000000 // # predicted branches that were taken
|
||||
#define MMCR1_PMC3_PM_SWITCH 0x48000000 // # of transitions between marked and unmarked processes
|
||||
#define MMCR1_PMC3_COND_STORE 0x50000000 // # of store conditional instructions completed
|
||||
#define MMCR1_PMC3_FPU 0x58000000 // # of instructions completed from the FPU
|
||||
#define MMCR1_PMC3_L2_SNOOP_CASTOUT 0x60000000 // # of L2 castout caused by snoops to modified lines
|
||||
#define MMCR1_PMC3_L2_HIT 0x68000000 // # of cache operations that hit in the L2 cache
|
||||
#define MMCR1_PMC3_L1_MISS_CYCLE 0x78000000 // # of cycles generated by L1 load misses
|
||||
#define MMCR1_PMC3_Bx_SECOND 0x80000000 // # of branches in the second speculative branch
|
||||
// resolved correctly
|
||||
#define MMCR1_PMC3_BPU_LR_CR 0x88000000 // # of cycles the BPU stalls due to LR or CR unresolved
|
||||
// dependencies
|
||||
|
||||
#define MMCR1_PMC4_HOLD 0x00000000 // Register holds current value
|
||||
#define MMCR1_PMC4_CYCLE 0x00400000 // Processor cycles
|
||||
#define MMCR1_PMC4_INSTRUCTION 0x00800000 // # of instructions completed
|
||||
#define MMCR1_PMC4_TRANSITION 0x00C00000 // # of time-base (lower) bit transitions
|
||||
#define MMCR1_PMC4_DISPATCHED 0x01000000 // # of instructions dispatched
|
||||
#define MMCR1_PMC4_L2_CASTOUT 0x01400000 // # of L2 castouts
|
||||
#define MMCR1_PMC4_DTLB_CYCLE 0x01800000 // # of cycles spent performing table searches for DTLB accesses
|
||||
#define MMCR1_PMC4_Bx_MISSED 0x02000000 // # of mispredicted branches
|
||||
#define MMCR1_PMC4_COND_STORE_INT 0x02800000 // # of store conditional instructions completed
|
||||
// with reservation intact
|
||||
#define MMCR1_PMC4_SYNC 0x02C00000 // # of completed sync instructions
|
||||
#define MMCR1_PMC4_SNOOP_RETRY 0x03000000 // # of snoop request retries
|
||||
#define MMCR1_PMC4_INTEGER 0x03400000 // # of completed integer operations
|
||||
#define MMCR1_PMC4_BPU_THIRD 0x03800000 // # of cycles the BPU cannot process new branches
|
||||
// due to having two unresolved branches
|
||||
#define MMCR1_PMC4_DC_MISS 0x07C00000 // # of L1 data cache misses
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
FPSCR bits
|
||||
*---------------------------------------------------------------------------*/
|
||||
#ifndef FPSCR_FX
|
||||
#define FPSCR_FX 0x80000000 // Exception summary
|
||||
#define FPSCR_FEX 0x40000000 // Enabled exception summary
|
||||
#define FPSCR_VX 0x20000000 // Invalid operation
|
||||
#define FPSCR_OX 0x10000000 // Overflow exception
|
||||
#define FPSCR_UX 0x08000000 // Underflow exception
|
||||
#define FPSCR_ZX 0x04000000 // Zero divide exception
|
||||
#define FPSCR_XX 0x02000000 // Inexact exception
|
||||
#define FPSCR_VXSNAN 0x01000000 // SNaN
|
||||
#define FPSCR_VXISI 0x00800000 // Infinity - Infinity
|
||||
#define FPSCR_VXIDI 0x00400000 // Infinity / Infinity
|
||||
#define FPSCR_VXZDZ 0x00200000 // 0 / 0
|
||||
#define FPSCR_VXIMZ 0x00100000 // Infinity * 0
|
||||
#define FPSCR_VXVC 0x00080000 // Invalid compare
|
||||
#define FPSCR_FR 0x00040000 // Fraction rounded
|
||||
#define FPSCR_FI 0x00020000 // Fraction inexact
|
||||
#define FPSCR_VXSOFT 0x00000400 // Software request
|
||||
#define FPSCR_VXSQRT 0x00000200 // Invalid square root
|
||||
#define FPSCR_VXCVI 0x00000100 // Invalid integer convert
|
||||
#define FPSCR_VE 0x00000080 // Invalid operation exception enable
|
||||
#define FPSCR_OE 0x00000040 // Overflow exception enable
|
||||
#define FPSCR_UE 0x00000020 // Underflow exception enable
|
||||
#define FPSCR_ZE 0x00000010 // Zero divide exception enable
|
||||
#define FPSCR_XE 0x00000008 // Inexact exception enable
|
||||
#define FPSCR_NI 0x00000004 // Non-IEEE mode
|
||||
#endif
|
||||
|
||||
#ifndef FPSCR_FX_BIT
|
||||
#define FPSCR_FX_BIT 0 // Exception summary
|
||||
#define FPSCR_FEX_BIT 1 // Enabled exception summary
|
||||
#define FPSCR_VX_BIT 2 // Invalid operation
|
||||
#define FPSCR_OX_BIT 3 // Overflow exception
|
||||
#define FPSCR_UX_BIT 4 // Underflow exception
|
||||
#define FPSCR_ZX_BIT 5 // Zero divide exception
|
||||
#define FPSCR_XX_BIT 6 // Inexact exception
|
||||
#define FPSCR_VXSNAN_BIT 7 // SNaN
|
||||
#define FPSCR_VXISI_BIT 8 // Infinity - Infinity
|
||||
#define FPSCR_VXIDI_BIT 9 // Infinity / Infinity
|
||||
#define FPSCR_VXZDZ_BIT 10 // 0 / 0
|
||||
#define FPSCR_VXIMZ_BIT 11 // Infinity * 0
|
||||
#define FPSCR_VXVC_BIT 12 // Invalid compare
|
||||
#define FPSCR_FR_BIT 13 // Fraction rounded
|
||||
#define FPSCR_FI_BIT 14 // Fraction inexact
|
||||
#define FPSCR_VXSOFT_BIT 21 // Software request
|
||||
#define FPSCR_VXSQRT_BIT 22 // Invalid square root
|
||||
#define FPSCR_VXCVI_BIT 23 // Invalid integer convert
|
||||
#define FPSCR_VE_BIT 24 // Invalid operation exception enable
|
||||
#define FPSCR_OE_BIT 25 // Overflow exception enable
|
||||
#define FPSCR_UE_BIT 26 // Underflow exception enable
|
||||
#define FPSCR_ZE_BIT 27 // Zero divide exception enable
|
||||
#define FPSCR_XE_BIT 28 // Inexact exception enable
|
||||
#define FPSCR_NI_BIT 29 // Non-IEEE mode
|
||||
#endif
|
||||
|
||||
union FpscrUnion {
|
||||
f64 f;
|
||||
struct {
|
||||
u32 fpscr_pad;
|
||||
u32 fpscr;
|
||||
} u;
|
||||
};
|
||||
|
||||
// PPCArch
|
||||
u32 PPCMfmsr();
|
||||
void PPCMtmsr(u32 newMSR);
|
||||
u32 PPCOrMsr(u32 value);
|
||||
u32 PPCMfhid0();
|
||||
void PPCMthid0(u32 newHID0);
|
||||
u32 PPCMfl2cr();
|
||||
void PPCMtl2cr(u32 newL2cr);
|
||||
void PPCMtdec(u32 newDec);
|
||||
void PPCSync();
|
||||
void PPCHalt();
|
||||
u32 PPCMffpscr();
|
||||
void PPCMtfpscr(u32 newFPSCR);
|
||||
u32 PPCMfhid2();
|
||||
void PPCMthid2(u32 newhid2);
|
||||
u32 PPCMfwpar();
|
||||
void PPCMtwpar(u32 newwpar);
|
||||
void PPCEnableSpeculation();
|
||||
void PPCDisableSpeculation();
|
||||
void PPCSetFpIEEEMode();
|
||||
void PPCSetFpNonIEEEMode();
|
||||
u32 PPCMfpmc4();
|
||||
u32 PPCMfpmc3();
|
||||
u32 PPCMfpmc1();
|
||||
void PPCMtpmc1(u32 newPmc1);
|
||||
void PPCMtpmc2(u32 newPmc1);
|
||||
void PPCMtpmc3(u32 newPmc1);
|
||||
void PPCMtpmc4(u32 newPmc1);
|
||||
void PPCMtmmcr0(u32 newMmcr0);
|
||||
void PPCMtmmcr1(u32 newMmcr0);
|
||||
void PPCMtdmaU(u32 newdmau);
|
||||
void PPCMtdmaL(u32 newdmal);
|
||||
u32 PPCMfdec(void);
|
||||
u32 PPCMfpmc2(void);
|
||||
u32 PPCAndMsr(u32 value);
|
||||
u32 PPCAndCMsr(u32 value);
|
||||
u32 PPCMfhid1();
|
||||
void PPCEieio();
|
||||
u32 PPCMfmmcr0();
|
||||
u32 PPCMfmmcr1();
|
||||
u32 PPCMfpmc2();
|
||||
u32 PPCMfsia();
|
||||
void PPCMtsia(u32 newSia);
|
||||
u32 PPCMfdmaL();
|
||||
u32 PPCMfpvr();
|
||||
u32 PPCMfdmaU();
|
||||
|
||||
// PPCPm
|
||||
void PMBegin(void);
|
||||
void PMEnd(void);
|
||||
void PMCycles(void);
|
||||
void PML1FetchMisses(void);
|
||||
void PML1MissCycles(void);
|
||||
void PMInstructions(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DOLPHIN_PPCARCH
|
||||
@@ -1,340 +0,0 @@
|
||||
#ifndef _DOLPHIN_CARD_H_
|
||||
#define _DOLPHIN_CARD_H_
|
||||
|
||||
#include <dolphin/os.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CARD_FILENAME_MAX 32
|
||||
#define CARD_MAX_FILE 127
|
||||
#define CARD_ICON_MAX 8
|
||||
|
||||
#if TARGET_PC
|
||||
|
||||
typedef enum {
|
||||
CARD_RAWIMAGE,
|
||||
CARD_GCIFOLDER,
|
||||
} CARDFileType;
|
||||
|
||||
#endif
|
||||
|
||||
typedef void (*CARDCallback)(s32 chan, s32 result);
|
||||
|
||||
typedef struct CARDFileInfo {
|
||||
s32 chan;
|
||||
s32 fileNo;
|
||||
s32 offset;
|
||||
s32 length;
|
||||
u16 iBlock;
|
||||
} CARDFileInfo;
|
||||
|
||||
typedef struct CARDDir {
|
||||
u8 gameName[4];
|
||||
u8 company[2];
|
||||
u8 _padding0;
|
||||
u8 bannerFormat;
|
||||
u8 fileName[CARD_FILENAME_MAX];
|
||||
u32 time; // seconds since 01/01/2000 midnight
|
||||
u32 iconAddr; // 0xffffffff if not used
|
||||
u16 iconFormat;
|
||||
u16 iconSpeed;
|
||||
u8 permission;
|
||||
u8 copyTimes;
|
||||
u16 startBlock;
|
||||
u16 length;
|
||||
u8 _padding1[2];
|
||||
u32 commentAddr; // 0xffffffff if not used
|
||||
} CARDDir;
|
||||
|
||||
typedef struct CARDControl {
|
||||
/* 0x000 */ BOOL attached;
|
||||
/* 0x004 */ s32 result;
|
||||
/* 0x008 */ u16 size;
|
||||
/* 0x00A */ u16 pageSize;
|
||||
/* 0x00C */ s32 sectorSize;
|
||||
/* 0x010 */ u16 cBlock;
|
||||
/* 0x012 */ u16 vendorID;
|
||||
/* 0x014 */ s32 latency;
|
||||
/* 0x018 */ u8 id[12];
|
||||
/* 0x024 */ int mountStep;
|
||||
/* 0x028 */ int formatStep;
|
||||
/* 0x028 */ u32 scramble;
|
||||
/* 0x02C */ DSPTaskInfo task;
|
||||
/* 0x080 */ void* workArea;
|
||||
/* 0x084 */ CARDDir *currentDir;
|
||||
/* 0x088 */ u16* currentFat;
|
||||
/* 0x08C */ OSThreadQueue threadQueue;
|
||||
/* 0x094 */ u8 cmd[9];
|
||||
/* 0x0A0 */ s32 cmdlen;
|
||||
/* 0x0A4 */ volatile u32 mode;
|
||||
/* 0x0A8 */ int retry;
|
||||
/* 0x0AC */ int repeat;
|
||||
/* 0x0B0 */ u32 addr;
|
||||
/* 0x0B4 */ void* buffer;
|
||||
/* 0x0B8 */ s32 xferred;
|
||||
/* 0x0BC */ u16 freeNo;
|
||||
/* 0x0BE */ u16 startBlock;
|
||||
/* 0x0C0 */ CARDFileInfo* fileInfo;
|
||||
/* 0x0C4 */ CARDCallback extCallback;
|
||||
/* 0x0C8 */ CARDCallback txCallback;
|
||||
/* 0x0CC */ CARDCallback exiCallback;
|
||||
/* 0x0D0 */ CARDCallback apiCallback;
|
||||
/* 0x0D4 */ CARDCallback xferCallback;
|
||||
/* 0x0D8 */ CARDCallback eraseCallback;
|
||||
/* 0x0DC */ CARDCallback unlockCallback;
|
||||
/* 0x0E0 */ OSAlarm alarm;
|
||||
/* 0x108 */ u32 cid;
|
||||
/* 0x10C */ const DVDDiskID* diskID;
|
||||
} CARDControl;
|
||||
|
||||
typedef struct CARDDecParam {
|
||||
/* 0x00 */ u8* inputAddr;
|
||||
/* 0x04 */ u32 inputLength;
|
||||
/* 0x08 */ u32 aramAddr;
|
||||
/* 0x0C */ u8* outputAddr;
|
||||
} CARDDecParam;
|
||||
|
||||
typedef struct CARDID {
|
||||
/* 0x000 */ u8 serial[32];
|
||||
/* 0x020 */ u16 deviceID;
|
||||
/* 0x022 */ u16 size;
|
||||
/* 0x024 */ u16 encode;
|
||||
/* 0x026 */ u8 padding[470];
|
||||
/* 0x1FC */ u16 checkSum;
|
||||
/* 0x1FE */ u16 checkSumInv;
|
||||
} CARDID;
|
||||
|
||||
typedef struct CARDDirCheck {
|
||||
/* 0x00 */ u8 padding0[56];
|
||||
/* 0x38 */ u16 padding1;
|
||||
/* 0x3A */ s16 checkCode;
|
||||
/* 0x3C */ u16 checkSum;
|
||||
/* 0x3E */ u16 checkSumInv;
|
||||
} CARDDirCheck;
|
||||
|
||||
typedef struct CARDStat {
|
||||
/* 0x00 */ char fileName[CARD_FILENAME_MAX];
|
||||
/* 0x20 */ u32 length;
|
||||
/* 0x24 */ u32 time;
|
||||
/* 0x28 */ u8 gameName[4];
|
||||
/* 0x2C */ u8 company[2];
|
||||
/* 0x2E */ u8 bannerFormat;
|
||||
/* 0x30 */ u32 iconAddr;
|
||||
/* 0x34 */ u16 iconFormat;
|
||||
/* 0x36 */ u16 iconSpeed;
|
||||
/* 0x38 */ u32 commentAddr;
|
||||
/* 0x3C */ u32 offsetBanner;
|
||||
/* 0x40 */ u32 offsetBannerTlut;
|
||||
/* 0x44 */ u32 offsetIcon[CARD_ICON_MAX];
|
||||
/* 0x64 */ u32 offsetIconTlut;
|
||||
/* 0x68 */ u32 offsetData;
|
||||
} CARDStat;
|
||||
|
||||
#define CARD_ATTR_PUBLIC 0x04u
|
||||
#define CARD_ATTR_NO_COPY 0x08u
|
||||
#define CARD_ATTR_NO_MOVE 0x10u
|
||||
#define CARD_ATTR_GLOBAL 0x20u
|
||||
#define CARD_ATTR_COMPANY 0x40u
|
||||
|
||||
#define CARD_FAT_AVAIL 0x0000u
|
||||
#define CARD_FAT_CHECKSUM 0x0000u
|
||||
#define CARD_FAT_CHECKSUMINV 0x0001u
|
||||
#define CARD_FAT_CHECKCODE 0x0002u
|
||||
#define CARD_FAT_FREEBLOCKS 0x0003u
|
||||
#define CARD_FAT_LASTSLOT 0x0004u
|
||||
|
||||
#define CARD_WORKAREA_SIZE (5 * 8 * 1024)
|
||||
|
||||
#define CARD_SEG_SIZE 0x200u
|
||||
#define CARD_PAGE_SIZE 0x80u
|
||||
#define CARD_MAX_SIZE 0x01000000U
|
||||
|
||||
#define CARD_NUM_SYSTEM_BLOCK 5
|
||||
#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u)
|
||||
|
||||
#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2)
|
||||
|
||||
#define CARD_STAT_SPEED_END 0
|
||||
#define CARD_STAT_SPEED_FAST 1
|
||||
#define CARD_STAT_SPEED_MIDDLE 2
|
||||
#define CARD_STAT_SPEED_SLOW 3
|
||||
#define CARD_STAT_SPEED_MASK 3
|
||||
|
||||
#define CARD_STAT_ANIM_LOOP 0
|
||||
#define CARD_STAT_ANIM_BOUNCE 4
|
||||
#define CARD_STAT_ANIM_MASK 0x4
|
||||
|
||||
#define CARD_RESULT_UNLOCKED 1
|
||||
#define CARD_RESULT_READY 0
|
||||
#define CARD_RESULT_BUSY -1
|
||||
#define CARD_RESULT_WRONGDEVICE -2
|
||||
#define CARD_RESULT_NOCARD -3
|
||||
#define CARD_RESULT_NOFILE -4
|
||||
#define CARD_RESULT_IOERROR -5
|
||||
#define CARD_RESULT_BROKEN -6
|
||||
#define CARD_RESULT_EXIST -7
|
||||
#define CARD_RESULT_NOENT -8
|
||||
#define CARD_RESULT_INSSPACE -9
|
||||
#define CARD_RESULT_NOPERM -10
|
||||
#define CARD_RESULT_LIMIT -11
|
||||
#define CARD_RESULT_NAMETOOLONG -12
|
||||
#define CARD_RESULT_ENCODING -13
|
||||
#define CARD_RESULT_CANCELED -14
|
||||
#define CARD_RESULT_FATAL_ERROR -128
|
||||
|
||||
#define CARDIsValidBlockNo(card, blockNo) ((blockNo) >= CARD_NUM_SYSTEM_BLOCK && (blockNo) < (card)->cBlock)
|
||||
|
||||
#define CARD_READ_SIZE 512
|
||||
|
||||
#define CARD_COMMENT_SIZE 64
|
||||
|
||||
#define CARD_ICON_WIDTH 32
|
||||
#define CARD_ICON_HEIGHT 32
|
||||
|
||||
#define CARD_BANNER_WIDTH 96
|
||||
#define CARD_BANNER_HEIGHT 32
|
||||
|
||||
#define CARD_STAT_ICON_NONE 0
|
||||
#define CARD_STAT_ICON_C8 1
|
||||
#define CARD_STAT_ICON_RGB5A3 2
|
||||
#define CARD_STAT_ICON_MASK 3
|
||||
|
||||
#define CARD_STAT_BANNER_NONE 0
|
||||
#define CARD_STAT_BANNER_C8 1
|
||||
#define CARD_STAT_BANNER_RGB5A3 2
|
||||
#define CARD_STAT_BANNER_MASK 3
|
||||
|
||||
#define CARD_ENCODE_ANSI 0
|
||||
#define CARD_ENCODE_SJIS 1
|
||||
|
||||
#define CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE])
|
||||
#define CARDGetBannerFormat(stat) (((stat)->bannerFormat) & CARD_STAT_BANNER_MASK)
|
||||
#define CARDGetIconAnim(stat) (((stat)->bannerFormat) & CARD_STAT_ANIM_MASK)
|
||||
#define CARDGetIconFormat(stat, n) (((stat)->iconFormat >> (2 * (n))) & CARD_STAT_ICON_MASK)
|
||||
#define CARDGetIconSpeed(stat, n) (((stat)->iconSpeed >> (2 * (n))) & CARD_STAT_SPEED_MASK)
|
||||
#define CARDSetBannerFormat(stat, f) \
|
||||
((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_BANNER_MASK) | (f)))
|
||||
#define CARDSetIconAnim(stat, f) \
|
||||
((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_ANIM_MASK) | (f)))
|
||||
#define CARDSetIconFormat(stat, n, f) \
|
||||
((stat)->iconFormat = \
|
||||
(u16)(((stat)->iconFormat & ~(CARD_STAT_ICON_MASK << (2 * (n)))) | ((f) << (2 * (n)))))
|
||||
#define CARDSetIconSpeed(stat, n, f) \
|
||||
((stat)->iconSpeed = \
|
||||
(u16)(((stat)->iconSpeed & ~(CARD_STAT_SPEED_MASK << (2 * (n)))) | ((f) << (2 * (n)))))
|
||||
#define CARDSetIconAddress(stat, addr) ((stat)->iconAddr = (u32)(addr))
|
||||
#define CARDSetCommentAddress(stat, addr) ((stat)->commentAddr = (u32)(addr))
|
||||
#define CARDGetFileNo(fileInfo) ((fileInfo)->fileNo)
|
||||
|
||||
extern u32 __CARDFreq;
|
||||
|
||||
#if DEBUG
|
||||
#define CARDFreq __CARDFreq
|
||||
#else
|
||||
#define CARDFreq EXI_FREQ_16M
|
||||
#endif
|
||||
|
||||
s32 CARDRenameAsync(s32 chan, const char* oldName, const char* newName, CARDCallback callback);
|
||||
|
||||
// CARDBios
|
||||
#if TARGET_PC
|
||||
void CARDInit(const char* game, const char* maker);
|
||||
void CARDSetGameAndMaker(const s32 chan, const char* game, const char* maker);
|
||||
|
||||
// pass -1 to set both
|
||||
void CARDDetectDolphin(s32 chan);
|
||||
// pass -1 to set both
|
||||
void CARDSetBasePath(const char*, s32 chan);
|
||||
void CARDSetLoadType(CARDFileType type);
|
||||
|
||||
#else
|
||||
void CARDInit(void);
|
||||
#endif
|
||||
s32 CARDGetResultCode(s32 chan);
|
||||
s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed);
|
||||
s32 CARDGetEncoding(s32 chan, u16* encode);
|
||||
s32 CARDGetMemSize(s32 chan, u16* size);
|
||||
s32 CARDGetSectorSize(s32 chan, u32* size);
|
||||
const DVDDiskID* CARDGetDiskID(s32 chan);
|
||||
s32 CARDSetDiskID(s32 chan, const DVDDiskID* diskID);
|
||||
BOOL CARDSetFastMode(BOOL enable);
|
||||
BOOL CARDGetFastMode(void);
|
||||
s32 CARDGetCurrentMode(s32 chan, u32* mode);
|
||||
|
||||
// CARDCheck
|
||||
s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback);
|
||||
s32 CARDCheckAsync(s32 chan, CARDCallback callback);
|
||||
s32 CARDCheckEx(s32 chan, s32* xferBytes);
|
||||
s32 CARDCheck(s32 chan);
|
||||
|
||||
// CARDCreate
|
||||
s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback);
|
||||
s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo);
|
||||
|
||||
// CARDDelete
|
||||
s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback);
|
||||
s32 CARDFastDelete(s32 chan, s32 fileNo);
|
||||
s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback);
|
||||
s32 CARDDelete(s32 chan, const char* fileName);
|
||||
|
||||
// CARDErase
|
||||
s32 CARDEraseAsync(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDCallback callback);
|
||||
s32 CARDErase(CARDFileInfo* fileInfo, s32 length, s32 offset);
|
||||
|
||||
// CARDFormat
|
||||
s32 CARDFormat(s32 chan);
|
||||
|
||||
// CARDMount
|
||||
int CARDProbe(s32 chan);
|
||||
s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize);
|
||||
s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback);
|
||||
s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback);
|
||||
s32 CARDUnmount(s32 chan);
|
||||
|
||||
// CARDNet
|
||||
u16 CARDSetVendorID(u16 vendorID);
|
||||
u16 CARDGetVendorID();
|
||||
s32 CARDGetSerialNo(s32 chan, u64* serialNo);
|
||||
s32 CARDGetUniqueCode(s32 chan, u64* uniqueCode);
|
||||
s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr);
|
||||
s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback);
|
||||
s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr);
|
||||
|
||||
// CARDOpen
|
||||
s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo);
|
||||
s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo);
|
||||
s32 CARDClose(CARDFileInfo* fileInfo);
|
||||
|
||||
// CARDProgram
|
||||
s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback);
|
||||
s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset);
|
||||
|
||||
// CARDRdwr
|
||||
s32 CARDGetXferredBytes(s32 chan);
|
||||
|
||||
// CARDRead
|
||||
s32 CARDReadAsync(const CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset, CARDCallback callback);
|
||||
s32 CARDRead(const CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset);
|
||||
s32 CARDCancel(CARDFileInfo* fileInfo);
|
||||
|
||||
// CARDRename
|
||||
s32 CARDRename(s32 chan, const char* oldName, const char* newName);
|
||||
|
||||
// CARDStat
|
||||
s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat);
|
||||
s32 CARDSetStatusAsync(s32 chan, s32 fileNo, const CARDStat* stat, CARDCallback callback);
|
||||
s32 CARDSetStatus(s32 chan, s32 fileNo, const CARDStat* stat);
|
||||
|
||||
// CARDWrite
|
||||
s32 CARDWriteAsync(const CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset, CARDCallback callback);
|
||||
s32 CARDWrite(const CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _DOLPHIN_DB_H_
|
||||
#define _DOLPHIN_DB_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/db/DBInterface.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OS_DBINTERFACE_ADDR 0x00000040
|
||||
|
||||
BOOL DBIsDebuggerPresent(void);
|
||||
void DBPrintf(char* str, ...);
|
||||
s32 DBQueryData(void);
|
||||
u32 DBRead(u8*, u32);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DOLPHIN_DB_H_
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef _DOLPHIN_DBINTERFACE_H_
|
||||
#define _DOLPHIN_DBINTERFACE_H_
|
||||
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct DBInterface {
|
||||
u32 bPresent;
|
||||
u32 exceptionMask;
|
||||
void (*ExceptionDestination)(void);
|
||||
void* exceptionReturn;
|
||||
} DBInterface;
|
||||
|
||||
extern DBInterface* __DBInterface;
|
||||
|
||||
void DBInit(void);
|
||||
void DBInitComm(int* inputFlagPtr, int* mtrCallback);
|
||||
void __DBExceptionDestination(void);
|
||||
void __DBExceptionDestinationAux(void);
|
||||
BOOL __DBIsExceptionMarked(__OSException exception);
|
||||
void __DBMarkException(u8 exception, int value);
|
||||
void __DBSetPresent(u32 value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef _DOLPHIN_H_
|
||||
#define _DOLPHIN_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/os.h>
|
||||
#include <dolphin/dsp.h>
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/gx.h>
|
||||
#include <dolphin/hio.h>
|
||||
#include <dolphin/mtx.h>
|
||||
#include <dolphin/vi.h>
|
||||
#include <dolphin/card.h>
|
||||
#include <dolphin/perf.h>
|
||||
#include <dolphin/ar.h>
|
||||
#include <dolphin/base/PPCArch.h>
|
||||
#include <dolphin/db.h>
|
||||
#include <dolphin/pad.h>
|
||||
#include <dolphin/dtk.h>
|
||||
#include <dolphin/ai.h>
|
||||
// #include <dolphin/demo.h>
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/si.h>
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef _DOLPHIN_DSP_H_
|
||||
#define _DOLPHIN_DSP_H_
|
||||
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*DSPCallback)(void* task);
|
||||
typedef struct STRUCT_DSP_TASK DSPTaskInfo;
|
||||
|
||||
typedef struct STRUCT_DSP_TASK {
|
||||
/* 0x00 */ volatile u32 state;
|
||||
/* 0x04 */ volatile u32 priority;
|
||||
/* 0x08 */ volatile u32 flags;
|
||||
/* 0x0C */ u16* iram_mmem_addr;
|
||||
/* 0x10 */ u32 iram_length;
|
||||
/* 0x14 */ u32 iram_addr;
|
||||
/* 0x18 */ u16* dram_mmem_addr;
|
||||
/* 0x1C */ u32 dram_length;
|
||||
/* 0x20 */ u32 dram_addr;
|
||||
/* 0x24 */ u16 dsp_init_vector;
|
||||
/* 0x26 */ u16 dsp_resume_vector;
|
||||
/* 0x28 */ DSPCallback init_cb;
|
||||
/* 0x2C */ DSPCallback res_cb;
|
||||
/* 0x30 */ DSPCallback done_cb;
|
||||
/* 0x34 */ DSPCallback req_cb;
|
||||
/* 0x38 */ DSPTaskInfo* next;
|
||||
/* 0x3C */ DSPTaskInfo* prev;
|
||||
/* 0x40 */ OSTime t_context;
|
||||
/* 0x48 */ OSTime t_task;
|
||||
} DSPTaskInfo;
|
||||
|
||||
u32 DSPCheckMailToDSP(void);
|
||||
u32 DSPCheckMailFromDSP(void);
|
||||
u32 DSPReadCPUToDSPMbox(void);
|
||||
u32 DSPReadMailFromDSP(void);
|
||||
void DSPSendMailToDSP(u32 mail);
|
||||
void DSPAssertInt(void);
|
||||
void DSPInit(void);
|
||||
BOOL DSPCheckInit(void);
|
||||
void DSPReset(void);
|
||||
void DSPHalt(void);
|
||||
void DSPUnhalt(void);
|
||||
u32 DSPGetDMAStatus(void);
|
||||
DECL_WEAK DSPTaskInfo* DSPAddTask(DSPTaskInfo* task);
|
||||
DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task);
|
||||
DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task);
|
||||
|
||||
DSPTaskInfo* __DSPGetCurrentTask(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef _DOLPHIN_DTK_H_
|
||||
#define _DOLPHIN_DTK_H_
|
||||
|
||||
#include <dolphin/dvd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*DTKCallback)(u32 eventMask);
|
||||
typedef void (*DTKFlushCallback)(void);
|
||||
|
||||
typedef struct DTKTrack {
|
||||
/* 0x00 */ struct DTKTrack* prev;
|
||||
/* 0x04 */ struct DTKTrack* next;
|
||||
/* 0x08 */ char* fileName;
|
||||
/* 0x0C */ u32 eventMask;
|
||||
/* 0x10 */ DTKCallback callback;
|
||||
/* 0x14 */ DVDFileInfo dvdFileInfo;
|
||||
} DTKTrack;
|
||||
|
||||
#define DTK_STATE_STOP 0
|
||||
#define DTK_STATE_RUN 1
|
||||
#define DTK_STATE_PAUSE 2
|
||||
#define DTK_STATE_BUSY 3
|
||||
#define DTK_STATE_PREPARE 4
|
||||
|
||||
#define DTK_MODE_NOREPEAT 0
|
||||
#define DTK_MODE_ALLREPEAT 1
|
||||
#define DTK_MODE_REPEAT1 2
|
||||
|
||||
void DTKInit(void);
|
||||
void DTKShutdown(void);
|
||||
u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback);
|
||||
u32 DTKRemoveTrack(DTKTrack* track);
|
||||
int DTKFlushTracks(DTKFlushCallback callback);
|
||||
void DTKSetSampleRate(u32 samplerate);
|
||||
void DTKSetInterruptFrequency(u32 samples);
|
||||
void DTKSetRepeatMode(u32 repeat);
|
||||
int DTKSetState(u32 state);
|
||||
int DTKNextTrack(void);
|
||||
int DTKPrevTrack(void);
|
||||
u32 DTKGetSampleRate(void);
|
||||
u32 DTKGetRepeatMode(void);
|
||||
u32 DTKGetState(void);
|
||||
u32 DTKGetPosition(void);
|
||||
u32 DTKGetInterruptFrequency(void);
|
||||
DTKTrack* DTKGetCurrentTrack(void);
|
||||
void DTKSetVolume(u8 left, u8 right);
|
||||
u16 DTKGetVolume(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,237 +0,0 @@
|
||||
#ifndef _DOLPHIN_DVD_H_
|
||||
#define _DOLPHIN_DVD_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DVD_ASSERTMSGLINE(line, cond, msg) \
|
||||
if (!(cond)) \
|
||||
OSPanic(__FILE__, line, msg)
|
||||
|
||||
#define DVD_ASSERTMSG1LINE(line, cond, msg, arg1) \
|
||||
if (!(cond)) \
|
||||
OSPanic(__FILE__, line, msg, arg1)
|
||||
|
||||
#define DVD_ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \
|
||||
if (!(cond)) \
|
||||
OSPanic(__FILE__, line, msg, arg1, arg2)
|
||||
|
||||
#define DVD_RESULT_GOOD 0
|
||||
#define DVD_RESULT_FATAL_ERROR -1
|
||||
#define DVD_RESULT_IGNORED -2
|
||||
#define DVD_RESULT_CANCELED -6
|
||||
|
||||
#define DVD_STATE_FATAL_ERROR -1
|
||||
#define DVD_STATE_END 0
|
||||
#define DVD_STATE_BUSY 1
|
||||
#define DVD_STATE_WAITING 2
|
||||
#define DVD_STATE_COVER_CLOSED 3
|
||||
#define DVD_STATE_NO_DISK 4
|
||||
#define DVD_STATE_COVER_OPEN 5
|
||||
#define DVD_STATE_WRONG_DISK 6
|
||||
#define DVD_STATE_MOTOR_STOPPED 7
|
||||
#define DVD_STATE_PAUSING 8
|
||||
#define DVD_STATE_IGNORED 9
|
||||
#define DVD_STATE_CANCELED 10
|
||||
#define DVD_STATE_RETRY 11
|
||||
|
||||
#define DVD_MIN_TRANSFER_SIZE 32
|
||||
|
||||
// could be bitfields
|
||||
#define DVD_INTTYPE_TC 1
|
||||
#define DVD_INTTYPE_DE 2
|
||||
// unk type 3
|
||||
#define DVD_INTTYPE_CVR 4
|
||||
|
||||
// DVD Commands
|
||||
#define DVD_COMMAND_NONE 0
|
||||
#define DVD_COMMAND_READ 1
|
||||
#define DVD_COMMAND_SEEK 2
|
||||
#define DVD_COMMAND_CHANGE_DISK 3
|
||||
#define DVD_COMMAND_BSREAD 4
|
||||
#define DVD_COMMAND_READID 5
|
||||
#define DVD_COMMAND_INITSTREAM 6
|
||||
#define DVD_COMMAND_CANCELSTREAM 7
|
||||
#define DVD_COMMAND_STOP_STREAM_AT_END 8
|
||||
#define DVD_COMMAND_REQUEST_AUDIO_ERROR 9
|
||||
#define DVD_COMMAND_REQUEST_PLAY_ADDR 10
|
||||
#define DVD_COMMAND_REQUEST_START_ADDR 11
|
||||
#define DVD_COMMAND_REQUEST_LENGTH 12
|
||||
#define DVD_COMMAND_AUDIO_BUFFER_CONFIG 13
|
||||
#define DVD_COMMAND_INQUIRY 14
|
||||
#define DVD_COMMAND_BS_CHANGE_DISK 15
|
||||
#define DVD_COMMAND_UNK_16 16
|
||||
|
||||
typedef struct DVDDiskID {
|
||||
char gameName[4];
|
||||
char company[2];
|
||||
u8 diskNumber;
|
||||
u8 gameVersion;
|
||||
u8 streaming;
|
||||
u8 streamingBufSize;
|
||||
u8 padding[22];
|
||||
} DVDDiskID;
|
||||
|
||||
typedef struct DVDCommandBlock DVDCommandBlock;
|
||||
typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block);
|
||||
typedef void (*DVDLowCallback)(u32);
|
||||
|
||||
typedef void (*DVDCommandCheckerCallback)(u32);
|
||||
typedef void (*DVDCommandChecker)(DVDCommandBlock*, DVDCommandCheckerCallback);
|
||||
|
||||
struct DVDCommandBlock {
|
||||
/* 0x00 */ DVDCommandBlock* next;
|
||||
/* 0x04 */ DVDCommandBlock* prev;
|
||||
/* 0x08 */ u32 command;
|
||||
/* 0x0C */ s32 state;
|
||||
/* 0x10 */ u32 offset;
|
||||
/* 0x14 */ u32 length;
|
||||
/* 0x18 */ void* addr;
|
||||
/* 0x1C */ u32 currTransferSize;
|
||||
/* 0x20 */ u32 transferredSize;
|
||||
/* 0x24 */ DVDDiskID* id;
|
||||
/* 0x28 */ DVDCBCallback callback;
|
||||
/* 0x2C */ void* userData;
|
||||
};
|
||||
|
||||
typedef struct DVDFileInfo DVDFileInfo;
|
||||
typedef void (*DVDCallback)(s32 result, DVDFileInfo *fileInfo);
|
||||
struct DVDFileInfo {
|
||||
/* 0x00 */ DVDCommandBlock cb;
|
||||
/* 0x30 */ u32 startAddr;
|
||||
/* 0x34 */ u32 length;
|
||||
/* 0x38 */ DVDCallback callback;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u32 entryNum;
|
||||
u32 location;
|
||||
u32 next;
|
||||
} DVDDir;
|
||||
|
||||
typedef struct {
|
||||
u32 entryNum;
|
||||
BOOL isDir;
|
||||
char* name;
|
||||
} DVDDirEntry;
|
||||
|
||||
typedef struct DVDBB2 {
|
||||
/* 0x00 */ u32 bootFilePosition;
|
||||
/* 0x04 */ u32 FSTPosition;
|
||||
/* 0x08 */ u32 FSTLength;
|
||||
/* 0x0C */ u32 FSTMaxLength;
|
||||
/* 0x10 */ void* FSTAddress;
|
||||
/* 0x14 */ u32 userPosition;
|
||||
/* 0x18 */ u32 userLength;
|
||||
/* 0x1C */ u32 padding0;
|
||||
} DVDBB2;
|
||||
|
||||
typedef struct DVDDriveInfo {
|
||||
/* 0x00 */ u16 revisionLevel;
|
||||
/* 0x02 */ u16 deviceCode;
|
||||
/* 0x04 */ u32 releaseDate;
|
||||
/* 0x08 */ u8 padding[24];
|
||||
} DVDDriveInfo;
|
||||
|
||||
// DVD
|
||||
void DVDInit(void);
|
||||
int DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback, s32 prio);
|
||||
int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio);
|
||||
int DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback);
|
||||
int DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback);
|
||||
int DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, DVDCBCallback callback);
|
||||
int DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDCancelStream(DVDCommandBlock* block);
|
||||
int DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDStopStreamAtEnd(DVDCommandBlock* block);
|
||||
int DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDGetStreamErrorStatus(DVDCommandBlock* block);
|
||||
int DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDGetStreamPlayAddr(DVDCommandBlock* block);
|
||||
int DVDGetStreamStartAddrAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDGetStreamStartAddr(DVDCommandBlock* block);
|
||||
int DVDGetStreamLengthAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDGetStreamLength(DVDCommandBlock* block);
|
||||
int DVDChangeDiskAsyncForBS(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
int DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback);
|
||||
s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id);
|
||||
int DVDStopMotorAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDStopMotor(DVDCommandBlock* block);
|
||||
int DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback);
|
||||
s32 DVDInquiry(DVDCommandBlock* block, DVDDriveInfo* info);
|
||||
void DVDReset(void);
|
||||
int DVDResetRequired(void);
|
||||
s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block);
|
||||
s32 DVDGetDriveStatus(void);
|
||||
BOOL DVDSetAutoInvalidation(BOOL autoInval);
|
||||
void DVDPause(void);
|
||||
void DVDResume(void);
|
||||
int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback);
|
||||
s32 DVDCancel(volatile DVDCommandBlock* block);
|
||||
int DVDCancelAllAsync(DVDCBCallback callback);
|
||||
s32 DVDCancelAll(void);
|
||||
DVDDiskID* DVDGetCurrentDiskID(void);
|
||||
BOOL DVDCheckDisk(void);
|
||||
|
||||
// DVD FATAL
|
||||
int DVDSetAutoFatalMessaging(BOOL enable);
|
||||
|
||||
// DVD FS
|
||||
s32 DVDConvertPathToEntrynum(const char* pathPtr);
|
||||
BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo);
|
||||
BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo);
|
||||
BOOL DVDClose(DVDFileInfo* fileInfo);
|
||||
BOOL DVDGetCurrentDir(char* path, u32 maxlen);
|
||||
BOOL DVDChangeDir(const char* dirName);
|
||||
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
|
||||
DVDCallback callback, s32 prio);
|
||||
s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio);
|
||||
int DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, void (* callback)(s32, DVDFileInfo *), s32 prio);
|
||||
s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio);
|
||||
s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo);
|
||||
BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir);
|
||||
int DVDOpenDir(const char* dirName, DVDDir* dir);
|
||||
int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent);
|
||||
int DVDCloseDir(DVDDir* dir);
|
||||
void DVDRewindDir(DVDDir* dir);
|
||||
void* DVDGetFSTLocation(void);
|
||||
const u8* DVDGetDOLLocation(s32* out_size);
|
||||
BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback);
|
||||
s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset);
|
||||
s32 DVDGetTransferredSize(DVDFileInfo* fileinfo);
|
||||
|
||||
#define DVDReadAsync(fileInfo, addr, length, offset, callback) \
|
||||
DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2)
|
||||
|
||||
// DVD ID UTILS
|
||||
int DVDCompareDiskID(const DVDDiskID* id1, const DVDDiskID* id2);
|
||||
DVDDiskID* DVDGenerateDiskID(DVDDiskID* id, const char* game, const char* company, u8 diskNum, u8 version);
|
||||
|
||||
// DVD LOW
|
||||
BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback);
|
||||
BOOL DVDLowSeek(u32 offset, DVDLowCallback callback);
|
||||
BOOL DVDLowWaitCoverClose(DVDLowCallback callback);
|
||||
BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback);
|
||||
BOOL DVDLowStopMotor(DVDLowCallback callback);
|
||||
BOOL DVDLowRequestError(DVDLowCallback callback);
|
||||
BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback);
|
||||
BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback);
|
||||
BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback);
|
||||
BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback);
|
||||
void DVDLowReset(void);
|
||||
DVDLowCallback DVDLowSetResetCoverCallback(DVDLowCallback callback);
|
||||
BOOL DVDLowBreak(void);
|
||||
DVDLowCallback DVDLowClearCallback(void);
|
||||
u32 DVDLowGetCoverStatus(void);
|
||||
|
||||
// DVD QUEUE
|
||||
void DVDDumpWaitingQueue(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,103 +0,0 @@
|
||||
#ifndef _DOLPHIN_EXI_H_
|
||||
#define _DOLPHIN_EXI_H_
|
||||
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EXI_MEMORY_CARD_59 0x00000004
|
||||
#define EXI_MEMORY_CARD_123 0x00000008
|
||||
#define EXI_MEMORY_CARD_251 0x00000010
|
||||
#define EXI_MEMORY_CARD_507 0x00000020
|
||||
|
||||
#define EXI_MEMORY_CARD_1019 0x00000040
|
||||
#define EXI_MEMORY_CARD_2043 0x00000080
|
||||
|
||||
#define EXI_MEMORY_CARD_1019A 0x00000140
|
||||
#define EXI_MEMORY_CARD_1019B 0x00000240
|
||||
#define EXI_MEMORY_CARD_1019C 0x00000340
|
||||
#define EXI_MEMORY_CARD_1019D 0x00000440
|
||||
#define EXI_MEMORY_CARD_1019E 0x00000540
|
||||
#define EXI_MEMORY_CARD_1019F 0x00000640
|
||||
#define EXI_MEMORY_CARD_1019G 0x00000740
|
||||
|
||||
#define EXI_MEMORY_CARD_2043A 0x00000180
|
||||
#define EXI_MEMORY_CARD_2043B 0x00000280
|
||||
#define EXI_MEMORY_CARD_2043C 0x00000380
|
||||
#define EXI_MEMORY_CARD_2043D 0x00000480
|
||||
#define EXI_MEMORY_CARD_2043E 0x00000580
|
||||
#define EXI_MEMORY_CARD_2043F 0x00000680
|
||||
#define EXI_MEMORY_CARD_2043G 0x00000780
|
||||
|
||||
#define EXI_USB_ADAPTER 0x01010000
|
||||
#define EXI_NPDP_GDEV 0x01020000
|
||||
|
||||
#define EXI_MODEM 0x02020000
|
||||
#define EXI_ETHER 0x04020200
|
||||
#define EXI_MIC 0x04060000
|
||||
#define EXI_AD16 0x04120000
|
||||
#define EXI_RS232C 0x04040404
|
||||
#define EXI_ETHER_VIEWER 0x04220001
|
||||
#define EXI_STREAM_HANGER 0x04130000
|
||||
|
||||
#define EXI_MARLIN 0x03010000
|
||||
|
||||
#define EXI_IS_VIEWER 0x05070000
|
||||
|
||||
#define EXI_READ 0
|
||||
#define EXI_WRITE 1
|
||||
|
||||
#define EXI_FREQ_1M 0
|
||||
#define EXI_FREQ_2M 1
|
||||
#define EXI_FREQ_4M 2
|
||||
#define EXI_FREQ_8M 3
|
||||
#define EXI_FREQ_16M 4
|
||||
#define EXI_FREQ_32M 5
|
||||
|
||||
typedef void (*EXICallback)(s32 chan, OSContext* context);
|
||||
typedef struct EXIControl {
|
||||
EXICallback exiCallback;
|
||||
EXICallback tcCallback;
|
||||
EXICallback extCallback;
|
||||
volatile u32 state;
|
||||
int immLen;
|
||||
u8* immBuf;
|
||||
u32 dev;
|
||||
u32 id;
|
||||
s32 idTime;
|
||||
int items;
|
||||
struct {
|
||||
u32 dev;
|
||||
EXICallback callback;
|
||||
} queue[3];
|
||||
} EXIControl;
|
||||
|
||||
EXICallback EXISetExiCallback(s32 channel, EXICallback callback);
|
||||
|
||||
void EXIInit(void);
|
||||
BOOL EXILock(s32 channel, u32 device, EXICallback callback);
|
||||
BOOL EXIUnlock(s32 channel);
|
||||
BOOL EXISelect(s32 channel, u32 device, u32 frequency);
|
||||
BOOL EXIDeselect(s32 channel);
|
||||
BOOL EXIImm(s32 channel, void* buffer, s32 length, u32 type, EXICallback callback);
|
||||
BOOL EXIImmEx(s32 channel, void* buffer, s32 length, u32 type);
|
||||
BOOL EXIDma(s32 channel, void* buffer, s32 length, u32 type, EXICallback callback);
|
||||
BOOL EXISync(s32 channel);
|
||||
BOOL EXIProbe(s32 channel);
|
||||
s32 EXIProbeEx(s32 channel);
|
||||
BOOL EXIAttach(s32 channel, EXICallback callback);
|
||||
BOOL EXIDetach(s32 channel);
|
||||
u32 EXIGetState(s32 channel);
|
||||
s32 EXIGetID(s32 channel, u32 device, u32* id);
|
||||
void EXIProbeReset(void);
|
||||
int EXISelectSD(s32 chan, u32 dev, u32 freq);
|
||||
s32 EXIGetType(s32 chan, u32 dev, u32* type);
|
||||
char* EXIGetTypeString(u32 type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_H_
|
||||
#define _DOLPHIN_GD_H_
|
||||
|
||||
#include <dolphin/gd/GDAurora.h>
|
||||
#include <dolphin/gd/GDBase.h>
|
||||
#include <dolphin/gd/GDFile.h>
|
||||
#include <dolphin/gd/GDGeometry.h>
|
||||
#include <dolphin/gd/GDIndirect.h>
|
||||
#include <dolphin/gd/GDLight.h>
|
||||
#include <dolphin/gd/GDPixel.h>
|
||||
#include <dolphin/gd/GDTev.h>
|
||||
#include <dolphin/gd/GDTexture.h>
|
||||
#include <dolphin/gd/GDTransform.h>
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef DOLPHIN_GDAURORA_H
|
||||
#define DOLPHIN_GDAURORA_H
|
||||
|
||||
/**
|
||||
* Pushes a debug group to the backend graphics API. These may show in debugging tools such as RenderDoc.
|
||||
*
|
||||
* It is considered an error to have unpopped debug groups at the end of the frame. They will be automatically cleared.
|
||||
* Debug groups are *not* automatically scoped to a display list.
|
||||
*/
|
||||
void GDPushDebugGroup(const char* label);
|
||||
|
||||
/**
|
||||
* Pop a debug group previously pushed via GXPushDebugGroup().
|
||||
*/
|
||||
void GDPopDebugGroup();
|
||||
|
||||
/**
|
||||
* Sends a debug marker to the backend graphics API. These may show in debugging tools such as RenderDoc.
|
||||
*/
|
||||
void GDInsertDebugMarker(const char* label);
|
||||
|
||||
#endif // DOLPHIN_GDAURORA_H
|
||||
@@ -1,177 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_BASE_H
|
||||
#define _DOLPHIN_GD_BASE_H
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/gx/GXCommandList.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*GDOverflowCb)(void);
|
||||
|
||||
typedef struct _GDLObj {
|
||||
u8* start;
|
||||
u32 length;
|
||||
u8* ptr;
|
||||
u8* top;
|
||||
} GDLObj;
|
||||
|
||||
extern GDLObj* __GDCurrentDL;
|
||||
|
||||
void GDInitGDLObj(GDLObj* dl, void* start, u32 length);
|
||||
void GDFlushCurrToMem(void);
|
||||
void GDPadCurr32(void);
|
||||
void GDOverflowed(void);
|
||||
void GDSetOverflowCallback(GDOverflowCb callback);
|
||||
GDOverflowCb GDGetOverflowCallback(void);
|
||||
|
||||
inline static void GDOverflowCheck(u32 size) {
|
||||
if (__GDCurrentDL->ptr + size > __GDCurrentDL->top) {
|
||||
GDOverflowed();
|
||||
}
|
||||
}
|
||||
|
||||
inline static void __GDWrite(u8 data) {
|
||||
*__GDCurrentDL->ptr++ = data;
|
||||
}
|
||||
|
||||
inline static void GDWrite_data(const void* data, u32 length) {
|
||||
GDOverflowCheck(length);
|
||||
// The compiler realizes this is memcpy, trust.
|
||||
const u8* dataPtr = static_cast<const u8*>(data);
|
||||
for (u32 i = 0; i < length; i++) {
|
||||
__GDWrite(dataPtr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void GDWrite_u8(u8 data) {
|
||||
GDOverflowCheck(sizeof(u8));
|
||||
__GDWrite(data);
|
||||
}
|
||||
|
||||
inline static void GDWrite_u16(u16 data) {
|
||||
GDOverflowCheck(sizeof(u16));
|
||||
__GDWrite((u8)((data >> 8)));
|
||||
__GDWrite((u8)((data >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
inline static void GDWrite_u24(u32 data) {
|
||||
GDOverflowCheck(3);
|
||||
__GDWrite((u8)((data >> 16) & 0xFF));
|
||||
__GDWrite((u8)((data >> 8) & 0xFF));
|
||||
__GDWrite((u8)((data >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
inline static void GDWrite_u32(u32 data) {
|
||||
GDOverflowCheck(sizeof(u32));
|
||||
__GDWrite((u8)((data >> 24) & 0xFF));
|
||||
__GDWrite((u8)((data >> 16) & 0xFF));
|
||||
__GDWrite((u8)((data >> 8) & 0xFF));
|
||||
__GDWrite((u8)((data >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
inline static void GDWrite_u64(u64 data) {
|
||||
GDOverflowCheck(sizeof(u64));
|
||||
__GDWrite((u8)((data >> 56) & 0xFF));
|
||||
__GDWrite((u8)((data >> 48) & 0xFF));
|
||||
__GDWrite((u8)((data >> 40) & 0xFF));
|
||||
__GDWrite((u8)((data >> 32) & 0xFF));
|
||||
__GDWrite((u8)((data >> 24) & 0xFF));
|
||||
__GDWrite((u8)((data >> 16) & 0xFF));
|
||||
__GDWrite((u8)((data >> 8) & 0xFF));
|
||||
__GDWrite((u8)((data >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
inline static void GDWrite_f32(f32 data) {
|
||||
union {
|
||||
f32 f;
|
||||
u32 u;
|
||||
} fid;
|
||||
fid.f = data;
|
||||
GDWrite_u32(fid.u);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFCmdHdr(u16 addr, u8 len) {
|
||||
GDWrite_u8(GX_LOAD_XF_REG);
|
||||
GDWrite_u16(len - 1);
|
||||
GDWrite_u16(addr);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFCmd(u16 addr, u32 val) {
|
||||
GDWrite_u8(GX_LOAD_XF_REG);
|
||||
GDWrite_u16(0);
|
||||
GDWrite_u16(addr);
|
||||
GDWrite_u32(val);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFIndxDCmd(u16 addr, u8 len, u16 index) {
|
||||
GDWrite_u8(GX_LOAD_INDX_D);
|
||||
GDWrite_u16(index);
|
||||
GDWrite_u16((len - 1) << 12 | addr);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFIndxACmd(u16 addr, u8 len, u16 index) {
|
||||
GDWrite_u8(GX_LOAD_INDX_A);
|
||||
GDWrite_u16(index);
|
||||
GDWrite_u16(((len - 1) << 12) | addr);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFIndxBCmd(u16 addr, u8 len, u16 index) {
|
||||
GDWrite_u8(GX_LOAD_INDX_B);
|
||||
GDWrite_u16(index);
|
||||
GDWrite_u16(((len - 1) << 12) | addr);
|
||||
}
|
||||
|
||||
inline static void GDWriteXFIndxCCmd(u16 addr, u8 len, u16 index) {
|
||||
GDWrite_u8(GX_LOAD_INDX_C);
|
||||
GDWrite_u16(index);
|
||||
GDWrite_u16(((len - 1) << 12) | addr);
|
||||
}
|
||||
|
||||
inline static void GDWriteCPCmd(u8 addr, u32 val) {
|
||||
GDWrite_u8(GX_LOAD_CP_REG);
|
||||
GDWrite_u8(addr);
|
||||
GDWrite_u32(val);
|
||||
}
|
||||
|
||||
inline static void GDWriteBPCmd(u32 regval) {
|
||||
GDWrite_u8(GX_LOAD_BP_REG);
|
||||
GDWrite_u32(regval);
|
||||
}
|
||||
|
||||
inline static void GDWriteAuroraCmd(u16 subCommand) {
|
||||
GDWrite_u8(GX_LOAD_AURORA);
|
||||
GDWrite_u16(subCommand);
|
||||
}
|
||||
|
||||
inline static void GDSetCurrent(GDLObj* dl) {
|
||||
__GDCurrentDL = dl;
|
||||
}
|
||||
|
||||
static inline u32 GDGetCurrOffset(void) {
|
||||
return (u32)(__GDCurrentDL->ptr - __GDCurrentDL->start);
|
||||
}
|
||||
|
||||
static inline void GDSetCurrOffset(u32 offset) {
|
||||
__GDCurrentDL->ptr = __GDCurrentDL->start + offset;
|
||||
}
|
||||
|
||||
static inline void* GDGetCurrPointer(void) {
|
||||
return (void*)__GDCurrentDL->ptr;
|
||||
}
|
||||
|
||||
static inline u8* GDGetCurrPointer2(void) {
|
||||
return __GDCurrentDL->ptr;
|
||||
}
|
||||
|
||||
static inline u32 GDGetGDLObjOffset(const GDLObj* dl) {
|
||||
return (u32)(dl->ptr - dl->start);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_FILE_H
|
||||
#define _DOLPHIN_GD_FILE_H
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GD_FILE_VERSION_NUMBER 0x11223344
|
||||
|
||||
typedef struct _GDGList {
|
||||
void* ptr;
|
||||
u32 byteLength;
|
||||
} GDGList;
|
||||
|
||||
typedef struct _GDFileHeader {
|
||||
u32 versionNumber;
|
||||
u32 numDLs;
|
||||
u32 numPLs;
|
||||
GDGList* DLDescArray;
|
||||
GDGList* PLDescArray;
|
||||
} GDFileHeader;
|
||||
|
||||
s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,525 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_GEOMETRY_H_
|
||||
#define _DOLPHIN_GD_GEOMETRY_H_
|
||||
|
||||
#include <dolphin/gx/GXStruct.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Command processor register IDs
|
||||
#define CP_REG_MTXIDXA_ID 0x30 // Matrix index A
|
||||
#define CP_REG_MTXIDXB_ID 0x40 // Matrix index B
|
||||
#define CP_REG_VCD_LO_ID 0x50 // Vertex descriptor (lo)
|
||||
#define CP_REG_VCD_HI_ID 0x60 // Vertex descriptor (hi)
|
||||
#define CP_REG_VAT_GRP0_ID 0x70 // Vertex attribute table (group 0)
|
||||
#define CP_REG_VAT_GRP1_ID 0x80 // Vertex attribute table (group 1)
|
||||
#define CP_REG_VAT_GRP2_ID 0x90 // Vertex attribute table (group 2)
|
||||
#define CP_REG_ARRAYBASE_ID 0xA0 // Vertex array start/base
|
||||
#define CP_REG_ARRAYSTRIDE_ID 0xB0 // Vertex array stride
|
||||
|
||||
// XF locators for textures
|
||||
// Projection type [30-30]
|
||||
#define GX_XF_TEX_PROJTYPE_ST 30
|
||||
#define GX_XF_TEX_PROJTYPE_END 30
|
||||
|
||||
// Input format [29-29]
|
||||
#define GX_XF_TEX_INPUTFORM_ST 29
|
||||
#define GX_XF_TEX_INPUTFORM_END 29
|
||||
|
||||
// Texture gen type [25-27]
|
||||
#define GX_XF_TEX_TEXGENTYPE_ST 25
|
||||
#define GX_XF_TEX_TEXGENTYPE_END 27
|
||||
|
||||
// Source row [20-24]
|
||||
#define GX_XF_TEX_SRCROW_ST 20
|
||||
#define GX_XF_TEX_SRCROW_END 24
|
||||
|
||||
// Bump source texture [17-19]
|
||||
#define GX_XF_TEX_BUMPSRCTEX_ST 17
|
||||
#define GX_XF_TEX_BUMPSRCTEX_END 19
|
||||
|
||||
// Bump source light [14-16]
|
||||
#define GX_XF_TEX_BUMPSRCLIGHT_ST 14
|
||||
#define GX_XF_TEX_BUMPSRCLIGHT_END 16
|
||||
|
||||
// Blitting processor registers.
|
||||
#define GX_BP_REG_GENMODE 0x0 // gen mode
|
||||
|
||||
// display copy filters
|
||||
#define GX_BP_REG_DISPCOPYFILTER0 0x1 // display copy filter 0
|
||||
#define GX_BP_REG_DISPCOPYFILTER1 0x2 // display copy filter 1
|
||||
#define GX_BP_REG_DISPCOPYFILTER2 0x3 // display copy filter 2
|
||||
#define GX_BP_REG_DISPCOPYFILTER3 0x4 // display copy filter 3
|
||||
|
||||
// indirect matrices
|
||||
#define GX_BP_REG_INDMTX0A 0x6 // indirect matrix 0A
|
||||
#define GX_BP_REG_INDMTX0B 0x7 // indirect matrix 0B
|
||||
#define GX_BP_REG_INDMTX0C 0x8 // indirect matrix 0C
|
||||
#define GX_BP_REG_INDMTX1A 0x9 // indirect matrix 1A
|
||||
#define GX_BP_REG_INDMTX1B 0xA // indirect matrix 1B
|
||||
#define GX_BP_REG_INDMTX1C 0xB // indirect matrix 1C
|
||||
#define GX_BP_REG_INDMTX2A 0xC // indirect matrix 2A
|
||||
#define GX_BP_REG_INDMTX2B 0xD // indirect matrix 2B
|
||||
#define GX_BP_REG_INDMTX2C 0xE // indirect matrix 2C
|
||||
#define GX_BP_REG_INDIMASK 0xF // indirect mask
|
||||
|
||||
// indirect TEV stages
|
||||
#define GX_BP_REG_INDTEVSTAGE0 0x10 // indirect TEV stage 0
|
||||
#define GX_BP_REG_INDTEVSTAGE1 0x11 // indirect TEV stage 1
|
||||
#define GX_BP_REG_INDTEVSTAGE2 0x12 // indirect TEV stage 2
|
||||
#define GX_BP_REG_INDTEVSTAGE3 0x13 // indirect TEV stage 3
|
||||
#define GX_BP_REG_INDTEVSTAGE4 0x14 // indirect TEV stage 4
|
||||
#define GX_BP_REG_INDTEVSTAGE5 0x15 // indirect TEV stage 5
|
||||
#define GX_BP_REG_INDTEVSTAGE6 0x16 // indirect TEV stage 6
|
||||
#define GX_BP_REG_INDTEVSTAGE7 0x17 // indirect TEV stage 7
|
||||
#define GX_BP_REG_INDTEVSTAGE8 0x18 // indirect TEV stage 8
|
||||
#define GX_BP_REG_INDTEVSTAGE9 0x19 // indirect TEV stage 9
|
||||
#define GX_BP_REG_INDTEVSTAGE10 0x1A // indirect TEV stage 10
|
||||
#define GX_BP_REG_INDTEVSTAGE11 0x1B // indirect TEV stage 11
|
||||
#define GX_BP_REG_INDTEVSTAGE12 0x1C // indirect TEV stage 12
|
||||
#define GX_BP_REG_INDTEVSTAGE13 0x1D // indirect TEV stage 13
|
||||
#define GX_BP_REG_INDTEVSTAGE14 0x1E // indirect TEV stage 14
|
||||
#define GX_BP_REG_INDTEVSTAGE15 0x1F // indirect TEV stage 15
|
||||
|
||||
// performance manips
|
||||
#define GX_BP_REG_SCISSORTL 0x20 // scissor top left
|
||||
#define GX_BP_REG_SCISSORBR 0x21 // scissor bottom right
|
||||
#define GX_BP_REG_LINEPTWIDTH 0x22 // line point width
|
||||
#define GX_BP_REG_PERF0TRI 0x23 // performance 0 (triangle)
|
||||
#define GX_BP_REG_PERF0QUAD 0x24 // performance 0 (quad)
|
||||
|
||||
// rasters
|
||||
#define GX_BP_REG_RAS1_SS0 0x25
|
||||
#define GX_BP_REG_RAS1_SS1 0x26
|
||||
#define GX_BP_REG_RAS1_IREF 0x27
|
||||
#define GX_BP_REG_RAS1_TREF0 0x28
|
||||
#define GX_BP_REG_RAS1_TREF1 0x29
|
||||
#define GX_BP_REG_RAS1_TREF2 0x2A
|
||||
#define GX_BP_REG_RAS1_TREF3 0x2B
|
||||
#define GX_BP_REG_RAS1_TREF4 0x2C
|
||||
#define GX_BP_REG_RAS1_TREF5 0x2D
|
||||
#define GX_BP_REG_RAS1_TREF6 0x2E
|
||||
#define GX_BP_REG_RAS1_TREF7 0x2F
|
||||
|
||||
// setup sizes
|
||||
#define GX_BP_REG_SU_SSIZE0 0x30
|
||||
#define GX_BP_REG_SU_TSIZE0 0x31
|
||||
#define GX_BP_REG_SU_SSIZE1 0x32
|
||||
#define GX_BP_REG_SU_TSIZE1 0x33
|
||||
#define GX_BP_REG_SU_SSIZE2 0x34
|
||||
#define GX_BP_REG_SU_TSIZE2 0x35
|
||||
#define GX_BP_REG_SU_SSIZE3 0x36
|
||||
#define GX_BP_REG_SU_TSIZE3 0x37
|
||||
#define GX_BP_REG_SU_SSIZE4 0x38
|
||||
#define GX_BP_REG_SU_TSIZE4 0x39
|
||||
#define GX_BP_REG_SU_SSIZE5 0x3A
|
||||
#define GX_BP_REG_SU_TSIZE5 0x3B
|
||||
#define GX_BP_REG_SU_SSIZE6 0x3C
|
||||
#define GX_BP_REG_SU_TSIZE6 0x3D
|
||||
#define GX_BP_REG_SU_SSIZE7 0x3E
|
||||
#define GX_BP_REG_SU_TSIZE7 0x3F
|
||||
|
||||
// Z and blend controls
|
||||
#define GX_BP_REG_ZMODE 0x40
|
||||
#define GX_BP_REG_BLENDMODE 0x41
|
||||
#define GX_BP_REG_DSTALPHA 0x42
|
||||
#define GX_BP_REG_ZCONTROL 0x43
|
||||
#define GX_BP_REG_FIELDMASK 0x44
|
||||
#define GX_BP_REG_DRAWDONE 0x45
|
||||
#define GX_BP_REG_PETOKEN 0x47
|
||||
#define GX_BP_REG_PETOKENINT 0x48
|
||||
|
||||
// copying
|
||||
#define GX_BP_REG_TEXCOPYSRCXY 0x49
|
||||
#define GX_BP_REG_TEXCOPYSRCWH 0x4A
|
||||
#define GX_BP_REG_TEXCOPYDST 0x4B
|
||||
#define GX_BP_REG_DISPCOPYSTRIDE 0x4D
|
||||
#define GX_BP_REG_DISPCOPYSCALEY 0x4E
|
||||
#define GX_BP_REG_COPYCLEARAR 0x4F
|
||||
#define GX_BP_REG_COPYCLEARGB 0x50
|
||||
#define GX_BP_REG_COPYCLEARZ 0x51
|
||||
#define GX_BP_REG_COPYFILTER0 0x53
|
||||
#define GX_BP_REG_COPYFILTER1 0x54
|
||||
|
||||
//
|
||||
#define GX_BP_REG_BOUNDINGBOX0 0x55
|
||||
#define GX_BP_REG_BOUNDINGBOX1 0x56
|
||||
|
||||
#define GX_BP_REG_SCISSOROFFSET 0x59
|
||||
|
||||
// texture memory
|
||||
#define GX_BP_REG_TMEMPRELOADADDR 0x60
|
||||
#define GX_BP_REG_TMEMPRELOADEVEN 0x61
|
||||
#define GX_BP_REG_TMEMPRELOADODD 0x62
|
||||
#define GX_BP_REG_TMEMPRELOADMODE 0x63
|
||||
#define GX_BP_REG_TMEMTLUTSRC 0x64
|
||||
#define GX_BP_REG_TMEMTLUTDST 0x65
|
||||
#define GX_BP_REG_TMEMTEXINVALIDATE 0x66
|
||||
|
||||
// performance 1
|
||||
#define GX_BP_REG_PERF1 0x67
|
||||
#define GX_BP_REG_FIELDMODE 0x68
|
||||
|
||||
// set modes
|
||||
#define GX_BP_REG_SETMODE0_TEX0 0x80
|
||||
#define GX_BP_REG_SETMODE0_TEX1 0x81
|
||||
#define GX_BP_REG_SETMODE0_TEX2 0x82
|
||||
#define GX_BP_REG_SETMODE0_TEX3 0x83
|
||||
#define GX_BP_REG_SETMODE1_TEX0 0x84
|
||||
#define GX_BP_REG_SETMODE1_TEX1 0x85
|
||||
#define GX_BP_REG_SETMODE1_TEX2 0x86
|
||||
#define GX_BP_REG_SETMODE1_TEX3 0x87
|
||||
|
||||
// set images
|
||||
#define GX_BP_REG_SETIMAGE0_TEX0 0x88
|
||||
#define GX_BP_REG_SETIMAGE0_TEX1 0x89
|
||||
#define GX_BP_REG_SETIMAGE0_TEX2 0x8A
|
||||
#define GX_BP_REG_SETIMAGE0_TEX3 0x8B
|
||||
#define GX_BP_REG_SETIMAGE1_TEX0 0x8C
|
||||
#define GX_BP_REG_SETIMAGE1_TEX1 0x8D
|
||||
#define GX_BP_REG_SETIMAGE1_TEX2 0x8E
|
||||
#define GX_BP_REG_SETIMAGE1_TEX3 0x8F
|
||||
#define GX_BP_REG_SETIMAGE2_TEX0 0x90
|
||||
#define GX_BP_REG_SETIMAGE2_TEX1 0x91
|
||||
#define GX_BP_REG_SETIMAGE2_TEX2 0x92
|
||||
#define GX_BP_REG_SETIMAGE2_TEX3 0x93
|
||||
#define GX_BP_REG_SETIMAGE3_TEX0 0x94
|
||||
#define GX_BP_REG_SETIMAGE3_TEX1 0x95
|
||||
#define GX_BP_REG_SETIMAGE3_TEX2 0x96
|
||||
#define GX_BP_REG_SETIMAGE3_TEX3 0x97
|
||||
|
||||
// set texture lookups
|
||||
#define GX_BP_REG_SETTLUT_TEX0 0x98
|
||||
#define GX_BP_REG_SETTLUT_TEX1 0x99
|
||||
#define GX_BP_REG_SETTLUT_TEX2 0x9A
|
||||
#define GX_BP_REG_SETTLUT_TEX3 0x9B
|
||||
|
||||
// set modes continued
|
||||
#define GX_BP_REG_SETMODE0_TEX4 0xA0
|
||||
#define GX_BP_REG_SETMODE0_TEX5 0xA1
|
||||
#define GX_BP_REG_SETMODE0_TEX6 0xA2
|
||||
#define GX_BP_REG_SETMODE0_TEX7 0xA3
|
||||
#define GX_BP_REG_SETMODE1_TEX4 0xA4
|
||||
#define GX_BP_REG_SETMODE1_TEX5 0xA5
|
||||
#define GX_BP_REG_SETMODE1_TEX6 0xA6
|
||||
#define GX_BP_REG_SETMODE1_TEX7 0xA7
|
||||
|
||||
// set images continued
|
||||
#define GX_BP_REG_SETIMAGE0_TEX4 0xA8
|
||||
#define GX_BP_REG_SETIMAGE0_TEX5 0xA9
|
||||
#define GX_BP_REG_SETIMAGE0_TEX6 0xAA
|
||||
#define GX_BP_REG_SETIMAGE0_TEX7 0xAB
|
||||
#define GX_BP_REG_SETIMAGE1_TEX4 0xAC
|
||||
#define GX_BP_REG_SETIMAGE1_TEX5 0xAD
|
||||
#define GX_BP_REG_SETIMAGE1_TEX6 0xAE
|
||||
#define GX_BP_REG_SETIMAGE1_TEX7 0xAF
|
||||
#define GX_BP_REG_SETIMAGE2_TEX4 0xB0
|
||||
#define GX_BP_REG_SETIMAGE2_TEX5 0xB1
|
||||
#define GX_BP_REG_SETIMAGE2_TEX6 0xB2
|
||||
#define GX_BP_REG_SETIMAGE2_TEX7 0xB3
|
||||
#define GX_BP_REG_SETIMAGE3_TEX4 0xB4
|
||||
#define GX_BP_REG_SETIMAGE3_TEX5 0xB5
|
||||
#define GX_BP_REG_SETIMAGE3_TEX6 0xB6
|
||||
#define GX_BP_REG_SETIMAGE3_TEX7 0xB7
|
||||
|
||||
// set texture lookups continued
|
||||
#define GX_BP_REG_SETTLUT_TEX4 0xB8
|
||||
#define GX_BP_REG_SETTLUT_TEX5 0xB9
|
||||
#define GX_BP_REG_SETTLUT_TEX6 0xBA
|
||||
#define GX_BP_REG_SETTLUT_TEX7 0xBB
|
||||
|
||||
// TEV color manips
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER0 0xC0
|
||||
#define GX_BP_REG_TEVALPHACOMBINER0 0xC1
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER1 0xC2
|
||||
#define GX_BP_REG_TEVALPHACOMBINER1 0xC3
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER2 0xC4
|
||||
#define GX_BP_REG_TEVALPHACOMBINER2 0xC5
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER3 0xC6
|
||||
#define GX_BP_REG_TEVALPHACOMBINER3 0xC7
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER4 0xC8
|
||||
#define GX_BP_REG_TEVALPHACOMBINER4 0xC9
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER5 0xCA
|
||||
#define GX_BP_REG_TEVALPHACOMBINER5 0xCB
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER6 0xCC
|
||||
#define GX_BP_REG_TEVALPHACOMBINER6 0xCD
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER7 0xCE
|
||||
#define GX_BP_REG_TEVALPHACOMBINER7 0xCF
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER8 0xD0
|
||||
#define GX_BP_REG_TEVALPHACOMBINER8 0xD1
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER9 0xD2
|
||||
#define GX_BP_REG_TEVALPHACOMBINER9 0xD3
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER10 0xD4
|
||||
#define GX_BP_REG_TEVALPHACOMBINER10 0xD5
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER11 0xD6
|
||||
#define GX_BP_REG_TEVALPHACOMBINER11 0xD7
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER12 0xD8
|
||||
#define GX_BP_REG_TEVALPHACOMBINER12 0xD9
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER13 0xDA
|
||||
#define GX_BP_REG_TEVALPHACOMBINER13 0xDB
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER14 0xDC
|
||||
#define GX_BP_REG_TEVALPHACOMBINER14 0xDD
|
||||
#define GX_BP_REG_TEVCOLORCOMBINER15 0xDE
|
||||
#define GX_BP_REG_TEVALPHACOMBINER15 0xDF
|
||||
|
||||
// TEV registers
|
||||
#define GX_BP_REG_TEVREG0LO 0xE0
|
||||
#define GX_BP_REG_TEVREG0HI 0xE1
|
||||
#define GX_BP_REG_TEVREG1LO 0xE2
|
||||
#define GX_BP_REG_TEVREG1HI 0xE3
|
||||
#define GX_BP_REG_TEVREG2LO 0xE4
|
||||
#define GX_BP_REG_TEVREG2HI 0xE5
|
||||
#define GX_BP_REG_TEVREG3LO 0xE6
|
||||
#define GX_BP_REG_TEVREG3HI 0xE7
|
||||
|
||||
// fog registers
|
||||
#define GX_BP_REG_FOGRANGE 0xE8
|
||||
#define GX_BP_REG_FOGRANGEK0 0xE9
|
||||
#define GX_BP_REG_FOGRANGEK1 0xEA
|
||||
#define GX_BP_REG_FOGRANGEK2 0xEB
|
||||
#define GX_BP_REG_FOGRANGEK3 0xEC
|
||||
#define GX_BP_REG_FOGRANGEK4 0xED
|
||||
#define GX_BP_REG_FOGPARAM0 0xEE
|
||||
#define GX_BP_REG_FOGPARAM1 0xEF
|
||||
#define GX_BP_REG_FOGPARAM2 0xF0
|
||||
#define GX_BP_REG_FOGPARAM3 0xF1
|
||||
#define GX_BP_REG_FOGCOLOR 0xF2
|
||||
|
||||
// performance manip registers
|
||||
#define GX_BP_REG_ALPHACOMPARE 0xF3
|
||||
#define GX_BP_REG_ZTEXTURE0 0xF4
|
||||
#define GX_BP_REG_ZTEXTURE1 0xF5
|
||||
|
||||
// TEV K selectors
|
||||
#define GX_BP_REG_TEVKSEL0 0xF6
|
||||
#define GX_BP_REG_TEVKSEL1 0xF7
|
||||
#define GX_BP_REG_TEVKSEL2 0xF8
|
||||
#define GX_BP_REG_TEVKSEL3 0xF9
|
||||
#define GX_BP_REG_TEVKSEL4 0xFA
|
||||
#define GX_BP_REG_TEVKSEL5 0xFB
|
||||
#define GX_BP_REG_TEVKSEL6 0xFC
|
||||
#define GX_BP_REG_TEVKSEL7 0xFD
|
||||
|
||||
// SS mask
|
||||
#define GX_BP_REG_SSMASK 0xFE
|
||||
|
||||
// Transform Unit Registers
|
||||
#define GX_XF_REG_ERROR 0x1000
|
||||
#define GX_XF_REG_DIAGNOSTICS 0x1001
|
||||
#define GX_XF_REG_STATE0 0x1002
|
||||
#define GX_XF_REG_STATE1 0x1003
|
||||
#define GX_XF_REG_CLOCK 0x1004
|
||||
#define GX_XF_REG_CLIPDISABLE 0x1005
|
||||
#define GX_XF_REG_PERF0 0x1006
|
||||
#define GX_XF_REG_PERF1 0x1007
|
||||
#define GX_XF_REG_INVERTEXSPEC 0x1008
|
||||
#define GX_XF_REG_NUMCOLORS 0x1009
|
||||
#define GX_XF_REG_AMBIENT0 0x100A
|
||||
#define GX_XF_REG_AMBIENT1 0x100B
|
||||
#define GX_XF_REG_MATERIAL0 0x100C
|
||||
#define GX_XF_REG_MATERIAL1 0x100D
|
||||
#define GX_XF_REG_COLOR0CNTRL 0x100E
|
||||
#define GX_XF_REG_COLOR1CNTRL 0x100F
|
||||
#define GX_XF_REG_ALPHA0CNTRL 0x1010
|
||||
#define GX_XF_REG_ALPHA1CNTRL 0x1011
|
||||
#define GX_XF_REG_DUALTEXTRAN 0x1012
|
||||
#define GX_XF_REG_MATRIXINDEX0 0x1018
|
||||
#define GX_XF_REG_MATRIXINDEX1 0x1019
|
||||
#define GX_XF_REG_SCALEX 0x101A
|
||||
#define GX_XF_REG_SCALEY 0x101B
|
||||
#define GX_XF_REG_SCALEZ 0x101C
|
||||
#define GX_XF_REG_OFFSETX 0x101D
|
||||
#define GX_XF_REG_OFFSETY 0x101E
|
||||
#define GX_XF_REG_OFFSETZ 0x101F
|
||||
#define GX_XF_REG_PROJECTIONA 0x1020
|
||||
#define GX_XF_REG_PROJECTIONB 0x1021
|
||||
#define GX_XF_REG_PROJECTIONC 0x1022
|
||||
#define GX_XF_REG_PROJECTIOND 0x1023
|
||||
#define GX_XF_REG_PROJECTIONE 0x1024
|
||||
#define GX_XF_REG_PROJECTIONF 0x1025
|
||||
#define GX_XF_REG_PROJECTORTHO 0x1026
|
||||
#define GX_XF_REG_NUMTEX 0x103F
|
||||
#define GX_XF_REG_TEX0 0x1040
|
||||
#define GX_XF_REG_TEX1 0x1041
|
||||
#define GX_XF_REG_TEX2 0x1042
|
||||
#define GX_XF_REG_TEX3 0x1043
|
||||
#define GX_XF_REG_TEX4 0x1044
|
||||
#define GX_XF_REG_TEX5 0x1045
|
||||
#define GX_XF_REG_TEX6 0x1046
|
||||
#define GX_XF_REG_TEX7 0x1047
|
||||
#define GX_XF_REG_DUALTEX0 0x1050
|
||||
#define GX_XF_REG_DUALTEX1 0x1051
|
||||
#define GX_XF_REG_DUALTEX2 0x1052
|
||||
#define GX_XF_REG_DUALTEX3 0x1053
|
||||
#define GX_XF_REG_DUALTEX4 0x1054
|
||||
#define GX_XF_REG_DUALTEX5 0x1055
|
||||
#define GX_XF_REG_DUALTEX6 0x1056
|
||||
#define GX_XF_REG_DUALTEX7 0x1057
|
||||
|
||||
#define CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1) \
|
||||
( \
|
||||
(pnMtxIdx) << 0 | \
|
||||
(txMtxIdxMask) << 1 | \
|
||||
(posn) << 9 | \
|
||||
(norm) << 11 | \
|
||||
(col0) << 13 | \
|
||||
(col1) << 15 \
|
||||
)
|
||||
|
||||
#define CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7) \
|
||||
( \
|
||||
(tex0) << 0 | \
|
||||
(tex1) << 2 | \
|
||||
(tex2) << 4 | \
|
||||
(tex3) << 6 | \
|
||||
(tex4) << 8 | \
|
||||
(tex5) << 10 | \
|
||||
(tex6) << 12 | \
|
||||
(tex7) << 14 \
|
||||
)
|
||||
|
||||
#define CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, p12, nrmIdx3) \
|
||||
( \
|
||||
(posCnt) << 0 | \
|
||||
(posType) << 1 | \
|
||||
(posFrac) << 4 | \
|
||||
(nrmCnt) << 9 | \
|
||||
(nrmType) << 10 | \
|
||||
(c0Cnt) << 13 | \
|
||||
(c0Type) << 14 | \
|
||||
(c1Cnt) << 17 | \
|
||||
(c1Type) << 18 | \
|
||||
(tx0Cnt) << 21 | \
|
||||
(tx0Type) << 22 | \
|
||||
(tx0Frac) << 25 | \
|
||||
(p12) << 30 | \
|
||||
(nrmIdx3) << 31 \
|
||||
)
|
||||
|
||||
#define CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, p11) \
|
||||
( \
|
||||
(tx1Cnt) << 0 | \
|
||||
(tx1Type) << 1 | \
|
||||
(tx1Frac) << 4 | \
|
||||
(tx2Cnt) << 9 | \
|
||||
(tx2Type) << 10 | \
|
||||
(tx2Frac) << 13 | \
|
||||
(tx3Cnt) << 18 | \
|
||||
(tx3Type) << 19 | \
|
||||
(tx3Frac) << 22 | \
|
||||
(tx4Cnt) << 27 | \
|
||||
(tx4Type) << 28 | \
|
||||
p11 << 31 \
|
||||
)
|
||||
|
||||
#define CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac) \
|
||||
( \
|
||||
(tx4Frac) << 0 | \
|
||||
(tx5Cnt) << 5 | \
|
||||
(tx5Type) << 6 | \
|
||||
(tx5Frac) << 9 | \
|
||||
(tx6Cnt) << 14 | \
|
||||
(tx6Type) << 15 | \
|
||||
(tx6Frac) << 18 | \
|
||||
(tx7Cnt) << 23 | \
|
||||
(tx7Type) << 24 | \
|
||||
(tx7Frac) << 27 \
|
||||
)
|
||||
|
||||
// Transform unit register IDs
|
||||
#define XF_REG_ERROR_ID 0x1000
|
||||
#define XF_REG_DIAGNOSTICS_ID 0x1001
|
||||
#define XF_REG_STATE0_ID 0x1002
|
||||
#define XF_REG_STATE1_ID 0x1003
|
||||
#define XF_REG_CLOCK_ID 0x1004
|
||||
#define XF_REG_CLIPDISABLE_ID 0x1005
|
||||
#define XF_REG_PERF0_ID 0x1006
|
||||
#define XF_REG_PERF1_ID 0x1007
|
||||
#define XF_REG_INVERTEXSPEC_ID 0x1008
|
||||
#define XF_REG_NUMCOLORS_ID 0x1009
|
||||
#define XF_REG_DUALTEXTRAN_ID 0x1012
|
||||
#define XF_REG_SCALEX_ID 0x101A
|
||||
#define XF_REG_SCALEY_ID 0x101B
|
||||
#define XF_REG_SCALEZ_ID 0x101C
|
||||
#define XF_REG_OFFSETX_ID 0x101D
|
||||
#define XF_REG_OFFSETY_ID 0x101E
|
||||
#define XF_REG_OFFSETZ_ID 0x101F
|
||||
#define XF_REG_NUMTEX_ID 0x103F
|
||||
#define XF_REG_TEX0_ID 0x1040
|
||||
#define XF_REG_TEX1_ID 0x1041
|
||||
#define XF_REG_TEX2_ID 0x1042
|
||||
#define XF_REG_TEX3_ID 0x1043
|
||||
#define XF_REG_TEX4_ID 0x1044
|
||||
#define XF_REG_TEX5_ID 0x1045
|
||||
#define XF_REG_TEX6_ID 0x1046
|
||||
#define XF_REG_TEX7_ID 0x1047
|
||||
#define XF_REG_DUALTEX0_ID 0x1050
|
||||
#define XF_REG_DUALTEX1_ID 0x1051
|
||||
#define XF_REG_DUALTEX2_ID 0x1052
|
||||
#define XF_REG_DUALTEX3_ID 0x1053
|
||||
#define XF_REG_DUALTEX4_ID 0x1054
|
||||
#define XF_REG_DUALTEX5_ID 0x1055
|
||||
#define XF_REG_DUALTEX6_ID 0x1056
|
||||
#define XF_REG_DUALTEX7_ID 0x1057
|
||||
|
||||
#define XF_REG_INVTXSPEC(ncols, nnorms, ntexs) \
|
||||
( \
|
||||
(ncols) << 0 | \
|
||||
(nnorms) << 2 | \
|
||||
(ntexs) << 4 \
|
||||
)
|
||||
|
||||
#define XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit) \
|
||||
( \
|
||||
(proj) << 1 | \
|
||||
(form) << 2 | \
|
||||
(tgType) << 4 | \
|
||||
(row) << 7 | \
|
||||
(embossRow) << 12 | \
|
||||
(embossLit) << 15 \
|
||||
)
|
||||
|
||||
#define XF_REG_DUALTEX(mtx, normalize) \
|
||||
( \
|
||||
(mtx) << 0 | \
|
||||
(normalize) << 8 \
|
||||
)
|
||||
|
||||
#define BP_GEN_MODE(nTexGens, nChans, nTevs, p4, nInds) \
|
||||
( \
|
||||
(u32)(nTexGens) << 0 | \
|
||||
(u32)(nChans) << 4 | \
|
||||
(u32)(nTevs) << 10 | \
|
||||
(u32)(p4) << 14 | \
|
||||
(u32)(nInds) << 16 \
|
||||
)
|
||||
|
||||
#define BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, p5) \
|
||||
( \
|
||||
(u32)(lineWidth) << 0 | \
|
||||
(u32)(pointSize) << 8 | \
|
||||
(u32)(lineOffset) << 16 | \
|
||||
(u32)(pointOffset) << 19 | \
|
||||
(u32)(lineHalfAspect) << 22 | \
|
||||
(u32)(p5) << 24 \
|
||||
)
|
||||
|
||||
void GDSetVtxDescv(const GXVtxDescList* attrPtr);
|
||||
void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list);
|
||||
void GDSetArraySized(GXAttr attr, void* base_ptr, u32 size, u8 stride, bool le);
|
||||
void GDSetArray(GXAttr attr, void* base_ptr, u8 stride);
|
||||
void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride);
|
||||
void GDPatchArrayPtr(void* base_ptr);
|
||||
void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx);
|
||||
void GDSetCullMode(GXCullMode mode);
|
||||
void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs);
|
||||
void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm);
|
||||
void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect);
|
||||
void GDSetCoPlanar(u8 enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_INDIRECT_H_
|
||||
#define _DOLPHIN_GD_INDIRECT_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/mtx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BP_TEV_INDIRECT(ind_stage, format, bias_sel, alpha_sel, mtx_sel, wrap_s, wrap_t, utc_lod, add_prev, id) \
|
||||
( \
|
||||
(u32)(ind_stage) << 0 | \
|
||||
(u32)(format) << 2 | \
|
||||
(u32)(bias_sel) << 4 | \
|
||||
(u32)(alpha_sel) << 7 | \
|
||||
(u32)(mtx_sel) << 9 | \
|
||||
(u32)(wrap_s) << 13 | \
|
||||
(u32)(wrap_t) << 16 | \
|
||||
(u32)(utc_lod) << 19 | \
|
||||
(u32)(add_prev) << 20 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IND_MTX(m0, m1, scale_exp, id) \
|
||||
( \
|
||||
(u32)(m0) << 0 | \
|
||||
(u32)(m1) << 11 | \
|
||||
(u32)(scale_exp) << 22 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IND_TEXCOORD_SCALE(scaleS0, scaleT0, scaleS1, scaleT1, id) \
|
||||
( \
|
||||
(u32)(scaleS0) << 0 | \
|
||||
(u32)(scaleT0) << 4 | \
|
||||
(u32)(scaleS1) << 8 | \
|
||||
(u32)(scaleT1) << 12 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IND_TEX_ORDER(map0, coord0, map1, coord1, map2, coord2, map3, coord3, id) \
|
||||
( \
|
||||
(u32)(map0) << 0 | \
|
||||
(u32)(coord0) << 3 | \
|
||||
(u32)(map1) << 6 | \
|
||||
(u32)(coord1) << 9 | \
|
||||
(u32)(map2) << 12 | \
|
||||
(u32)(coord2) << 15 | \
|
||||
(u32)(map3) << 18 | \
|
||||
(u32)(coord3) << 21 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IND_MASK(mask, id) \
|
||||
( \
|
||||
(u32)(mask) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage,
|
||||
GXIndTexFormat format, GXIndTexBiasSel bias_sel,
|
||||
GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s,
|
||||
GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod,
|
||||
GXIndTexAlphaSel alpha_sel);
|
||||
void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp);
|
||||
void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0,
|
||||
GXIndTexScale scaleT0, GXIndTexScale scaleS1,
|
||||
GXIndTexScale scaleT1);
|
||||
void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0,
|
||||
GXTexCoordID texCoord1, GXTexMapID texMap1,
|
||||
GXTexCoordID texCoord2, GXTexMapID texMap2,
|
||||
GXTexCoordID texCoord3, GXTexMapID texMap3);
|
||||
void GDSetTevDirect(GXTevStageID tev_stage);
|
||||
void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel);
|
||||
void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage,
|
||||
u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s,
|
||||
u16 tilespacing_t, GXIndTexFormat format,
|
||||
GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel,
|
||||
GXIndTexAlphaSel alpha_sel);
|
||||
void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel);
|
||||
void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel);
|
||||
void GDSetTevIndRepeat(GXTevStageID tev_stage);
|
||||
void __GDSetIndTexMask(u32 mask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_LIGHT_H_
|
||||
#define _DOLPHIN_GD_LIGHT_H_
|
||||
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/gx/GXStruct.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define XF_LIGHT_ID 0x0600
|
||||
#define XF_LIGHT_COLOR_ID 0x0603
|
||||
#define XF_LIGHT_ATTN_ID 0x0604
|
||||
#define XF_LIGHT_DISTATTN_ID 0x0607
|
||||
#define XF_LIGHT_POS_ID 0x060A
|
||||
#define XF_LIGHT_SPEC_DIR_ID 0x060A
|
||||
#define XF_LIGHT_DIR_ID 0x060D
|
||||
|
||||
#define XF_REG_AMBIENT0_ID 0x100A
|
||||
#define XF_REG_AMBIENT1_ID 0x100B
|
||||
#define XF_REG_MATERIAL0_ID 0x100C
|
||||
#define XF_REG_MATERIAL1_ID 0x100D
|
||||
#define XF_REG_COLOR0CNTRL_ID 0x100E
|
||||
#define XF_REG_COLOR1CNTRL_ID 0x100F
|
||||
#define XF_REG_ALPHA0CNTRL_ID 0x1010
|
||||
#define XF_REG_ALPHA1CNTRL_ID 0x1011
|
||||
|
||||
#define XF_REG_CHAN_CTRL(matsrc, enable, lightmask0, ambsrc, diff_fn, p5, p6, lightmask4) \
|
||||
( \
|
||||
(u32)(matsrc) << 0 | \
|
||||
(u32)(enable) << 1 | \
|
||||
(u32)(lightmask0) << 2 | \
|
||||
(u32)(ambsrc) << 6 | \
|
||||
(u32)(diff_fn) << 7 | \
|
||||
(u32)(p5) << 9 | \
|
||||
(u32)(p6) << 10 | \
|
||||
(u32)(lightmask4) << 11 \
|
||||
)
|
||||
|
||||
void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2);
|
||||
void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func);
|
||||
void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func);
|
||||
void GDSetLightColor(GXLightID light, GXColor color);
|
||||
void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z);
|
||||
void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz);
|
||||
void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz);
|
||||
void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz);
|
||||
void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light);
|
||||
void GDSetChanAmbColor(GXChannelID chan, GXColor color);
|
||||
void GDSetChanMatColor(GXChannelID chan, GXColor color);
|
||||
void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src,
|
||||
GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn,
|
||||
GXAttnFn attn_fn);
|
||||
|
||||
u16 __GDLightID2Index(GXLightID id);
|
||||
|
||||
inline static u16 __GDLightID2Offset(GXLightID id) {
|
||||
return __GDLightID2Index(id) * 16;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,95 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_PIXEL_H
|
||||
#define _DOLPHIN_GD_PIXEL_H
|
||||
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/gx/GXStruct.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BP_FOG_UNK0(a, id) \
|
||||
( \
|
||||
(u32)(a) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_FOG_UNK1(b_m, id) \
|
||||
( \
|
||||
(u32)(b_m) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_FOG_UNK2(b_expn, id) \
|
||||
( \
|
||||
(u32)(b_expn) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_FOG_UNK3(c, proj, fsel, id) \
|
||||
( \
|
||||
(u32)(c) << 0 | \
|
||||
(u32)(proj) << 20 | \
|
||||
(u32)(fsel) << 21 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_FOG_COLOR(r, g, b, id) \
|
||||
( \
|
||||
(u32)(b) << 0 | \
|
||||
(u32)(g) << 8 | \
|
||||
(u32)(r) << 16 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_BLEND_MODE(enable, enable_logic, enable_dither, enable_color_update, enable_alpha_update, dst_factor, src_factor, blend_sub, logic_op, id) \
|
||||
( \
|
||||
(u32)(enable) << 0 | \
|
||||
(u32)(enable_logic) << 1 | \
|
||||
(u32)(enable_dither) << 2 | \
|
||||
(u32)(enable_color_update) << 3 | \
|
||||
(u32)(enable_alpha_update) << 4 | \
|
||||
(u32)(dst_factor) << 5 | \
|
||||
(u32)(src_factor) << 8 | \
|
||||
(u32)(blend_sub) << 11 | \
|
||||
(u32)(logic_op) << 12 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_Z_MODE(enable_compare, compare_fn, enable_update, id) \
|
||||
( \
|
||||
(u32)(enable_compare) << 0 | \
|
||||
(u32)(compare_fn) << 1 | \
|
||||
(u32)(enable_update) << 4 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_DST_ALPHA(alpha, enable, id) \
|
||||
( \
|
||||
(u32)(alpha) << 0 | \
|
||||
(u32)(enable) << 8 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TOKEN(token, id) \
|
||||
( \
|
||||
(u32)(token) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
void GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color);
|
||||
void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op);
|
||||
void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor,
|
||||
GXBlendFactor dst_factor, GXLogicOp logic_op,
|
||||
u8 color_update_enable,
|
||||
u8 alpha_update_enable,
|
||||
u8 dither_enable);
|
||||
void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable);
|
||||
void GDSetDstAlpha(u8 enable, u8 alpha);
|
||||
void GDSetDrawSync(u16 token);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,133 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_TEV_H
|
||||
#define _DOLPHIN_GD_TEV_H
|
||||
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/gx/GXStruct.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BP_TEV_COLOR(d, c, b, a, bias, op, clamp, scale, out, id) \
|
||||
( \
|
||||
(u32)(d) << 0 | \
|
||||
(u32)(c) << 4 | \
|
||||
(u32)(b) << 8 | \
|
||||
(u32)(a) << 12 | \
|
||||
(u32)(bias) << 16 | \
|
||||
(u32)(op) << 18 | \
|
||||
(u32)(clamp) << 19 | \
|
||||
(u32)(scale) << 20 | \
|
||||
(u32)(out) << 22 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op, clamp, scale, out, id) \
|
||||
( \
|
||||
(u32)(ras_sel) << 0 | \
|
||||
(u32)(tex_sel) << 2 | \
|
||||
(u32)(d) << 4 | \
|
||||
(u32)(c) << 7 | \
|
||||
(u32)(b) << 10 | \
|
||||
(u32)(a) << 13 | \
|
||||
(u32)(bias) << 16 | \
|
||||
(u32)(op) << 18 | \
|
||||
(u32)(clamp) << 19 | \
|
||||
(u32)(scale) << 20 | \
|
||||
(u32)(out) << 22 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEV_COLOR_REG_RA(r, a, reg, id) \
|
||||
( \
|
||||
(u32)(r) << 0 | \
|
||||
(u32)(a) << 12 | \
|
||||
(u32)(reg) << 23 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEV_COLOR_REG_BG(b, g, reg, id) \
|
||||
( \
|
||||
(u32)(b) << 0 | \
|
||||
(u32)(g) << 12 | \
|
||||
(u32)(reg) << 23 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEV_KSEL(rb, ga, kcsel0, kasel0, kcsel1, kasel1, id) \
|
||||
( \
|
||||
(u32)(rb) << 0 | \
|
||||
(u32)(ga) << 2 | \
|
||||
(u32)(kcsel0) << 4 | \
|
||||
(u32)(kasel0) << 9 | \
|
||||
(u32)(kcsel1) << 14 | \
|
||||
(u32)(kasel1) << 19 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, id) \
|
||||
( \
|
||||
(u32)(ref0) << 0 | \
|
||||
(u32)(ref1) << 8 | \
|
||||
(u32)(comp0) << 16 | \
|
||||
(u32)(comp1) << 19 | \
|
||||
(u32)(op) << 22 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_ZTEX_PARAMS_0(bias, id) \
|
||||
( \
|
||||
(u32)(bias) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_ZTEX_PARAMS_1(zfmt, op, id) \
|
||||
( \
|
||||
(u32)(zfmt) << 0 | \
|
||||
(u32)(op) << 2 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEV_ORDER(map0, coord0, enable0, color0, map1, coord1, enable1, color1, id) \
|
||||
( \
|
||||
(u32)(map0) << 0 | \
|
||||
(u32)(coord0) << 3 | \
|
||||
(u32)(enable0) << 6 | \
|
||||
(u32)(color0) << 7 | \
|
||||
(u32)(map1) << 12 | \
|
||||
(u32)(coord1) << 15 | \
|
||||
(u32)(enable1) << 18 | \
|
||||
(u32)(color1) << 19 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
void GDSetTevOp(GXTevStageID stage, GXTevMode mode);
|
||||
void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b,
|
||||
GXTevColorArg c, GXTevColorArg d, GXTevOp op,
|
||||
GXTevBias bias, GXTevScale scale, u8 clamp,
|
||||
GXTevRegID out_reg);
|
||||
void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a,
|
||||
GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d,
|
||||
GXTevOp op, GXTevBias bias, GXTevScale scale,
|
||||
u8 clamp, GXTevRegID out_reg,
|
||||
GXTevSwapSel ras_sel, GXTevSwapSel tex_sel);
|
||||
void GDSetTevColor(GXTevRegID reg, GXColor color);
|
||||
void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color);
|
||||
void GDSetTevKColor(GXTevKColorID reg, GXColor color);
|
||||
void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0,
|
||||
GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1,
|
||||
GXTevKAlphaSel kasel1);
|
||||
void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red,
|
||||
GXTevColorChan green, GXTevColorChan blue,
|
||||
GXTevColorChan alpha);
|
||||
void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1);
|
||||
void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias);
|
||||
void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0,
|
||||
GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1,
|
||||
GXChannelID color1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,127 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_TEXTURE_H
|
||||
#define _DOLPHIN_GD_TEXTURE_H
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BP_TEX_MODE0(wrap_s, wrap_t, mag_filt, min_filt, edge_lod, lod_bias, max_aniso, bias_clamp, id) \
|
||||
( \
|
||||
(u32)(wrap_s) << 0 | \
|
||||
(u32)(wrap_t) << 2 | \
|
||||
(u32)(mag_filt) << 4 | \
|
||||
(u32)(min_filt) << 5 | \
|
||||
(u32)(edge_lod) << 8 | \
|
||||
(u32)(lod_bias) << 9 | \
|
||||
(u32)(max_aniso) << 19 | \
|
||||
(u32)(bias_clamp) << 21 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEX_MODE1(min_lod, max_lod, id) \
|
||||
( \
|
||||
(u32)(min_lod) << 0 | \
|
||||
(u32)(max_lod) << 8 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IMAGE_ATTR(width, height, format, id) \
|
||||
( \
|
||||
(u32)(width) << 0 | \
|
||||
(u32)(height) << 10 | \
|
||||
(u32)(format) << 20 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_IMAGE_PTR(ptr, id) \
|
||||
( \
|
||||
(u32)(ptr) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEX_CACHE_EVEN(tmem, size0, size1, type, id) \
|
||||
( \
|
||||
(u32)(tmem) << 0 | \
|
||||
(u32)(size0) << 15 | \
|
||||
(u32)(size1) << 18 | \
|
||||
(u32)(type) << 21 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEX_CACHE_ODD(tmem, size0, size1, id) \
|
||||
( \
|
||||
(u32)(tmem) << 0 | \
|
||||
(u32)(size0) << 15 | \
|
||||
(u32)(size1) << 18 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEX_TLUT(tmem, format, id) \
|
||||
( \
|
||||
(u32)(tmem) << 0 | \
|
||||
(u32)(format) << 10 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEXCOORD_S_SCALE(s_scale, s_bias, s_wrap, line_offset, point_offset, id) \
|
||||
( \
|
||||
(u32)(s_scale) << 0 | \
|
||||
(u32)(s_bias) << 16 | \
|
||||
(u32)(s_wrap) << 17 | \
|
||||
(u32)(line_offset) << 18 | \
|
||||
(u32)(point_offset) << 19 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_TEXCOORD_T_SCALE(t_scale, t_bias, t_wrap, id) \
|
||||
( \
|
||||
(u32)(t_scale) << 0 | \
|
||||
(u32)(t_bias) << 16 | \
|
||||
(u32)(t_wrap) << 17 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_LOAD_TLUT0(ptr, id) \
|
||||
( \
|
||||
(u32)(ptr) << 0 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
#define BP_LOAD_TLUT1(ptr, size, id) \
|
||||
( \
|
||||
(u32)(ptr) << 0 | \
|
||||
(u32)(size) << 10 | \
|
||||
(u32)(id) << 24 \
|
||||
)
|
||||
|
||||
void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s,
|
||||
GXTexWrapMode wrap_t, GXTexFilter min_filt,
|
||||
GXTexFilter mag_filt, f32 min_lod, f32 max_lod,
|
||||
f32 lod_bias, u8 bias_clamp, u8 do_edge_lod,
|
||||
GXAnisotropy max_aniso);
|
||||
|
||||
void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format);
|
||||
void GDSetTexImgPtr(GXTexMapID id, void* image_ptr);
|
||||
void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw);
|
||||
void GDPatchTexImgPtr(void* image_ptr);
|
||||
void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even,
|
||||
u32 tmem_odd, GXTexCacheSize size_odd);
|
||||
void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd);
|
||||
void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format);
|
||||
void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale);
|
||||
void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias,
|
||||
u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap);
|
||||
void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias,
|
||||
u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap,
|
||||
u8 line_offset, u8 point_offset);
|
||||
void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size);
|
||||
void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef _DOLPHIN_GD_TRANSFORM_H_
|
||||
#define _DOLPHIN_GD_TRANSFORM_H_
|
||||
|
||||
#include <dolphin/types.h>
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
#include <dolphin/mtx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CP_MTX_REG_A_ID 0x30
|
||||
#define CP_MTX_REG_B_ID 0x40
|
||||
|
||||
#define XF_REG_MATRIXINDEX0_ID 0x1018
|
||||
#define XF_REG_MATRIXINDEX1_ID 0x1019
|
||||
#define XF_REG_PROJECTIONA_ID 0x1020
|
||||
#define XF_REG_PROJECTIONB_ID 0x1021
|
||||
#define XF_REG_PROJECTIONC_ID 0x1022
|
||||
#define XF_REG_PROJECTIOND_ID 0x1023
|
||||
#define XF_REG_PROJECTIONE_ID 0x1024
|
||||
#define XF_REG_PROJECTIONF_ID 0x1025
|
||||
#define XF_REG_PROJECTORTHO_ID 0x1026
|
||||
|
||||
#define CP_MTX_REG_A(pn, t0, t1, t2, t3) \
|
||||
( \
|
||||
(u32)(pn) << 0 | \
|
||||
(u32)(t0) << 6 | \
|
||||
(u32)(t1) << 12 | \
|
||||
(u32)(t2) << 18 | \
|
||||
(u32)(t3) << 24 \
|
||||
)
|
||||
|
||||
#define CP_MTX_REG_B(t4, t5, t6, t7) \
|
||||
( \
|
||||
(u32)(t4) << 0 | \
|
||||
(u32)(t5) << 6 | \
|
||||
(u32)(t6) << 12 | \
|
||||
(u32)(t7) << 18 \
|
||||
)
|
||||
|
||||
void GDLoadPosMtxImm(const Mtx mtx, u32 id);
|
||||
void GDLoadPosMtxIndx(u16 mtx_indx, u32 id);
|
||||
void GDLoadNrmMtxImm(const Mtx mtx, u32 id);
|
||||
void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id);
|
||||
void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id);
|
||||
void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type);
|
||||
void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type);
|
||||
void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7);
|
||||
void GDSetProjection(const Mtx44 mtx, GXProjectionType type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef _DOLPHIN_GF_H_
|
||||
#define _DOLPHIN_GF_H_
|
||||
|
||||
#include <dolphin/gf/GFGeometry.h>
|
||||
#include <dolphin/gf/GFLight.h>
|
||||
#include <dolphin/gf/GFPixel.h>
|
||||
#include <dolphin/gf/GFTev.h>
|
||||
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef _DOLPHIN_GF_GFGEOMETRY_H_
|
||||
#define _DOLPHIN_GF_GFGEOMETRY_H_
|
||||
|
||||
#include <dolphin/gx.h>
|
||||
|
||||
#define GF_GEN_MODE(nTexGens, nChans, nTevs, cm, nInds) \
|
||||
( \
|
||||
(u32)(nTexGens) << 0 | \
|
||||
(u32)(nChans) << 4 | \
|
||||
(u32)(nTevs) << 10 | \
|
||||
(u32)(cm) << 14 | \
|
||||
(u32)(nInds) << 16 \
|
||||
)
|
||||
|
||||
static inline void GFWrite_u8(u8 data) {
|
||||
GXCmd1u8(data);
|
||||
}
|
||||
|
||||
static inline void GFWrite_u32(u32 data) {
|
||||
GXCmd1u32(data);
|
||||
}
|
||||
|
||||
static inline void GFWrite_u16(u16 data) {
|
||||
GXCmd1u16(data);
|
||||
}
|
||||
|
||||
static inline void GFWriteBPCmd(u32 regval) {
|
||||
GFWrite_u8(GX_LOAD_BP_REG);
|
||||
GFWrite_u32(regval);
|
||||
}
|
||||
|
||||
static inline void GFWriteXFCmd(u16 addr, u32 val) {
|
||||
GFWrite_u8(GX_LOAD_XF_REG);
|
||||
GFWrite_u16(0);
|
||||
GFWrite_u16(addr);
|
||||
GFWrite_u32(val);
|
||||
}
|
||||
|
||||
void GFSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm);
|
||||
|
||||
#endif /* _DOLPHIN_GF_GFGEOMETRY_H_ */
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef _DOLPHIN_GF_GFLIGHT_H
|
||||
#define _DOLPHIN_GF_GFLIGHT_H
|
||||
|
||||
#include <dolphin/gx.h>
|
||||
|
||||
void GFSetChanAmbColor(GXChannelID chan, GXColor color);
|
||||
|
||||
#endif /* _DOLPHIN_GF_GFLIGHT_H */
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef _DOLPHIN_GF_GFPIXEL_H
|
||||
#define _DOLPHIN_GF_GFPIXEL_H
|
||||
|
||||
#include <dolphin/gx.h>
|
||||
|
||||
void GFSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color);
|
||||
void GFSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor,
|
||||
GXBlendFactor dst_factor, GXLogicOp logic_op,
|
||||
u8 color_update_enable, u8 alpha_update_enable,
|
||||
u8 dither_enable);
|
||||
void GFSetZMode(u8 compare_enable, GXCompare func, u8 update_enable);
|
||||
|
||||
#endif /* _DOLPHIN_GF_GFPIXEL_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user