mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-10-02 16:10:26 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ab77952f4 |
@@ -3,4 +3,3 @@
|
||||
|
||||
# Patch files must stay LF: git apply matches context bytes against LF upstream sources
|
||||
*.patch -text
|
||||
translator/tests/Translator.Tests/TestAssets/**/*.bin binary
|
||||
|
||||
@@ -14,10 +14,6 @@ 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
|
||||
@@ -30,14 +26,6 @@ jobs:
|
||||
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
|
||||
|
||||
|
||||
@@ -20,10 +20,6 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
recompilation:
|
||||
name: Recompilation test
|
||||
uses: ./.github/workflows/recomp-test.yml
|
||||
|
||||
linux-appimage:
|
||||
name: Linux (AppImage, ${{ matrix.arch }})
|
||||
strategy:
|
||||
@@ -39,7 +35,6 @@ jobs:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
@@ -75,7 +70,6 @@ jobs:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-dotnet@v6
|
||||
with:
|
||||
@@ -99,7 +93,7 @@ jobs:
|
||||
release:
|
||||
name: Publish GitHub Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [linux-appimage, windows-installer, recompilation]
|
||||
needs: [linux-appimage, windows-installer]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -107,10 +101,9 @@ jobs:
|
||||
- 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 differs from the release tag, so a tag that was pushed without bumping every 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:
|
||||
@@ -125,7 +118,9 @@ jobs:
|
||||
status=1
|
||||
fi
|
||||
}
|
||||
check Launcher/Directory.Build.props "<Version>$version</Version>"
|
||||
check Launcher/WiiCompiled.Setup.Windows/Program.cs "public const string Version = \"$version\";"
|
||||
check Launcher/WiiCompiled.Setup.Windows/WiiCompiled.Setup.Windows.csproj "<Version>$version</Version>"
|
||||
check Launcher/Build-Installer.ps1 "ProductVersion = '$version'"
|
||||
exit $status
|
||||
|
||||
# The build jobs upload with `archive: false`, which stores each installer as a raw file
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
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
|
||||
@@ -26,8 +26,6 @@ Code.pul
|
||||
/build/
|
||||
/build-*/
|
||||
/native-build/
|
||||
/native-build-macos/
|
||||
/local-products/
|
||||
/dist/
|
||||
/out/
|
||||
[Bb]in/
|
||||
@@ -72,5 +70,3 @@ project.lock.json
|
||||
*.log
|
||||
output.txt
|
||||
|
||||
# Operating System
|
||||
.DS_Store
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "aurora-main"]
|
||||
path = aurora-main
|
||||
url = https://github.com/patchzyy/aurora.git
|
||||
@@ -73,16 +73,7 @@ function Resolve-VcRuntimeDirectory([string]$RequestedPath) {
|
||||
function Copy-Directory([string]$Source, [string]$Destination) {
|
||||
Assert-Directory $Source "Source directory"
|
||||
[IO.Directory]::CreateDirectory($Destination) | Out-Null
|
||||
# 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
|
||||
}
|
||||
}
|
||||
Copy-Item -Path (Join-Path $Source '*') -Destination $Destination -Recurse -Force
|
||||
}
|
||||
function Compress-Zip([string]$Source, [string]$Destination, [string[]]$Entries) {
|
||||
$tar = Join-Path $env:SystemRoot 'System32\tar.exe'
|
||||
@@ -288,12 +279,9 @@ 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 = $productVersion
|
||||
ProductVersion = '0.2.28'
|
||||
ExpectedGameId = $pins.GameId
|
||||
ExpectedDolSha256 = $pins.DolSha256
|
||||
ExpectedRelSha256 = $pins.RelSha256
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- The one product version. Release tags must match it. -->
|
||||
<Version>0.2.33</Version>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
+2
-10
@@ -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 $realWorkspace)).TrimEnd('\') + '\'
|
||||
$installRoot = [IO.Path]::GetFullPath((Split-Path -Parent $Workspace)).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,16 +150,8 @@ 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-MkwBuildSafePath $Toolkit 'toolchain' 'CMake\bin\cmake.exe'
|
||||
$toolchain = Get-MkwShellSafeToolchainRoot $Toolkit
|
||||
$cmake = Join-Path $toolchain 'CMake\bin\cmake.exe'
|
||||
$ninja = Join-Path $toolchain 'Ninja\ninja.exe'
|
||||
$toolchainBin = Join-Path $toolchain 'llvm-mingw\bin'
|
||||
|
||||
@@ -40,55 +40,41 @@ function Get-MkwToolchainPath([string]$ToolchainRoot) {
|
||||
) -join ';')
|
||||
}
|
||||
|
||||
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)
|
||||
function Get-MkwShellSafeToolchainRoot([string]$ToolchainRoot) {
|
||||
if ([string]::IsNullOrWhiteSpace($ToolchainRoot)) { throw 'A toolchain root is required.' }
|
||||
$full = [IO.Path]::GetFullPath($ToolchainRoot)
|
||||
# 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 -cmatch '^[A-Za-z0-9 ._\\:-]+$') { return $full }
|
||||
|
||||
Assert-File (Join-Path $full $MarkerFile) "$Kind marker"
|
||||
if ($full -notmatch '[()&^%!]') { return $full }
|
||||
|
||||
$sha = [Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
$bytes = $sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($full.ToLowerInvariant()))
|
||||
} finally { $sha.Dispose() }
|
||||
$linkName = "$Kind-" + ((($bytes[0..7]) | ForEach-Object { $_.ToString('x2') }) -join '')
|
||||
$linkName = 'toolchain-' + ((($bytes[0..7]) | ForEach-Object { $_.ToString('x2') }) -join '')
|
||||
|
||||
$failures = @()
|
||||
foreach ($base in @($env:ProgramData, $env:PUBLIC)) {
|
||||
if ([string]::IsNullOrWhiteSpace($base) -or $base -cnotmatch '^[A-Za-z0-9._\\:-]+$') { continue }
|
||||
if ([string]::IsNullOrWhiteSpace($base) -or $base -match '[()&^%! ]') { continue }
|
||||
$link = Join-Path (Join-Path $base 'WiiCompiled') $linkName
|
||||
try {
|
||||
[IO.Directory]::CreateDirectory((Split-Path -Parent $link)) | Out-Null
|
||||
$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 {
|
||||
# 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) }
|
||||
New-Item -ItemType Junction -Path $link -Target $full -ErrorAction Stop | Out-Null
|
||||
}
|
||||
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"
|
||||
Write-Host "MKWCBUILD: Building through $link, because $full contains characters cmd.exe cannot parse"
|
||||
return $link
|
||||
} catch {
|
||||
$failures += "$link ($($_.Exception.Message))"
|
||||
}
|
||||
}
|
||||
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.')
|
||||
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.')
|
||||
}
|
||||
|
||||
function Get-MkwProjectPins([string]$ProjectFile) {
|
||||
@@ -131,13 +117,12 @@ function Get-MkwProjectPins([string]$ProjectFile) {
|
||||
}
|
||||
|
||||
function Invoke-Checked([string]$FilePath, [string[]]$Arguments, [string]$Description,
|
||||
[string]$LogPrefix = 'MKWCBUILD', [string]$StepId = '', [bool]$WaitForProcessTree = $true) {
|
||||
[string]$LogPrefix = 'MKWCBUILD', [string]$StepId = '') {
|
||||
<#
|
||||
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.
|
||||
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.
|
||||
-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.
|
||||
#>
|
||||
@@ -147,14 +132,9 @@ function Invoke-Checked([string]$FilePath, [string[]]$Arguments, [string]$Descri
|
||||
if ($_.Contains('"')) { throw "A native build argument contains an unsupported quote: $_" }
|
||||
'"' + $_ + '"'
|
||||
})
|
||||
if ($WaitForProcessTree) {
|
||||
$process = Start-Process -FilePath $FilePath -ArgumentList $quotedArguments `
|
||||
-NoNewWindow -Wait -PassThru
|
||||
$exitCode = $process.ExitCode
|
||||
} else {
|
||||
& $FilePath @Arguments
|
||||
$exitCode = $LASTEXITCODE
|
||||
}
|
||||
$process = Start-Process -FilePath $FilePath -ArgumentList $quotedArguments `
|
||||
-NoNewWindow -Wait -PassThru
|
||||
$exitCode = $process.ExitCode
|
||||
$global:LASTEXITCODE = $exitCode
|
||||
if ($exitCode -ne 0) { throw "$Description failed with exit code $exitCode." }
|
||||
}
|
||||
@@ -244,14 +224,13 @@ function Get-MkwAuroraSourceFingerprint([string]$AuroraDirectory) {
|
||||
(Join-Path $root 'extern') + '\',
|
||||
(Join-Path $root 'build') + '\'
|
||||
)
|
||||
# Git metadata identifies a checkout location, not a source revision's bytes.
|
||||
# Exclude it explicitly, including a submodule's non-hidden .git file.
|
||||
# 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.
|
||||
$files = Get-ChildItem -LiteralPath $root -Recurse -File |
|
||||
Where-Object {
|
||||
$full = $_.FullName
|
||||
$relative = $full.Substring($root.Length + 1).Replace('\', '/')
|
||||
($relative -notmatch '(^|/)\.git(/|$)') -and
|
||||
-not ($excludedPrefixes | Where-Object { $full.StartsWith($_, [StringComparison]::OrdinalIgnoreCase) })
|
||||
-not ($excludedPrefixes | Where-Object { $full.StartsWith($_, [StringComparison]::OrdinalIgnoreCase) })
|
||||
} |
|
||||
Sort-Object { $_.FullName.Substring($root.Length + 1).Replace('\', '/') }
|
||||
$sha = [Security.Cryptography.SHA256]::Create()
|
||||
|
||||
@@ -21,9 +21,6 @@ $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
|
||||
@@ -42,9 +39,9 @@ $packages = @(
|
||||
},
|
||||
[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')
|
||||
Uris = @('https://github.com/encounter/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' })
|
||||
@{ File = $auroraDawn; Text = 'SHA256=7785373d569b3b0237918ec9c523239f7d0667857c5ea8242e3cdfde95e6aeab' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'fmt'; File = 'fmt-11.1.4.tar.gz'
|
||||
@@ -85,9 +82,9 @@ $packages = @(
|
||||
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' })
|
||||
Name = 'xxhash'; File = 'xxHash-0.8.3.tar.gz'
|
||||
Uris = @('https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.3.tar.gz')
|
||||
Pins = @(@{ File = $auroraExtern; Text = 'https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.3.tar.gz' })
|
||||
},
|
||||
[pscustomobject]@{
|
||||
Name = 'zlib'; File = 'zlib-1.3.2.tar.gz'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/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
|
||||
# (~43% of local build CPU time per Prepare-NativePrebuilt.ps1) and vendored Crypto++ 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
|
||||
@@ -22,17 +22,11 @@ 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'
|
||||
@@ -45,7 +39,8 @@ Usage: Prepare-NativePrebuilt.sh --arch {x86_64|aarch64} [options]
|
||||
--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
|
||||
--print-fingerprint-only Print the four provenance inputs (compiler_sha256, flag_fingerprint,
|
||||
aurora_fingerprint, third_party_fingerprint) 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.
|
||||
@@ -61,12 +56,6 @@ while [[ $# -gt 0 ]]; do
|
||||
--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
|
||||
@@ -83,22 +72,14 @@ 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}"
|
||||
toolchain_dir="$script_dir/artifacts/portable-tools/toolchain-$arch"
|
||||
cc="$toolchain_dir/bin/clang"
|
||||
cxx="$toolchain_dir/bin/clang++"
|
||||
cmake_bin="$toolchain_dir/bin/cmake"
|
||||
ninja_bin="$toolchain_dir/bin/ninja"
|
||||
runtime_source="$workspace/runtime"
|
||||
aurora_source="$workspace/aurora-main"
|
||||
|
||||
@@ -107,7 +88,7 @@ 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")
|
||||
clang_binary=$(normalize "$toolchain_dir/bin/clang-22")
|
||||
assert_file "$clang_binary" "Portable clang driver binary"
|
||||
|
||||
(( parallel > 0 )) || parallel=$(nproc)
|
||||
@@ -117,7 +98,7 @@ fingerprint_tree() {
|
||||
local root=$1; shift
|
||||
root=$(normalize "$root")
|
||||
[[ -d "$root" ]] || return 0
|
||||
local find_args=("$root" -name .git -prune -o)
|
||||
local find_args=("$root")
|
||||
local ex
|
||||
for ex in "$@"; do find_args+=(-path "$root/$ex" -prune -o); done
|
||||
find_args+=(-type f -print)
|
||||
@@ -150,8 +131,6 @@ fixed_configure_flags=(
|
||||
-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)
|
||||
@@ -162,16 +141,6 @@ fixed_configure_flags=(
|
||||
-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
|
||||
@@ -179,24 +148,19 @@ flag_fingerprint=$(printf '%s\n' "${fixed_configure_flags[@]}" | sha256sum | awk
|
||||
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.
|
||||
# The harvested Crypto++ archive is consumed against this tree's headers, so it is fingerprinted
|
||||
# for the same reason as aurora above. No exclusions: unlike aurora's extern/, nothing under
|
||||
# runtime/third_party is shipped separately.
|
||||
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
|
||||
compiler_sha256=$(sha256_of "$clang_binary")
|
||||
|
||||
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
|
||||
|
||||
@@ -397,21 +361,6 @@ while IFS='|' read -r name type file linkerfile; do
|
||||
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.
|
||||
@@ -477,9 +426,6 @@ for item in "${link_items[@]}"; do
|
||||
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
|
||||
@@ -559,9 +505,6 @@ generated_cmake="$output_dir/native_prebuilt.cmake"
|
||||
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"
|
||||
@@ -597,12 +540,12 @@ 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'
|
||||
"$sdl3_target" "$harvested_count" <<'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:]
|
||||
harvested_count) = sys.argv[1:]
|
||||
|
||||
contents = []
|
||||
for root, dirs, files in os.walk(output_dir):
|
||||
@@ -617,21 +560,9 @@ for root, dirs, files in os.walk(output_dir):
|
||||
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,
|
||||
"BuiltUtc": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z",
|
||||
"CompilerSha256": compiler_sha256,
|
||||
"CompilerVersion": compiler_version,
|
||||
"FlagFingerprint": flag_fingerprint,
|
||||
@@ -639,7 +570,6 @@ provenance = {
|
||||
"DawnRuntimeSha256": dawn_runtime_sha256,
|
||||
"AuroraSourceFingerprint": aurora_fingerprint,
|
||||
"ThirdPartySourceFingerprint": third_party_fingerprint,
|
||||
"MbedTlsFingerprint": mbedtls_fingerprint,
|
||||
"Sdl3Target": sdl3_target,
|
||||
"HarvestedLibraryCount": int(harvested_count),
|
||||
"Contents": contents,
|
||||
|
||||
@@ -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, shell scripts, and hand-written lists on
|
||||
# consumers can't read YAML (the C++ runtime header, the C# constants, hand-written lists on
|
||||
# both sides of the C#/PowerShell boundary), so those are checked here instead.
|
||||
[CmdletBinding()]
|
||||
param([string]$RepositoryRoot)
|
||||
@@ -58,12 +58,6 @@ $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.
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
# 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,6 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>WiiCompiled.Setup.Common.Cli</RootNamespace>
|
||||
<AssemblyName>WiiCompiled.Setup.Common.Cli</AssemblyName>
|
||||
<Version>0.2.28</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 = "https://rwfc.net/api/wfc/payload?g=RMCPD00";
|
||||
public const string CurrentRetroWfcPayloadUri = "http://nas.play.rwfc.net/payload?g=RMCPD00";
|
||||
private static readonly string RetroWfcOfflinePayloadFile =
|
||||
Path.Combine("binary", "payload.RMCPD00.bin");
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>WiiCompiled.Setup.Common</RootNamespace>
|
||||
<AssemblyName>WiiCompiled.Setup.Common</AssemblyName>
|
||||
<Version>0.2.28</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Shared nodtool/Retro-WFC-payload logic used by both the Windows and Linux installers</Description>
|
||||
|
||||
@@ -13,8 +13,7 @@ internal static class BuildRunner
|
||||
string workspace, string profile, string outputDir, string? baseOutputDir,
|
||||
string? retroDir, string? retroWfcOfflineDir, bool skipRetroWfcPayload,
|
||||
bool forceCleanBuild, string? translatorBin, string? ccBin, string? cxxBin, string? fuseLd,
|
||||
string? cmakeBin, string? ninjaBin, string? nativePrebuiltDir, string? sysroot,
|
||||
IInstallReporter reporter,
|
||||
string? cmakeBin, string? ninjaBin, string? nativePrebuiltDir, IInstallReporter reporter,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var script = Path.Combine(workspace, "Launcher", "local-build.sh");
|
||||
@@ -78,10 +77,6 @@ internal static class BuildRunner
|
||||
{
|
||||
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,13 +1,9 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace WiiCompiled.Setup.Linux;
|
||||
|
||||
internal static class ProductInfo
|
||||
{
|
||||
public const string Name = "WiiCompiled";
|
||||
public static readonly string Version =
|
||||
typeof(ProductInfo).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
|
||||
.InformationalVersion;
|
||||
public const string Version = "0.2.28";
|
||||
}
|
||||
|
||||
/// <summary>One installed product's record inside install-state.json.</summary>
|
||||
|
||||
@@ -127,52 +127,22 @@ 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,
|
||||
"Downloading the current Retro-WFC payload", 1);
|
||||
reporter.Progress(InstallStages.Validate, "Preparing the Retro-WFC payload", 1);
|
||||
try
|
||||
{
|
||||
// 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.
|
||||
RetroWfcPayload.ValidateStagedRetroWfcPayloadDirectory(cacheDir);
|
||||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
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,
|
||||
@@ -186,7 +156,6 @@ internal static class Program
|
||||
flags.GetValueOrDefault("cmake"),
|
||||
flags.GetValueOrDefault("ninja"),
|
||||
flags.GetValueOrDefault("native-prebuilt-dir"),
|
||||
sysroot,
|
||||
reporter, token);
|
||||
|
||||
reporter.Progress(InstallStages.Shortcuts, "Creating shortcuts", 98);
|
||||
@@ -355,7 +324,7 @@ internal static class Program
|
||||
{--download-retro-wfc-payload | --skip-retro-wfc-payload}]
|
||||
[--force-clean-build] [--translator-bin PATH] [--disc-tool-bin PATH]
|
||||
[--cc PATH] [--cxx PATH] [--fuse-ld NAME_OR_PATH] [--cmake PATH] [--ninja PATH]
|
||||
[--native-prebuilt-dir DIR] [--sysroot PATH] [--progress-json] [--workspace DIR]
|
||||
[--native-prebuilt-dir DIR] [--progress-json] [--workspace DIR]
|
||||
uninstall
|
||||
launch-base
|
||||
launch-retro
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>WiiCompiled.Setup.Linux</AssemblyName>
|
||||
<RootNamespace>WiiCompiled.Setup.Linux</RootNamespace>
|
||||
<Version>0.2.28</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Command-line installer and launcher for WiiCompiled on Linux</Description>
|
||||
|
||||
@@ -110,7 +110,8 @@ internal sealed class ProductRepairService
|
||||
InputValidation.CurrentRetroWfcPayloadUri, payloadScratch, cancellationToken);
|
||||
}
|
||||
catch (Exception ex) when (!cancellationToken.IsCancellationRequested &&
|
||||
ex is HttpRequestException or TimeoutException or IOException)
|
||||
ex is HttpRequestException or IOException or InvalidDataException
|
||||
or InvalidOperationException or OperationCanceledException)
|
||||
{
|
||||
payloadSnapshot = RecoverInstalledRetroWfcPayload(toolkitFingerprint,
|
||||
Path.Combine(scratchRoot, "retro-wfc-payload-recovered"), ex, cancellationToken);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
namespace WiiCompiled.Setup.Windows;
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static class Program
|
||||
@@ -122,9 +121,7 @@ internal static class PlatformChecks
|
||||
internal static class ProductInfo
|
||||
{
|
||||
public const string Name = "WiiCompiled";
|
||||
public static readonly string Version =
|
||||
typeof(ProductInfo).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
|
||||
.InformationalVersion;
|
||||
public const string Version = "0.2.28";
|
||||
|
||||
/// <summary>
|
||||
/// The setup executable is copied into the installation under this name. It is the launcher and
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<AssemblyName>WiiCompiled.Setup</AssemblyName>
|
||||
<RootNamespace>WiiCompiled.Setup.Windows</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Version>0.2.28</Version>
|
||||
<Authors>patchzy</Authors>
|
||||
<Product>WiiCompiled</Product>
|
||||
<Description>Command-line installer and launcher for WiiCompiled</Description>
|
||||
|
||||
@@ -128,9 +128,9 @@ cp -a "$workspace/Launcher/artifacts/portable-tools/toolchain-$appimagetool_arch
|
||||
|
||||
# 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
|
||||
# recompiles the whole aurora/Crypto++ 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.
|
||||
# the current compiler/flags/aurora/third_party sources.
|
||||
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)
|
||||
@@ -148,7 +148,6 @@ fields = {
|
||||
"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
|
||||
@@ -167,8 +166,6 @@ 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
|
||||
|
||||
+1
-39
@@ -65,7 +65,6 @@ translator_dll_override=""
|
||||
translator_bin_override=""
|
||||
fuse_ld_override=""
|
||||
native_prebuilt_dir=""
|
||||
sysroot=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
@@ -88,8 +87,6 @@ Usage: local-build.sh --output-dir DIR [options]
|
||||
--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
|
||||
}
|
||||
|
||||
@@ -113,7 +110,6 @@ while [[ $# -gt 0 ]]; do
|
||||
--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
|
||||
@@ -190,30 +186,6 @@ 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.
|
||||
@@ -442,14 +414,6 @@ 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" "${configure_args[@]}"
|
||||
@@ -481,9 +445,7 @@ publish_built_product() {
|
||||
local exe=$build/$target
|
||||
assert_file "$exe" "Locally compiled game executable"
|
||||
cp -f "$exe" "$destination/$target"
|
||||
# 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
|
||||
for name in dsp_coef.bin initial_pipeline_cache.db; do
|
||||
[[ -f "$build/$name" ]] && cp -f "$build/$name" "$destination/"
|
||||
done
|
||||
[[ -d "$build/wii_bootstrap" ]] && cp -rf "$build/wii_bootstrap" "$destination/"
|
||||
|
||||
@@ -98,8 +98,6 @@ 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"
|
||||
|
||||
@@ -27,7 +27,7 @@ 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
|
||||
for asset in dsp_coef.bin initial_pipeline_cache.db wii_bootstrap; do [[ -e "$build_dir/$asset" ]] || fail "missing runtime asset: $build_dir/$asset"; done
|
||||
|
||||
app="$output_dir/$product.app"
|
||||
macos="$app/Contents/MacOS"
|
||||
@@ -52,7 +52,7 @@ cat > "$app/Contents/Info.plist" <<EOF
|
||||
</dict></plist>
|
||||
EOF
|
||||
ditto "$build_dir/$product" "$macos/$product"
|
||||
for asset in dsp_coef.bin initial_pipeline_cache.db cacert.pem wii_bootstrap; do
|
||||
for asset in dsp_coef.bin initial_pipeline_cache.db wii_bootstrap; do
|
||||
ditto "$build_dir/$asset" "$resources/$asset"
|
||||
ln -s "../Resources/$asset" "$macos/$asset"
|
||||
done
|
||||
|
||||
@@ -77,40 +77,26 @@ if [[ -n "$retro_dir" ]]; 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
|
||||
if [[ -f "$retro_wfc_payload" ]] && ! "$translator" validate-retro-wfc-payload --directory "$retro_wfc_dir"; then
|
||||
printf 'Discarding an invalid cached Retro-WFC payload...\n' >&2
|
||||
rm -f "$retro_wfc_payload"
|
||||
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
|
||||
if [[ ! -f "$retro_wfc_payload" ]]; then
|
||||
printf 'Downloading the 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
|
||||
/usr/bin/curl --fail --silent --show-error --connect-timeout 10 --max-time 30 \
|
||||
--retry 1 --output "$temporary_payload" \
|
||||
'http://nas.play.rwfc.net/payload?g=RMCPD00' || fail 'could not download the Retro-WFC payload needed for online play'
|
||||
"$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
|
||||
|
||||
@@ -52,13 +52,13 @@ done
|
||||
|
||||
case "$arch" in
|
||||
x86_64) llvm_release_arch=X64; target_triple=x86_64-unknown-linux-gnu
|
||||
llvm_release_sha256=fccecb1906e7ddf5ec040aec5b646b650e2daaafa4423b41341c4717db5bdec0
|
||||
llvm_release_sha256=df0e1ecf16caf3489a272a5eea4eec9b0d82878f6477fa309504f918a0006384
|
||||
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
|
||||
llvm_release_sha256=805efad2bb91cb4967fa569e0881d10c0f69c04461cf671cccbae19f547acc34
|
||||
cmake_release_arch=aarch64
|
||||
cmake_sha256=9ea38356dbd3e32e51029a3e09a0f2f8e117ef4fbcaad7a21ffb36409bbd5cb4
|
||||
ninja_asset=ninja-linux-aarch64.zip
|
||||
@@ -101,14 +101,11 @@ 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_name="LLVM-$llvm_version-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" \
|
||||
"https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvm_version/$llvm_archive_name" \
|
||||
"$llvm_release_sha256"
|
||||
|
||||
extract_root="$script_dir/artifacts/.extract-clang-$arch"
|
||||
@@ -116,7 +113,7 @@ 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}"
|
||||
src="$extract_root/LLVM-$llvm_version-Linux-$llvm_release_arch"
|
||||
[[ -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..."
|
||||
@@ -168,8 +165,7 @@ 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}"
|
||||
cmake_src="$cmake_extract_root/cmake-$cmake_version-linux-$cmake_release_arch"
|
||||
[[ -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"
|
||||
@@ -205,10 +201,10 @@ Ninja $ninja_version
|
||||
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'
|
||||
echo "prepare-portable-tools.sh: smoke-testing the toolchain..."
|
||||
smoke_dir=$(mktemp -d)
|
||||
trap 'rm -rf "$smoke_dir"' EXIT
|
||||
cat > "$smoke_dir/t.cpp" <<'EOF'
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
int main() {
|
||||
@@ -218,25 +214,24 @@ int main() {
|
||||
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"
|
||||
"$work/bin/clang++" -std=c++20 -fuse-ld=lld "$smoke_dir/t.cpp" -o "$smoke_dir/t"
|
||||
"$smoke_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)
|
||||
cat > "$smoke_dir/CMakeLists.txt" <<'EOF'
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(smoke CXX)
|
||||
add_executable(smoke t.cpp)
|
||||
EOF
|
||||
"$work/bin/cmake" -S "$test_dir" -B "$test_dir/build" -G Ninja \
|
||||
"$work/bin/cmake" -S "$smoke_dir" -B "$smoke_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"
|
||||
"$work/bin/cmake" --build "$smoke_dir/build" >/dev/null
|
||||
"$smoke_dir/build/smoke"
|
||||
|
||||
rm -rf "$test_dir"
|
||||
rm -rf "$smoke_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,19 +1,6 @@
|
||||
<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
|
||||
@@ -66,6 +53,12 @@ Press **F10** while the game window has focus:
|
||||
|
||||
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.
|
||||
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.
|
||||
@@ -157,9 +150,7 @@ 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).
|
||||
|
||||
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).
|
||||
translation, generating the manifest and build graph, and compiling. see [`translator/README.md`](translator/README.md).
|
||||
|
||||
## FAQ
|
||||
|
||||
@@ -208,7 +199,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
|
||||
|
||||
@@ -114,16 +114,14 @@ 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`,
|
||||
`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
|
||||
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. 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> |
|
||||
@@ -132,7 +130,7 @@ trees themselves (fetched by `Launcher/Prepare-Dependencies.ps1`) so end-user bu
|
||||
| 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.4 | BSD-2-Clause | <https://github.com/Cyan4973/xxHash> |
|
||||
| xxHash | 0.8.3 | 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/> |
|
||||
|
||||
-1
Submodule aurora-main deleted from 5506c5dc53
@@ -0,0 +1,29 @@
|
||||
---
|
||||
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
|
||||
@@ -0,0 +1,10 @@
|
||||
.buildcache/
|
||||
.DS_Store
|
||||
.idea/
|
||||
.cache/
|
||||
.vscode/
|
||||
.vs/
|
||||
build/
|
||||
cmake-build-*/
|
||||
CMakeUserPresets.json
|
||||
out/
|
||||
@@ -0,0 +1,85 @@
|
||||
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 ()
|
||||
@@ -0,0 +1,21 @@
|
||||
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.
|
||||
@@ -0,0 +1,46 @@
|
||||
<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.
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,55 @@
|
||||
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()
|
||||
@@ -0,0 +1,255 @@
|
||||
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 ()
|
||||
@@ -0,0 +1,43 @@
|
||||
# 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)
|
||||
@@ -0,0 +1,150 @@
|
||||
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 ()
|
||||
@@ -0,0 +1,126 @@
|
||||
# Source-level fixes applied to the vendored SDL3 tree before it is built.
|
||||
#
|
||||
# Each patch is an exact string replacement, checked and idempotent: a tree that
|
||||
# already carries the fix is left alone, a tree where the anchor text is missing
|
||||
# (a different SDL version) stops the configure with a clear message instead of
|
||||
# silently building without the fix.
|
||||
#
|
||||
# Used two ways:
|
||||
# - included by AuroraSDL3Provider.cmake, which calls aurora_sdl3_apply_patches()
|
||||
# on a pre-provided source tree (FETCHCONTENT_SOURCE_DIR_SDL);
|
||||
# - run as `cmake -DSDL_SOURCE_DIR=<dir> -P AuroraSDL3Patches.cmake` from the
|
||||
# FetchContent PATCH_COMMAND for a freshly extracted tarball.
|
||||
|
||||
function(_aurora_sdl3_replace file description old new)
|
||||
file(READ "${file}" _content)
|
||||
string(FIND "${_content}" "${new}" _already)
|
||||
if (NOT _already EQUAL -1)
|
||||
return()
|
||||
endif ()
|
||||
string(FIND "${_content}" "${old}" _anchor)
|
||||
if (_anchor EQUAL -1)
|
||||
message(FATAL_ERROR "aurora: SDL3 patch '${description}' does not apply to ${file}; "
|
||||
"the vendored SDL version changed, review AuroraSDL3Patches.cmake")
|
||||
endif ()
|
||||
string(REPLACE "${old}" "${new}" _content "${_content}")
|
||||
file(WRITE "${file}" "${_content}")
|
||||
message(STATUS "aurora: SDL3 patch applied: ${description}")
|
||||
endfunction()
|
||||
|
||||
function(aurora_sdl3_apply_patches sdl_source_dir)
|
||||
set(_wii "${sdl_source_dir}/src/joystick/hidapi/SDL_hidapi_wii.c")
|
||||
if (NOT EXISTS "${_wii}")
|
||||
message(FATAL_ERROR "aurora: SDL3 source tree at ${sdl_source_dir} has no SDL_hidapi_wii.c")
|
||||
endif ()
|
||||
|
||||
# Wii Remote: rebuild the joystick in place after an extension change.
|
||||
#
|
||||
# When a Nunchuk or Classic Controller is plugged in or pulled out, the driver
|
||||
# flags the joystick as disconnected so it can come back with the new name and
|
||||
# capabilities. But the HID device stays open, and HIDAPI only removes a
|
||||
# joystick-less device once its handle is closed, so nothing ever re-creates
|
||||
# the joystick: the remote is gone for good until the application toggles the
|
||||
# driver hint (which closes and re-opens the Bluetooth HID handle, something
|
||||
# some Windows Bluetooth stacks answer by dropping the link). Instead, when the
|
||||
# device has no joystick, probe the extension again (two bounded attempts, at
|
||||
# most once a second) and connect a new joystick on the still-open handle.
|
||||
_aurora_sdl3_replace("${_wii}" "Wii Remote in-place reconnect (context field)"
|
||||
[==[ Uint64 m_ulNextMotionPlusCheck;
|
||||
bool m_bDisconnected;
|
||||
]==]
|
||||
[==[ Uint64 m_ulNextMotionPlusCheck;
|
||||
bool m_bDisconnected;
|
||||
Uint64 m_ulNextReconnect; /* WiiCompiled: see HIDAPI_DriverWii_UpdateDevice */
|
||||
]==])
|
||||
_aurora_sdl3_replace("${_wii}" "Wii Remote in-place reconnect (bounded extension probe)"
|
||||
[==[static EWiiExtensionControllerType ReadExtensionControllerType(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context;
|
||||
EWiiExtensionControllerType eExtensionControllerType = k_eWiiExtensionControllerType_Unknown;
|
||||
const int MAX_ATTEMPTS = 20;
|
||||
int attempts = 0;
|
||||
]==]
|
||||
[==[static EWiiExtensionControllerType ReadExtensionControllerTypeAttempts(SDL_HIDAPI_Device *device, int MAX_ATTEMPTS)
|
||||
{
|
||||
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context;
|
||||
EWiiExtensionControllerType eExtensionControllerType = k_eWiiExtensionControllerType_Unknown;
|
||||
int attempts = 0;
|
||||
]==])
|
||||
_aurora_sdl3_replace("${_wii}" "Wii Remote in-place reconnect (probe wrapper)"
|
||||
[==[static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
]==]
|
||||
[==[static EWiiExtensionControllerType ReadExtensionControllerType(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
return ReadExtensionControllerTypeAttempts(device, 20);
|
||||
}
|
||||
|
||||
static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
]==])
|
||||
_aurora_sdl3_replace("${_wii}" "Wii Remote in-place reconnect (UpdateDevice)"
|
||||
[==[ if (device->num_joysticks > 0) {
|
||||
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
now = SDL_GetTicks();
|
||||
]==]
|
||||
[==[ if (device->num_joysticks > 0) {
|
||||
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
||||
} else {
|
||||
/* WiiCompiled: the joystick was dropped (extension plugged or unplugged,
|
||||
* or a failed read) but the HID device is still open, and the device
|
||||
* list only removes a joystick-less device once its handle is closed.
|
||||
* Rebuild the joystick in place, so an extension change behaves like it
|
||||
* does on the console: the remote never goes away, it just changes
|
||||
* type. If the remote does not answer, keep the device and retry. */
|
||||
now = SDL_GetTicks();
|
||||
if (ctx->m_ulNextReconnect != 0 && now < ctx->m_ulNextReconnect) {
|
||||
return false;
|
||||
}
|
||||
ctx->m_ulNextReconnect = now + 1000;
|
||||
{
|
||||
EWiiExtensionControllerType type = ReadExtensionControllerTypeAttempts(device, 2);
|
||||
if (type == k_eWiiExtensionControllerType_Unknown) {
|
||||
return false;
|
||||
}
|
||||
ctx->m_bDisconnected = false;
|
||||
ctx->m_ulLastInput = now;
|
||||
ctx->m_ulNextReconnect = 0;
|
||||
ctx->m_eExtensionControllerType = type;
|
||||
UpdateDeviceIdentity(device);
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Reconnected joystick as %s", device->name);
|
||||
return HIDAPI_JoystickConnected(device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
now = SDL_GetTicks();
|
||||
]==])
|
||||
endfunction()
|
||||
|
||||
# Script mode (FetchContent PATCH_COMMAND).
|
||||
if (CMAKE_SCRIPT_MODE_FILE AND DEFINED SDL_SOURCE_DIR)
|
||||
aurora_sdl3_apply_patches("${SDL_SOURCE_DIR}")
|
||||
endif ()
|
||||
@@ -0,0 +1,161 @@
|
||||
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)
|
||||
# Source fixes for the vendored SDL (see AuroraSDL3Patches.cmake). A freshly
|
||||
# downloaded tarball is patched by the PATCH_COMMAND; a tree handed in through
|
||||
# FETCHCONTENT_SOURCE_DIR_SDL skips the download steps, so patch it here.
|
||||
set(_aurora_sdl3_patches "${CMAKE_CURRENT_LIST_DIR}/AuroraSDL3Patches.cmake")
|
||||
include("${_aurora_sdl3_patches}")
|
||||
if (DEFINED FETCHCONTENT_SOURCE_DIR_SDL AND EXISTS "${FETCHCONTENT_SOURCE_DIR_SDL}")
|
||||
aurora_sdl3_apply_patches("${FETCHCONTENT_SOURCE_DIR_SDL}")
|
||||
endif ()
|
||||
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
|
||||
PATCH_COMMAND "${CMAKE_COMMAND}" -DSDL_SOURCE_DIR=<SOURCE_DIR> -P "${_aurora_sdl3_patches}"
|
||||
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 ()
|
||||
@@ -0,0 +1,17 @@
|
||||
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)
|
||||
@@ -0,0 +1,64 @@
|
||||
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 ()
|
||||
@@ -0,0 +1,10 @@
|
||||
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)
|
||||
@@ -0,0 +1,16 @@
|
||||
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)
|
||||
@@ -0,0 +1,47 @@
|
||||
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)
|
||||
@@ -0,0 +1,6 @@
|
||||
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})
|
||||
@@ -0,0 +1,7 @@
|
||||
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)
|
||||
@@ -0,0 +1,12 @@
|
||||
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)
|
||||
@@ -0,0 +1,14 @@
|
||||
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)
|
||||
@@ -0,0 +1,7 @@
|
||||
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)
|
||||
@@ -0,0 +1,7 @@
|
||||
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)
|
||||
@@ -0,0 +1,7 @@
|
||||
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)
|
||||
@@ -0,0 +1,8 @@
|
||||
/* 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)))
|
||||
@@ -0,0 +1,55 @@
|
||||
# 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
|
||||
@@ -0,0 +1,4 @@
|
||||
if (AURORA_ENABLE_GX)
|
||||
add_executable(simple simple.c)
|
||||
target_link_libraries(simple PRIVATE aurora::core aurora::gx aurora::main aurora::vi)
|
||||
endif ()
|
||||
@@ -0,0 +1,90 @@
|
||||
#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
@@ -0,0 +1,310 @@
|
||||
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 ()
|
||||
@@ -0,0 +1,172 @@
|
||||
#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
|
||||
@@ -0,0 +1,27 @@
|
||||
#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
|
||||
@@ -0,0 +1,44 @@
|
||||
#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
|
||||
@@ -0,0 +1,97 @@
|
||||
#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
|
||||
@@ -0,0 +1,20 @@
|
||||
#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
|
||||
@@ -0,0 +1,13 @@
|
||||
#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);
|
||||
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
@@ -0,0 +1,254 @@
|
||||
#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
|
||||
@@ -0,0 +1,81 @@
|
||||
#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
|
||||
@@ -0,0 +1,50 @@
|
||||
#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
|
||||
@@ -0,0 +1,79 @@
|
||||
#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
|
||||
@@ -0,0 +1,542 @@
|
||||
#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
|
||||
@@ -0,0 +1,340 @@
|
||||
#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
|
||||
@@ -0,0 +1,22 @@
|
||||
#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_
|
||||
@@ -0,0 +1,31 @@
|
||||
#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
|
||||
@@ -0,0 +1,24 @@
|
||||
#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
|
||||
@@ -0,0 +1,57 @@
|
||||
#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
|
||||
@@ -0,0 +1,56 @@
|
||||
#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
|
||||
@@ -0,0 +1,237 @@
|
||||
#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
|
||||
@@ -0,0 +1,103 @@
|
||||
#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
|
||||
@@ -0,0 +1,15 @@
|
||||
#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
|
||||
@@ -0,0 +1,22 @@
|
||||
#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
|
||||
@@ -0,0 +1,177 @@
|
||||
#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
|
||||
@@ -0,0 +1,31 @@
|
||||
#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
|
||||
@@ -0,0 +1,525 @@
|
||||
#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
|
||||
@@ -0,0 +1,91 @@
|
||||
#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
|
||||
@@ -0,0 +1,65 @@
|
||||
#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
|
||||
@@ -0,0 +1,95 @@
|
||||
#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
|
||||
@@ -0,0 +1,133 @@
|
||||
#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
|
||||
@@ -0,0 +1,127 @@
|
||||
#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
|
||||
@@ -0,0 +1,56 @@
|
||||
#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
|
||||
@@ -0,0 +1,9 @@
|
||||
#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
|
||||
@@ -0,0 +1,41 @@
|
||||
#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_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,13 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _DOLPHIN_GF_GFTEV_H
|
||||
#define _DOLPHIN_GF_GFTEV_H
|
||||
|
||||
#include <dolphin/gx.h>
|
||||
|
||||
void GFSetTevColorS10(GXTevRegID reg, GXColorS10 color);
|
||||
|
||||
#endif /* _DOLPHIN_GF_GFTEV_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef DOLPHIN_GX_H
|
||||
#define DOLPHIN_GX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
#include <dolphin/gx/GXBump.h>
|
||||
#include <dolphin/gx/GXCommandList.h>
|
||||
#include <dolphin/gx/GXCpu2Efb.h>
|
||||
#include <dolphin/gx/GXCull.h>
|
||||
#include <dolphin/gx/GXDispList.h>
|
||||
#include <dolphin/gx/GXDraw.h>
|
||||
#include <dolphin/gx/GXExtra.h>
|
||||
#include <dolphin/gx/GXFifo.h>
|
||||
#include <dolphin/gx/GXFrameBuffer.h>
|
||||
#include <dolphin/gx/GXGeometry.h>
|
||||
#include <dolphin/gx/GXGet.h>
|
||||
#include <dolphin/gx/GXLighting.h>
|
||||
#include <dolphin/gx/GXManage.h>
|
||||
#include <dolphin/gx/GXPerf.h>
|
||||
#include <dolphin/gx/GXPixel.h>
|
||||
#include <dolphin/gx/GXStruct.h>
|
||||
#include <dolphin/gx/GXTev.h>
|
||||
#include <dolphin/gx/GXTexture.h>
|
||||
#include <dolphin/gx/GXTransform.h>
|
||||
#include <dolphin/gx/GXVert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
#ifndef DOLPHIN_GXAURORA_H
|
||||
#define DOLPHIN_GXAURORA_H
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// Subcommands for GX_LOAD_AURORA.
|
||||
//
|
||||
|
||||
/**
|
||||
* Sets the actual render viewport in native framebuffer coordinates.
|
||||
* Must be followed by six f32 values: left, top, width, height, nearz, farz.
|
||||
*/
|
||||
#define GX_LOAD_AURORA_VIEWPORT_RENDER 0x0001
|
||||
|
||||
/**
|
||||
* Sets the actual render scissor in native framebuffer coordinates.
|
||||
* Must be followed by four u32 values: left, top, width, height.
|
||||
*/
|
||||
#define GX_LOAD_AURORA_SCISSOR_RENDER 0x0002
|
||||
|
||||
/**
|
||||
* Aurora equivalent of CP_REG_ARRAYBASE_ID: sets the base address and size of a vertex array.
|
||||
* This command must be followed by a 64-bit memory address, 32-bit size, and 1-byte little-endian flag.
|
||||
* The index of the vertex array is given by the lowest 4 bits of the command ID,
|
||||
* e.g. writing GX_LOAD_AURORA_ARRAYBASE + 5 will set the vertex array for the sixth vertex attribute.
|
||||
* To set strides, use the normal CP_REG_ARRAYSTRIDE_ID register.
|
||||
*/
|
||||
#define GX_LOAD_AURORA_ARRAYBASE 0x0010
|
||||
|
||||
/**
|
||||
* Pushes a debug group to the backend graphics API. These may show in debugging tools such as RenderDoc.
|
||||
* Must be followed by a u16 string length and that many UTF-8 characters (no null terminator required).
|
||||
* It is considered an error to have unpopped debug groups at the end of the frame. They will be automatically cleared.
|
||||
*/
|
||||
#define GX_LOAD_AURORA_DEBUG_GROUP_PUSH 0x0020
|
||||
|
||||
/**
|
||||
* Pops a previously pushed debug group.
|
||||
* Followed by nothing.
|
||||
*/
|
||||
#define GX_LOAD_AURORA_DEBUG_GROUP_POP 0x0021
|
||||
|
||||
/**
|
||||
* Sends a debug marker to the backend graphics API.
|
||||
* Must be followed by a u16 string length and that many UTF-8 characters (no null terminator required).
|
||||
*/
|
||||
#define GX_LOAD_AURORA_DEBUG_MARKER_INSERT 0x0022
|
||||
|
||||
#define GX_LOAD_AURORA_TEXOBJ 0x0030
|
||||
|
||||
#define GX_LOAD_AURORA_TLUT 0x0031
|
||||
|
||||
#define GX_LOAD_AURORA_DESTROY_TEXOBJ 0x0032
|
||||
|
||||
#define GX_LOAD_AURORA_DESTROY_TLUT 0x0033
|
||||
|
||||
#define GX_LOAD_AURORA_DESTROY_COPY_TEX 0x0034
|
||||
|
||||
#define GX_LOAD_AURORA_INVALIDATE_TEX_ALL 0x0035
|
||||
|
||||
|
||||
/*
|
||||
* Debug marker stuff
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void GXPushDebugGroup(const char* label);
|
||||
|
||||
/**
|
||||
* Pop a debug group previously pushed via GXPushDebugGroup().
|
||||
*/
|
||||
void GXPopDebugGroup();
|
||||
|
||||
/**
|
||||
* Sends a debug marker to the backend graphics API. These may show in debugging tools such as RenderDoc.
|
||||
*/
|
||||
void GXInsertDebugMarker(const char* label);
|
||||
|
||||
typedef enum _AuroraViewportPolicy {
|
||||
AURORA_VIEWPORT_FIT = 0, // Preserve logical aspect in the content framebuffer
|
||||
AURORA_VIEWPORT_STRETCH = 1, // Match content framebuffer aspect to the native surface
|
||||
AURORA_VIEWPORT_NATIVE = 2, // Use active framebuffer pixels directly
|
||||
} AuroraViewportPolicy;
|
||||
|
||||
/**
|
||||
* Configures content framebuffer sizing and how GXSetViewport/GXSetScissor parameters are applied to rendering.
|
||||
* When AURORA_VIEWPORT_NATIVE is used, GXSetTexCopySrc/GXSetTexCopyDst will use native framebuffer resolution.
|
||||
*/
|
||||
void AuroraSetViewportPolicy(AuroraViewportPolicy policy);
|
||||
|
||||
/**
|
||||
* Retrieves the current content framebuffer size.
|
||||
*/
|
||||
void AuroraGetRenderSize(u32* width, u32* height);
|
||||
|
||||
/** Retrieves the current native presentation-surface size, ignoring the GX sizing policy. */
|
||||
void AuroraGetSurfaceSize(u32* width, u32* height);
|
||||
|
||||
/**
|
||||
* Sets the actual render viewport in native framebuffer coordinates.
|
||||
* Overrides the automatically scaled values set by the logical GXSetViewport.
|
||||
*/
|
||||
void GXSetViewportRender(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz);
|
||||
|
||||
/**
|
||||
* Sets the actual render scissor in native framebuffer coordinates.
|
||||
* Overrides the automatically scaled values set by the logical GXSetScissor.
|
||||
*/
|
||||
void GXSetScissorRender(u32 left, u32 top, u32 wd, u32 ht);
|
||||
|
||||
/** Maps the logical GX viewport and scissor into a centered safe area, for fixed-aspect UI bridges. */
|
||||
void GXSetViewportScissorRenderSafeArea(f32 aspect);
|
||||
|
||||
/** Restores the viewport and scissor from logical GX state after GXSetViewportScissorRenderSafeArea. */
|
||||
void GXRestoreViewportScissorRender(void);
|
||||
|
||||
/** Sets the texture-copy source in active render-target coordinates, for bridges that already
|
||||
* resolved VI/window scaling. */
|
||||
void GXSetTexCopySrcRender(u16 left, u16 top, u16 wd, u16 ht);
|
||||
|
||||
/**
|
||||
* Create an offscreen framebuffer and switch rendering to it.
|
||||
* All subsequent GX rendering will target this framebuffer until GXRestoreFrameBuffer() is called.
|
||||
* Use GXCopyTex to resolve the offscreen content into a texture.
|
||||
*/
|
||||
void GXCreateFrameBuffer(u32 width, u32 height);
|
||||
|
||||
/**
|
||||
* Restore rendering to the main EFB framebuffer.
|
||||
* Must be called after GXCreateFrameBuffer() to resume normal rendering.
|
||||
*/
|
||||
void GXRestoreFrameBuffer(void);
|
||||
|
||||
void GXApplyBPReg(u8 reg, u32 value);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user