~D9wr9Fx>Tp)L9K13&K(iSf2U%g49W*H{?CMgeg>o{Rrwa5_iCX#xPd_
zBe%KrtO&lYZuM(|jRz%_0+C=#-nAxOs+$OGIv}qHR*7C7ye6>>dj=Ou!m65;I0=g#
z>MSIJ!8b7u-bfHdUIz(EtN(}38kx9vmd@*-!g%Kh})SGL^0hGm)OCL
zZie^)1t5AJ;4+C5MNrO4ml2+yCrn6&T^4aCc`v9kY|RNEh)%q2a)2t0#5Yhg9dVh(
zWtis8Ylls(X5Ox8_-q8fpi79;cw_`d4
zBUCaZ*%lxez{u@~TFEZ4t-%mfg~30o9Kc3g*&4+?U801GTce2TiUM^`TRUPr*61@+
z@9wW{XxG0YyW)|DpZjG$9ZP$ld)M;bZ~Cl5IUbxQsa9@@)-wQ|!|US}sPS9!2%oDW
z$W4+Sn8y8=m#zsoUR(1r2vY>Fk+@-kHtNB8(XKQuxa3IzxLLKANzg!&}Fdkq2D(8kM_w398
zs-ifZ*IB|-7UFrjb5UD=Wa#2E2MTUW(Al+APITPXYCf3DN#xF3=QpZ_m%jjRlR$x$BDC*Ny+MF{Z?!n<^)
zwj@+PntFl!;UjYZ2PolZ^!PCz0x?6^|Kd`Y_fk(={a0k|ka*!TWKDVM&sw{srLLA^
z>L^QR%GNbj46>n69(OwXw{2eU=L^NJioY5^VfUhrABCdmia3QV+!CAnV^DT|t~z0@
zud*8vHy;T@`1iw8lsm=p-w)JTPZ*BBpKudc=>L7BjGAB)Z+&8Rfylof3G4s&9X16{
W2zi=MU&$Xvgqj**4NLXUM*M#q#*n7~
literal 0
HcmV?d00001
diff --git a/aurora-main/cmake/AuroraCopyRuntimeDLLs.cmake b/aurora-main/cmake/AuroraCopyRuntimeDLLs.cmake
new file mode 100644
index 0000000..b4fa166
--- /dev/null
+++ b/aurora-main/cmake/AuroraCopyRuntimeDLLs.cmake
@@ -0,0 +1,55 @@
+include_guard(GLOBAL)
+
+# aurora_copy_runtime_dlls( [...])
+#
+# 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 $ $
+ 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}" $
+ )
+ endif ()
+ endforeach ()
+ endif ()
+ endif ()
+endfunction()
+
+# aurora_install_runtime_dlls( )
+#
+# 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 \"$/*.dll\")\n\
+if(_aurora_runtime_dlls)\n\
+ file(INSTALL DESTINATION \"${install_destination}\" TYPE FILE FILES \${_aurora_runtime_dlls})\n\
+endif()"
+ )
+endfunction()
diff --git a/aurora-main/cmake/AuroraDawnProvider.cmake b/aurora-main/cmake/AuroraDawnProvider.cmake
new file mode 100644
index 0000000..002344b
--- /dev/null
+++ b/aurora-main/cmake/AuroraDawnProvider.cmake
@@ -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 ()
diff --git a/aurora-main/cmake/AuroraNodProvider.cmake b/aurora-main/cmake/AuroraNodProvider.cmake
new file mode 100644
index 0000000..dbb9a71
--- /dev/null
+++ b/aurora-main/cmake/AuroraNodProvider.cmake
@@ -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 ()
diff --git a/aurora-main/cmake/AuroraSDL3Provider.cmake b/aurora-main/cmake/AuroraSDL3Provider.cmake
new file mode 100644
index 0000000..458d424
--- /dev/null
+++ b/aurora-main/cmake/AuroraSDL3Provider.cmake
@@ -0,0 +1,149 @@
+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)
+ endif ()
+
+ include(FetchContent)
+ FetchContent_Declare(SDL
+ URL "https://github.com/libsdl-org/SDL/releases/download/release-${AURORA_SDL3_VERSION}/SDL3-${AURORA_SDL3_VERSION}.tar.gz"
+ DOWNLOAD_EXTRACT_TIMESTAMP TRUE
+ EXCLUDE_FROM_ALL
+ )
+ FetchContent_MakeAvailable(SDL)
+ else ()
+ message(STATUS "aurora: Using existing SDL3")
+ endif ()
+ _aurora_sdl3_select_target()
+
+else ()
+ message(FATAL_ERROR "Invalid AURORA_SDL3_PROVIDER: ${AURORA_SDL3_PROVIDER} "
+ "(must be auto, vendor, system, or package)")
+endif ()
diff --git a/aurora-main/cmake/aurora_card.cmake b/aurora-main/cmake/aurora_card.cmake
new file mode 100644
index 0000000..5eace0f
--- /dev/null
+++ b/aurora-main/cmake/aurora_card.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_core.cmake b/aurora-main/cmake/aurora_core.cmake
new file mode 100644
index 0000000..3e53a62
--- /dev/null
+++ b/aurora-main/cmake/aurora_core.cmake
@@ -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 ()
diff --git a/aurora-main/cmake/aurora_dvd.cmake b/aurora-main/cmake/aurora_dvd.cmake
new file mode 100644
index 0000000..c95f72e
--- /dev/null
+++ b/aurora-main/cmake/aurora_dvd.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_gd.cmake b/aurora-main/cmake/aurora_gd.cmake
new file mode 100644
index 0000000..80bd667
--- /dev/null
+++ b/aurora-main/cmake/aurora_gd.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_gx.cmake b/aurora-main/cmake/aurora_gx.cmake
new file mode 100644
index 0000000..ff740a7
--- /dev/null
+++ b/aurora-main/cmake/aurora_gx.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_main.cmake b/aurora-main/cmake/aurora_main.cmake
new file mode 100644
index 0000000..b712164
--- /dev/null
+++ b/aurora-main/cmake/aurora_main.cmake
@@ -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})
diff --git a/aurora-main/cmake/aurora_ms.cmake b/aurora-main/cmake/aurora_ms.cmake
new file mode 100644
index 0000000..9df3020
--- /dev/null
+++ b/aurora-main/cmake/aurora_ms.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_mtx.cmake b/aurora-main/cmake/aurora_mtx.cmake
new file mode 100644
index 0000000..580a942
--- /dev/null
+++ b/aurora-main/cmake/aurora_mtx.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_os.cmake b/aurora-main/cmake/aurora_os.cmake
new file mode 100644
index 0000000..77156f1
--- /dev/null
+++ b/aurora-main/cmake/aurora_os.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_pad.cmake b/aurora-main/cmake/aurora_pad.cmake
new file mode 100644
index 0000000..5790fd0
--- /dev/null
+++ b/aurora-main/cmake/aurora_pad.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_si.cmake b/aurora-main/cmake/aurora_si.cmake
new file mode 100644
index 0000000..0682c62
--- /dev/null
+++ b/aurora-main/cmake/aurora_si.cmake
@@ -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)
diff --git a/aurora-main/cmake/aurora_vi.cmake b/aurora-main/cmake/aurora_vi.cmake
new file mode 100644
index 0000000..38544af
--- /dev/null
+++ b/aurora-main/cmake/aurora_vi.cmake
@@ -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)
diff --git a/aurora-main/docs/building.md b/aurora-main/docs/building.md
new file mode 100644
index 0000000..ca1cabd
--- /dev/null
+++ b/aurora-main/docs/building.md
@@ -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
diff --git a/aurora-main/examples/CMakeLists.txt b/aurora-main/examples/CMakeLists.txt
new file mode 100644
index 0000000..c5977f6
--- /dev/null
+++ b/aurora-main/examples/CMakeLists.txt
@@ -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 ()
diff --git a/aurora-main/examples/simple.c b/aurora-main/examples/simple.c
new file mode 100644
index 0000000..cb8a6c4
--- /dev/null
+++ b/aurora-main/examples/simple.c
@@ -0,0 +1,90 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+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;
+}
diff --git a/aurora-main/extern/CMakeLists.txt b/aurora-main/extern/CMakeLists.txt
new file mode 100644
index 0000000..9d77bbb
--- /dev/null
+++ b/aurora-main/extern/CMakeLists.txt
@@ -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 .
+# 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
+ $<$:-include>
+ $<$: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 ()
diff --git a/aurora-main/include/aurora/aurora.h b/aurora-main/include/aurora/aurora.h
new file mode 100644
index 0000000..c3f70d2
--- /dev/null
+++ b/aurora-main/include/aurora/aurora.h
@@ -0,0 +1,172 @@
+#ifndef AURORA_AURORA_H
+#define AURORA_AURORA_H
+
+#ifdef __cplusplus
+#include
+#include
+
+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
diff --git a/aurora-main/include/aurora/dvd.h b/aurora-main/include/aurora/dvd.h
new file mode 100644
index 0000000..4a7f53b
--- /dev/null
+++ b/aurora-main/include/aurora/dvd.h
@@ -0,0 +1,27 @@
+#ifndef AURORA_DVD_H
+#define AURORA_DVD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+/**
+ * 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
diff --git a/aurora-main/include/aurora/event.h b/aurora-main/include/aurora/event.h
new file mode 100644
index 0000000..46ebf40
--- /dev/null
+++ b/aurora-main/include/aurora/event.h
@@ -0,0 +1,44 @@
+#ifndef AURORA_EVENT_H
+#define AURORA_EVENT_H
+
+#include "aurora.h"
+
+#include
+#include
+
+#ifdef __cplusplus
+#include
+
+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
diff --git a/aurora-main/include/aurora/gfx.h b/aurora-main/include/aurora/gfx.h
new file mode 100644
index 0000000..f58252f
--- /dev/null
+++ b/aurora-main/include/aurora/gfx.h
@@ -0,0 +1,97 @@
+#ifndef AURORA_GFX_H
+#define AURORA_GFX_H
+
+#ifdef __cplusplus
+#include
+#include
+
+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
diff --git a/aurora-main/include/aurora/imgui.h b/aurora-main/include/aurora/imgui.h
new file mode 100644
index 0000000..77eba9a
--- /dev/null
+++ b/aurora-main/include/aurora/imgui.h
@@ -0,0 +1,20 @@
+#ifndef AURORA_IMGUI_H
+#define AURORA_IMGUI_H
+
+#include
+
+#ifdef __cplusplus
+#include
+
+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
diff --git a/aurora-main/include/aurora/imgui_config.h b/aurora-main/include/aurora/imgui_config.h
new file mode 100644
index 0000000..3e62e59
--- /dev/null
+++ b/aurora-main/include/aurora/imgui_config.h
@@ -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);
diff --git a/aurora-main/include/aurora/main.h b/aurora-main/include/aurora/main.h
new file mode 100644
index 0000000..68ee67c
--- /dev/null
+++ b/aurora-main/include/aurora/main.h
@@ -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
diff --git a/aurora-main/include/aurora/math.hpp b/aurora-main/include/aurora/math.hpp
new file mode 100644
index 0000000..cb15cf1
--- /dev/null
+++ b/aurora-main/include/aurora/math.hpp
@@ -0,0 +1,254 @@
+#pragma once
+
+#include
+#include
+#include
+
+#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
+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
+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
+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 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
+ [[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