From 7471d8a200dedb4d44990eb67e6e3dde13633bd2 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:12:00 +0100 Subject: [PATCH 01/33] yay xbox --- .github/workflows/build-xboxone.yml | 83 +++++++++++++++++++++++++++++ .github/workflows/build.yml | 3 ++ CMakeLists.txt | 40 +++++++++++--- src/xboxone/main.c | 44 +++++++++++++++ 4 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/build-xboxone.yml create mode 100644 src/xboxone/main.c diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml new file mode 100644 index 000000000..e7568d2d5 --- /dev/null +++ b/.github/workflows/build-xboxone.yml @@ -0,0 +1,83 @@ +name: Xbox One builds + +on: + workflow_call: + +jobs: + build-xboxone: + name: Build (Xbox One) + runs-on: windows-2022 + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Install GDK + shell: pwsh + run: | + winget install Microsoft.Gaming.GDK ` + --accept-package-agreements ` + --accept-source-agreements ` + --silent + + - name: Install Ninja + uses: seanmiddleditch/gha-setup-ninja@v5 + + - name: Set up MSVC + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: Checkout SDL3 + uses: actions/checkout@v7 + with: + repository: libsdl-org/SDL + ref: release-3.2.10 + path: vendor/SDL3 + + - name: Configure SDL3 + shell: pwsh + run: | + cmake -S "$env:GITHUB_WORKSPACE/vendor/SDL3" ` + -B "$env:GITHUB_WORKSPACE/vendor/SDL3/build" ` + -G Ninja ` + -DCMAKE_BUILD_TYPE=Release ` + -DSDL_SHARED=OFF ` + -DSDL_STATIC=ON ` + -DSDL_TESTS=OFF ` + -DSDL_INSTALL=ON ` + -DSDL_GDK=ON ` + -DCMAKE_INSTALL_PREFIX="$env:GITHUB_WORKSPACE/vendor/SDL3/install" + + - name: Build SDL3 + shell: pwsh + run: | + cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" + + - name: Install SDL3 + shell: pwsh + run: | + cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL3/build" + + - name: Configure Butterscotch + shell: pwsh + run: | + cmake -S "$env:GITHUB_WORKSPACE" ` + -B "$env:GITHUB_WORKSPACE/build" ` + -G Ninja ` + -DPLATFORM=xboxone ` + -DBACKEND=sdl3 ` + -DSDL3_DIR="$env:GITHUB_WORKSPACE/vendor/SDL3/install" ` + -DCMAKE_BUILD_TYPE=Release ` + -DWERROR=ON + + - name: Build Butterscotch + shell: pwsh + run: | + cmake --build "$env:GITHUB_WORKSPACE/build" + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: butterscotch-xboxone + path: build/**/* \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8df58084b..5c9a87fe5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,5 +25,8 @@ jobs: Other: uses: ./.github/workflows/build-other.yml + XboxOne: + uses: ./.github/workflows/build-xboxone.yml + Compilers: uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8de80dba2..9b9b89557 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,15 @@ endif() set(BACKEND "sdl2") +elseif(PLATFORM STREQUAL "xboxone") +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(NOT DEFINED ENV{GDK} AND NOT DEFINED ENV{GDKX}) + message(FATAL_ERROR "Please define GDK or GDKX to point to your Xbox GDK installation before configuring PLATFORM=xboxone!") + endif() +endif() + +set(BACKEND "sdl3") + endif() project(butterscotch C) @@ -260,7 +269,7 @@ if(ENABLE_VM_EXCEPTIONS_LOGS) add_compile_definitions(ENABLE_VM_EXCEPTIONS_LOGS) endif() -if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") +if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch" OR PLATFORM STREQUAL "xboxone") if(PLATFORM STREQUAL "vita") # Normally, __VITA__ should already be defined, but for some reason, # in my case, this didn't really work... so just in case, when we're @@ -275,6 +284,13 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi elseif(PLATFORM STREQUAL "switch") add_compile_definitions(PLATFORM_SWITCH) + set(VM_GML_PROFILER_DEFAULT OFF) + set(VM_TRACING_DEFAULT OFF) + set(VM_OPCODE_PROFILER_DEFAULT OFF) + set(VM_STUB_LOGS_DEFAULT OFF) + elseif(PLATFORM STREQUAL "xboxone") + add_compile_definitions(PLATFORM_XBOXONE) + set(VM_GML_PROFILER_DEFAULT OFF) set(VM_TRACING_DEFAULT OFF) set(VM_OPCODE_PROFILER_DEFAULT OFF) @@ -400,11 +416,23 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi elseif(BACKEND STREQUAL "sdl3") add_compile_definitions(USE_SDL3) - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL3 REQUIRED sdl3) - target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + if(MSVC) + if(DEFINED SDL3_DIR) + find_package(SDL3 CONFIG REQUIRED) + set(BACKEND_LIBRARIES SDL3::SDL3) + elseif(DEFINED ENV{SDL3_DIR}) + find_package(SDL3 CONFIG REQUIRED) + set(BACKEND_LIBRARIES SDL3::SDL3) + else() + message(FATAL_ERROR "For Windows/GDK builds, set SDL3_DIR to the SDL3 CMake package directory before configuring with BACKEND=sdl3.") + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + endif() elseif(BACKEND STREQUAL "appkit") add_compile_definitions(USE_APPKIT) target_compile_definitions(butterscotch PRIVATE GL_SILENCE_DEPRECATION) diff --git a/src/xboxone/main.c b/src/xboxone/main.c new file mode 100644 index 000000000..4d6010484 --- /dev/null +++ b/src/xboxone/main.c @@ -0,0 +1,44 @@ +#include + +/* For SDL_main */ +#if defined(USE_SDL1) +#include +#elif defined(USE_SDL2) +#include +#elif defined(USE_SDL3) +#include +#endif + +int main(int argc, char* argv[]) { + (void)argc; + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CommandLineArgs args = {0}; + + args.exitAtFrame = -1; +#ifdef ENABLE_VM_TRACING + args.traceBytecodeAfterFrame = 0; +#endif + args.speedMultiplier = 1.0; + args.fastForwardSpeed = 0.0; + args.osType = OS_XBOXONE; + args.profilerFramesBetween = 0; + args.loadType = DATAWINLOADTYPE_LOAD_PER_CHUNK; + args.lazyRooms = true; + args.lazyTextures = true; + args.lazyAudio = true; +#if defined(ENABLE_MODERN_GL) + args.renderer = MODERN_GL; +#elif defined(ENABLE_LEGACY_GL) + args.renderer = LEGACY_GL; +#else + args.renderer = SOFTWARE; +#endif + args.dataWinPath = "data.win"; + args.saveFolder = "."; + + int ret = loop(args, argv[0]); + freeCommandLineArgs(&args); + return ret; +} From 3146adc4c6793938f29f1eff1f14d7999bd40401 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:18:08 +0100 Subject: [PATCH 02/33] where is winget --- .github/workflows/build-xboxone.yml | 64 +++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index e7568d2d5..849f6a459 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -15,13 +15,63 @@ jobs: - name: Install GDK shell: pwsh run: | - winget install Microsoft.Gaming.GDK ` + $ErrorActionPreference = "Stop" + + # GitHub's Windows images may have App Installer/WinGet + # installed without winget.exe being on PATH. + $winget = Get-ChildItem ` + "$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe", ` + "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*__8wekyb3d8bbwe\winget.exe" ` + -ErrorAction SilentlyContinue | + Select-Object -First 1 -ExpandProperty FullName + + if (-not $winget) { + Write-Host "winget.exe was not found." + Write-Host "WindowsApps contents:" + Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WindowsApps" ` + -ErrorAction SilentlyContinue | + Where-Object { $_.Name -like "*winget*" } + + throw "WinGet is not available on this GitHub Actions runner." + } + + Write-Host "Using WinGet: $winget" + + & $winget install Microsoft.Gaming.GDK ` --accept-package-agreements ` --accept-source-agreements ` - --silent + --silent ` + --disable-interactivity + + if ($LASTEXITCODE -ne 0) { + throw "GDK installation failed with exit code $LASTEXITCODE" + } + + - name: Verify GDK + shell: pwsh + run: | + $gdkPaths = @( + "C:\Program Files (x86)\Microsoft GDK", + "C:\Program Files\Microsoft GDK" + ) + + foreach ($path in $gdkPaths) { + if (Test-Path $path) { + Write-Host "GDK found at: $path" + Get-ChildItem $path -Directory | Select-Object Name + } + } + + $makepkg = Get-ChildItem ` + "C:\Program Files (x86)\Microsoft GDK" ` + -Recurse ` + -Filter "makepkg.exe" ` + -ErrorAction SilentlyContinue | + Select-Object -First 1 -ExpandProperty FullName - - name: Install Ninja - uses: seanmiddleditch/gha-setup-ninja@v5 + if ($makepkg) { + Write-Host "makepkg.exe: $makepkg" + } - name: Set up MSVC uses: ilammy/msvc-dev-cmd@v1 @@ -52,7 +102,7 @@ jobs: - name: Build SDL3 shell: pwsh run: | - cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" + cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" --parallel - name: Install SDL3 shell: pwsh @@ -74,10 +124,10 @@ jobs: - name: Build Butterscotch shell: pwsh run: | - cmake --build "$env:GITHUB_WORKSPACE/build" + cmake --build "$env:GITHUB_WORKSPACE/build" --parallel - name: Upload artifact uses: actions/upload-artifact@v7 with: name: butterscotch-xboxone - path: build/**/* \ No newline at end of file + path: build/** \ No newline at end of file From 4eeb58149df39619e922d639998a200b6e603d31 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:20:37 +0100 Subject: [PATCH 03/33] hmm --- .github/workflows/build-xboxone.yml | 86 +++++++++++++++++++---------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 849f6a459..bd22cf142 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -17,62 +17,84 @@ jobs: run: | $ErrorActionPreference = "Stop" - # GitHub's Windows images may have App Installer/WinGet - # installed without winget.exe being on PATH. - $winget = Get-ChildItem ` - "$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe", ` - "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*__8wekyb3d8bbwe\winget.exe" ` - -ErrorAction SilentlyContinue | - Select-Object -First 1 -ExpandProperty FullName - - if (-not $winget) { - Write-Host "winget.exe was not found." - Write-Host "WindowsApps contents:" - Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WindowsApps" ` - -ErrorAction SilentlyContinue | - Where-Object { $_.Name -like "*winget*" } + $gdkInstaller = "$env:RUNNER_TEMP\gdk.exe" - throw "WinGet is not available on this GitHub Actions runner." - } + Write-Host "Downloading GDK..." + Invoke-WebRequest ` + -Uri "https://aka.ms/gdkdl" ` + -OutFile $gdkInstaller - Write-Host "Using WinGet: $winget" + Write-Host "Downloaded GDK installer:" + Get-Item $gdkInstaller | Format-List FullName, Length - & $winget install Microsoft.Gaming.GDK ` - --accept-package-agreements ` - --accept-source-agreements ` - --silent ` - --disable-interactivity + Write-Host "Installing GDK..." + $process = Start-Process ` + -FilePath $gdkInstaller ` + -ArgumentList "/quiet", "/norestart" ` + -Wait ` + -PassThru - if ($LASTEXITCODE -ne 0) { - throw "GDK installation failed with exit code $LASTEXITCODE" + if ($process.ExitCode -ne 0) { + throw "GDK installer failed with exit code $($process.ExitCode)" } + Write-Host "GDK installation completed." + - name: Verify GDK shell: pwsh run: | + $ErrorActionPreference = "Stop" + $gdkPaths = @( "C:\Program Files (x86)\Microsoft GDK", "C:\Program Files\Microsoft GDK" ) + $gdkRoot = $null + foreach ($path in $gdkPaths) { if (Test-Path $path) { Write-Host "GDK found at: $path" - Get-ChildItem $path -Directory | Select-Object Name + $gdkRoot = $path + break } } + if (-not $gdkRoot) { + throw "Microsoft GDK was not found after installation." + } + + Write-Host "GDK contents:" + Get-ChildItem $gdkRoot + $makepkg = Get-ChildItem ` - "C:\Program Files (x86)\Microsoft GDK" ` + $gdkRoot ` -Recurse ` -Filter "makepkg.exe" ` -ErrorAction SilentlyContinue | - Select-Object -First 1 -ExpandProperty FullName + Select-Object -First 1 - if ($makepkg) { - Write-Host "makepkg.exe: $makepkg" + if (-not $makepkg) { + throw "makepkg.exe was not found in the GDK installation." } + Write-Host "Found makepkg:" + Write-Host $makepkg.FullName + + # Make GDK tools available to subsequent steps. + Add-Content $env:GITHUB_PATH $makepkg.Directory.FullName + + - name: Check GDK tools + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + + Write-Host "makepkg:" + Get-Command makepkg.exe + + - name: Install Ninja + uses: seanmiddleditch/gha-setup-ninja@v5 + - name: Set up MSVC uses: ilammy/msvc-dev-cmd@v1 with: @@ -126,6 +148,12 @@ jobs: run: | cmake --build "$env:GITHUB_WORKSPACE/build" --parallel + - name: Show build output + shell: pwsh + run: | + Write-Host "Build directory:" + Get-ChildItem "$env:GITHUB_WORKSPACE/build" -Recurse + - name: Upload artifact uses: actions/upload-artifact@v7 with: From 55b0455059d77a95e94ce29b57264dab70ce1e54 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:33:27 +0100 Subject: [PATCH 04/33] install winget --- .github/workflows/build-xboxone.yml | 95 +++-------------------------- 1 file changed, 10 insertions(+), 85 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index bd22cf142..b050c01ad 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -12,85 +12,16 @@ jobs: - name: Checkout uses: actions/checkout@v7 - - name: Install GDK - shell: pwsh - run: | - $ErrorActionPreference = "Stop" - - $gdkInstaller = "$env:RUNNER_TEMP\gdk.exe" - - Write-Host "Downloading GDK..." - Invoke-WebRequest ` - -Uri "https://aka.ms/gdkdl" ` - -OutFile $gdkInstaller - - Write-Host "Downloaded GDK installer:" - Get-Item $gdkInstaller | Format-List FullName, Length - - Write-Host "Installing GDK..." - $process = Start-Process ` - -FilePath $gdkInstaller ` - -ArgumentList "/quiet", "/norestart" ` - -Wait ` - -PassThru - - if ($process.ExitCode -ne 0) { - throw "GDK installer failed with exit code $($process.ExitCode)" - } - - Write-Host "GDK installation completed." - - - name: Verify GDK - shell: pwsh - run: | - $ErrorActionPreference = "Stop" - - $gdkPaths = @( - "C:\Program Files (x86)\Microsoft GDK", - "C:\Program Files\Microsoft GDK" - ) + - name: Install winget + uses: Cyberboss/install-winget@v1 - $gdkRoot = $null - - foreach ($path in $gdkPaths) { - if (Test-Path $path) { - Write-Host "GDK found at: $path" - $gdkRoot = $path - break - } - } - - if (-not $gdkRoot) { - throw "Microsoft GDK was not found after installation." - } - - Write-Host "GDK contents:" - Get-ChildItem $gdkRoot - - $makepkg = Get-ChildItem ` - $gdkRoot ` - -Recurse ` - -Filter "makepkg.exe" ` - -ErrorAction SilentlyContinue | - Select-Object -First 1 - - if (-not $makepkg) { - throw "makepkg.exe was not found in the GDK installation." - } - - Write-Host "Found makepkg:" - Write-Host $makepkg.FullName - - # Make GDK tools available to subsequent steps. - Add-Content $env:GITHUB_PATH $makepkg.Directory.FullName - - - name: Check GDK tools + - name: Install GDK shell: pwsh run: | - $ErrorActionPreference = "Stop" - - Write-Host "makepkg:" - Get-Command makepkg.exe + winget install Microsoft.Gaming.GDK ` + --accept-package-agreements ` + --accept-source-agreements ` + --silent - name: Install Ninja uses: seanmiddleditch/gha-setup-ninja@v5 @@ -124,7 +55,7 @@ jobs: - name: Build SDL3 shell: pwsh run: | - cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" --parallel + cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" - name: Install SDL3 shell: pwsh @@ -146,16 +77,10 @@ jobs: - name: Build Butterscotch shell: pwsh run: | - cmake --build "$env:GITHUB_WORKSPACE/build" --parallel - - - name: Show build output - shell: pwsh - run: | - Write-Host "Build directory:" - Get-ChildItem "$env:GITHUB_WORKSPACE/build" -Recurse + cmake --build "$env:GITHUB_WORKSPACE/build" - name: Upload artifact uses: actions/upload-artifact@v7 with: name: butterscotch-xboxone - path: build/** \ No newline at end of file + path: build/**/* \ No newline at end of file From 5e4187b8a5a41899ab28bf1a3b1a26a7592941f1 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:33:49 +0100 Subject: [PATCH 05/33] use windows 25 --- .github/workflows/build-xboxone.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index b050c01ad..992a95201 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -6,15 +6,12 @@ on: jobs: build-xboxone: name: Build (Xbox One) - runs-on: windows-2022 + runs-on: windows-2025 steps: - name: Checkout uses: actions/checkout@v7 - - name: Install winget - uses: Cyberboss/install-winget@v1 - - name: Install GDK shell: pwsh run: | From 9a64487565a4a23694efed703ab65eeda19fa80d Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:42:41 +0100 Subject: [PATCH 06/33] find gdk --- .github/workflows/build-xboxone.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 992a95201..2d18959f3 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -12,7 +12,17 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Cache GDK + id: cache-gdk + uses: actions/cache@v4 + with: + path: | + C:\Program Files\Microsoft GDK + C:\Program Files (x86)\Microsoft GDK + key: gdk-${{ runner.os }}-x64 + - name: Install GDK + if: steps.cache-gdk.outputs.cache-hit != 'true' shell: pwsh run: | winget install Microsoft.Gaming.GDK ` @@ -20,6 +30,21 @@ jobs: --accept-source-agreements ` --silent + - name: Resolve GDK path + shell: pwsh + run: | + $gdkRoot = @( + "$env:ProgramFiles\Microsoft GDK", + "$env:ProgramFiles(x86)\Microsoft GDK" + ) | Where-Object { Test-Path $_ } | Select-Object -First 1 + + if (-not $gdkRoot) { + throw "Microsoft GDK was not found under Program Files after installation." + } + + "GDK=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append + "GDKX=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Install Ninja uses: seanmiddleditch/gha-setup-ninja@v5 @@ -67,6 +92,8 @@ jobs: -G Ninja ` -DPLATFORM=xboxone ` -DBACKEND=sdl3 ` + -DGDK="$env:GDK" ` + -DGDKX="$env:GDKX" ` -DSDL3_DIR="$env:GITHUB_WORKSPACE/vendor/SDL3/install" ` -DCMAKE_BUILD_TYPE=Release ` -DWERROR=ON From 50ebd56987822ca83f9e5a1084944a8a1a28c4e3 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:47:43 +0100 Subject: [PATCH 07/33] fix path --- .github/workflows/build-xboxone.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 2d18959f3..7c22f61d9 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -17,7 +17,6 @@ jobs: uses: actions/cache@v4 with: path: | - C:\Program Files\Microsoft GDK C:\Program Files (x86)\Microsoft GDK key: gdk-${{ runner.os }}-x64 @@ -34,7 +33,6 @@ jobs: shell: pwsh run: | $gdkRoot = @( - "$env:ProgramFiles\Microsoft GDK", "$env:ProgramFiles(x86)\Microsoft GDK" ) | Where-Object { Test-Path $_ } | Select-Object -First 1 From d606d528c2753c7a780fc6392f72bf8bce249650 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:51:56 +0100 Subject: [PATCH 08/33] zzz --- .github/workflows/build-xboxone.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 7c22f61d9..0b7fe07b0 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -17,6 +17,7 @@ jobs: uses: actions/cache@v4 with: path: | + C:\Program Files\Microsoft GDK C:\Program Files (x86)\Microsoft GDK key: gdk-${{ runner.os }}-x64 @@ -33,8 +34,22 @@ jobs: shell: pwsh run: | $gdkRoot = @( - "$env:ProgramFiles(x86)\Microsoft GDK" - ) | Where-Object { Test-Path $_ } | Select-Object -First 1 + "${env:ProgramFiles(x86)}\Microsoft GDK", + "${env:ProgramFiles}\Microsoft GDK" + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkRoot) { + $gdkRoot = @( + (Get-ChildItem -Path "${env:ProgramFiles(x86)}" -Directory -Filter "Microsoft GDK" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), + (Get-ChildItem -Path "${env:ProgramFiles}" -Directory -Filter "Microsoft GDK" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), + (Get-ChildItem -Path "${env:ProgramFiles(x86)}" -Recurse -Directory -Filter "GDK*" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), + (Get-ChildItem -Path "${env:ProgramFiles}" -Recurse -Directory -Filter "GDK*" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName) + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + } if (-not $gdkRoot) { throw "Microsoft GDK was not found under Program Files after installation." From ee86bf88e46a04f70098dfcf1671a6557cc93f77 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:55:07 +0100 Subject: [PATCH 09/33] random bullshit go --- .github/workflows/build-xboxone.yml | 68 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 0b7fe07b0..81e0a4a27 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -16,43 +16,65 @@ jobs: id: cache-gdk uses: actions/cache@v4 with: - path: | - C:\Program Files\Microsoft GDK - C:\Program Files (x86)\Microsoft GDK + path: ${{ runner.temp }}\gdk-cache key: gdk-${{ runner.os }}-x64 - - name: Install GDK - if: steps.cache-gdk.outputs.cache-hit != 'true' + - name: Install or restore GDK shell: pwsh run: | - winget install Microsoft.Gaming.GDK ` - --accept-package-agreements ` - --accept-source-agreements ` - --silent + $cacheRoot = Join-Path '${{ runner.temp }}' 'gdk-cache' + $installRoots = @( + "${env:ProgramFiles}\Microsoft GDK", + "${env:ProgramFiles(x86)}\Microsoft GDK" + ) - - name: Resolve GDK path - shell: pwsh - run: | - $gdkRoot = @( - "${env:ProgramFiles(x86)}\Microsoft GDK", - "${env:ProgramFiles}\Microsoft GDK" - ) | + $gdkRoot = $installRoots | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 - if (-not $gdkRoot) { - $gdkRoot = @( - (Get-ChildItem -Path "${env:ProgramFiles(x86)}" -Directory -Filter "Microsoft GDK" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), - (Get-ChildItem -Path "${env:ProgramFiles}" -Directory -Filter "Microsoft GDK" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), - (Get-ChildItem -Path "${env:ProgramFiles(x86)}" -Recurse -Directory -Filter "GDK*" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName), - (Get-ChildItem -Path "${env:ProgramFiles}" -Recurse -Directory -Filter "GDK*" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName) + if ("${{ steps.cache-gdk.outputs.cache-hit }}" -eq "true") { + $cached = @( + (Join-Path $cacheRoot 'Microsoft GDK'), + (Join-Path $cacheRoot 'MicrosoftGDK'), + $cacheRoot ) | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 + + if (-not $cached) { + throw "Cached GDK directory was not found in $cacheRoot." + } + + if (-not $gdkRoot) { + $gdkRoot = "${env:ProgramFiles}\Microsoft GDK" + } + + if (Test-Path $gdkRoot) { + Remove-Item $gdkRoot -Recurse -Force + } + + Copy-Item $cached $gdkRoot -Recurse -Force + } + else { + winget install Microsoft.Gaming.GDK ` + --accept-package-agreements ` + --accept-source-agreements ` + --silent + + $gdkRoot = $installRoots | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkRoot) { + throw "Microsoft GDK was not found under Program Files after installation." + } + + New-Item -ItemType Directory -Force -Path $cacheRoot | Out-Null + Copy-Item $gdkRoot (Join-Path $cacheRoot 'Microsoft GDK') -Recurse -Force } if (-not $gdkRoot) { - throw "Microsoft GDK was not found under Program Files after installation." + throw "Microsoft GDK was not found under Program Files after restore." } "GDK=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append From 6fb47d5ff1f55cde9cc8bec0e256d9402bf46571 Mon Sep 17 00:00:00 2001 From: emiyl Date: Fri, 11 Sep 2026 23:59:08 +0100 Subject: [PATCH 10/33] use sdl2 --- .github/workflows/build-xboxone.yml | 46 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 81e0a4a27..642fd3404 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -88,48 +88,52 @@ jobs: with: arch: x64 - - name: Checkout SDL3 + - name: Cache SDL2 build + id: cache-sdl2 + uses: actions/cache@v6 + with: + path: ${{ github.workspace }}/vendor/SDL2/install + key: sdl2-xboxone-${{ runner.os }}-2.32.10-rev2 + + - name: Checkout SDL2 + if: steps.cache-sdl2.outputs.cache-hit != 'true' uses: actions/checkout@v7 with: repository: libsdl-org/SDL - ref: release-3.2.10 - path: vendor/SDL3 + ref: release-2.32.10 + path: vendor/SDL2 - - name: Configure SDL3 + - name: Build SDL2 from source + if: steps.cache-sdl2.outputs.cache-hit != 'true' shell: pwsh run: | - cmake -S "$env:GITHUB_WORKSPACE/vendor/SDL3" ` - -B "$env:GITHUB_WORKSPACE/vendor/SDL3/build" ` + cmake -S "$env:GITHUB_WORKSPACE/vendor/SDL2" ` + -B "$env:GITHUB_WORKSPACE/vendor/SDL2/build" ` -G Ninja ` -DCMAKE_BUILD_TYPE=Release ` + -DCMAKE_INSTALL_PREFIX="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` -DSDL_SHARED=OFF ` -DSDL_STATIC=ON ` -DSDL_TESTS=OFF ` - -DSDL_INSTALL=ON ` - -DSDL_GDK=ON ` - -DCMAKE_INSTALL_PREFIX="$env:GITHUB_WORKSPACE/vendor/SDL3/install" - - - name: Build SDL3 - shell: pwsh - run: | - cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL3/build" - - - name: Install SDL3 - shell: pwsh - run: | - cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL3/build" + -DSDL_GDK=ON + cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL2/build" + cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL2/build" - name: Configure Butterscotch + env: + PKG_CONFIG_PATH: "$env:GITHUB_WORKSPACE/vendor/SDL2/install/lib/pkgconfig" + PKG_CONFIG_LIBDIR: "$env:GITHUB_WORKSPACE/vendor/SDL2/install/lib/pkgconfig" + PKG_CONFIG_SYSROOT_DIR: "$env:GITHUB_WORKSPACE/vendor/SDL2/install" shell: pwsh run: | cmake -S "$env:GITHUB_WORKSPACE" ` -B "$env:GITHUB_WORKSPACE/build" ` -G Ninja ` -DPLATFORM=xboxone ` - -DBACKEND=sdl3 ` + -DBACKEND=sdl2 ` -DGDK="$env:GDK" ` -DGDKX="$env:GDKX" ` - -DSDL3_DIR="$env:GITHUB_WORKSPACE/vendor/SDL3/install" ` + -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` -DCMAKE_BUILD_TYPE=Release ` -DWERROR=ON From c763c8e2a9ef269f0017d86d8103241ae0a3d675 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:00:51 +0100 Subject: [PATCH 11/33] revert sdl3 --- CMakeLists.txt | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b9b89557..5084b6df0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -415,24 +415,12 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) elseif(BACKEND STREQUAL "sdl3") add_compile_definitions(USE_SDL3) - - if(MSVC) - if(DEFINED SDL3_DIR) - find_package(SDL3 CONFIG REQUIRED) - set(BACKEND_LIBRARIES SDL3::SDL3) - elseif(DEFINED ENV{SDL3_DIR}) - find_package(SDL3 CONFIG REQUIRED) - set(BACKEND_LIBRARIES SDL3::SDL3) - else() - message(FATAL_ERROR "For Windows/GDK builds, set SDL3_DIR to the SDL3 CMake package directory before configuring with BACKEND=sdl3.") - endif() - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL3 REQUIRED sdl3) - target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) - endif() + + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) elseif(BACKEND STREQUAL "appkit") add_compile_definitions(USE_APPKIT) target_compile_definitions(butterscotch PRIVATE GL_SILENCE_DEPRECATION) From 3d91c92d2207b789e615a07dc682393e33bc57d4 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:06:06 +0100 Subject: [PATCH 12/33] add sdl2 dir --- .github/workflows/build-xboxone.yml | 5 +---- CMakeLists.txt | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 642fd3404..9572f0f84 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -120,10 +120,6 @@ jobs: cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL2/build" - name: Configure Butterscotch - env: - PKG_CONFIG_PATH: "$env:GITHUB_WORKSPACE/vendor/SDL2/install/lib/pkgconfig" - PKG_CONFIG_LIBDIR: "$env:GITHUB_WORKSPACE/vendor/SDL2/install/lib/pkgconfig" - PKG_CONFIG_SYSROOT_DIR: "$env:GITHUB_WORKSPACE/vendor/SDL2/install" shell: pwsh run: | cmake -S "$env:GITHUB_WORKSPACE" ` @@ -133,6 +129,7 @@ jobs: -DBACKEND=sdl2 ` -DGDK="$env:GDK" ` -DGDKX="$env:GDKX" ` + -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` -DCMAKE_BUILD_TYPE=Release ` -DWERROR=ON diff --git a/CMakeLists.txt b/CMakeLists.txt index 5084b6df0..7617c0728 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -408,14 +408,27 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi elseif(BACKEND STREQUAL "sdl2") add_compile_definitions(USE_SDL2) - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL2 REQUIRED sdl2) - target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) + if(MSVC) + if(DEFINED SDL2_DIR OR DEFINED ENV{SDL2_DIR}) + find_package(SDL2 CONFIG REQUIRED) + set(BACKEND_LIBRARIES SDL2::SDL2) + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 REQUIRED sdl2) + target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 REQUIRED sdl2) + target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) + endif() elseif(BACKEND STREQUAL "sdl3") add_compile_definitions(USE_SDL3) - + find_package(PkgConfig REQUIRED) pkg_check_modules(SDL3 REQUIRED sdl3) target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) From cbb010c7959febb5f689531120c03edc00f2b7e2 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:07:34 +0100 Subject: [PATCH 13/33] add sdl3_dir --- CMakeLists.txt | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7617c0728..2e8c1622f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,11 +429,24 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi elseif(BACKEND STREQUAL "sdl3") add_compile_definitions(USE_SDL3) - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL3 REQUIRED sdl3) - target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + if(MSVC) + if(DEFINED SDL3_DIR OR DEFINED ENV{SDL3_DIR}) + find_package(SDL3 CONFIG REQUIRED) + set(BACKEND_LIBRARIES SDL3::SDL3) + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + endif() elseif(BACKEND STREQUAL "appkit") add_compile_definitions(USE_APPKIT) target_compile_definitions(butterscotch PRIVATE GL_SILENCE_DEPRECATION) From cdd2038d02e030341010d4e8cfa31da53d1398ab Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:07:39 +0100 Subject: [PATCH 14/33] temporarily remove other runners --- .github/workflows/build.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c9a87fe5..9d2893834 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,26 +7,26 @@ on: branches: [main] jobs: - Unix: - uses: ./.github/workflows/build-desktop.yml + # Unix: + # uses: ./.github/workflows/build-desktop.yml - Windows: - uses: ./.github/workflows/build-windows.yml + # Windows: + # uses: ./.github/workflows/build-windows.yml - macOS: - uses: ./.github/workflows/build-macos.yml + # macOS: + # uses: ./.github/workflows/build-macos.yml - Haiku: - uses: ./.github/workflows/build-haiku.yml + # Haiku: + # uses: ./.github/workflows/build-haiku.yml - Consoles: - uses: ./.github/workflows/build-console.yml + # Consoles: + # uses: ./.github/workflows/build-console.yml - Other: - uses: ./.github/workflows/build-other.yml + # Other: + # uses: ./.github/workflows/build-other.yml XboxOne: uses: ./.github/workflows/build-xboxone.yml - Compilers: - uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file + # Compilers: + # uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file From cdcc92487ce729c5fb09ee0fcffbb7918837704c Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:14:04 +0100 Subject: [PATCH 15/33] removing build so it can cache --- .github/workflows/build-xboxone.yml | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 9572f0f84..89961a357 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -119,28 +119,28 @@ jobs: cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL2/build" cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL2/build" - - name: Configure Butterscotch - shell: pwsh - run: | - cmake -S "$env:GITHUB_WORKSPACE" ` - -B "$env:GITHUB_WORKSPACE/build" ` - -G Ninja ` - -DPLATFORM=xboxone ` - -DBACKEND=sdl2 ` - -DGDK="$env:GDK" ` - -DGDKX="$env:GDKX" ` - -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - -DCMAKE_BUILD_TYPE=Release ` - -DWERROR=ON - - - name: Build Butterscotch - shell: pwsh - run: | - cmake --build "$env:GITHUB_WORKSPACE/build" - - - name: Upload artifact - uses: actions/upload-artifact@v7 - with: - name: butterscotch-xboxone - path: build/**/* \ No newline at end of file + # - name: Configure Butterscotch + # shell: pwsh + # run: | + # cmake -S "$env:GITHUB_WORKSPACE" ` + # -B "$env:GITHUB_WORKSPACE/build" ` + # -G Ninja ` + # -DPLATFORM=xboxone ` + # -DBACKEND=sdl2 ` + # -DGDK="$env:GDK" ` + # -DGDKX="$env:GDKX" ` + # -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` + # -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` + # -DCMAKE_BUILD_TYPE=Release ` + # -DWERROR=ON + + # - name: Build Butterscotch + # shell: pwsh + # run: | + # cmake --build "$env:GITHUB_WORKSPACE/build" + + # - name: Upload artifact + # uses: actions/upload-artifact@v7 + # with: + # name: butterscotch-xboxone + # path: build/**/* \ No newline at end of file From 634aa6bd90b6002706ca9ed1d96442c152fb2e69 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:39:07 +0100 Subject: [PATCH 16/33] add the build back --- .github/workflows/build-xboxone.yml | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 89961a357..9572f0f84 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -119,28 +119,28 @@ jobs: cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL2/build" cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL2/build" - # - name: Configure Butterscotch - # shell: pwsh - # run: | - # cmake -S "$env:GITHUB_WORKSPACE" ` - # -B "$env:GITHUB_WORKSPACE/build" ` - # -G Ninja ` - # -DPLATFORM=xboxone ` - # -DBACKEND=sdl2 ` - # -DGDK="$env:GDK" ` - # -DGDKX="$env:GDKX" ` - # -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - # -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - # -DCMAKE_BUILD_TYPE=Release ` - # -DWERROR=ON - - # - name: Build Butterscotch - # shell: pwsh - # run: | - # cmake --build "$env:GITHUB_WORKSPACE/build" - - # - name: Upload artifact - # uses: actions/upload-artifact@v7 - # with: - # name: butterscotch-xboxone - # path: build/**/* \ No newline at end of file + - name: Configure Butterscotch + shell: pwsh + run: | + cmake -S "$env:GITHUB_WORKSPACE" ` + -B "$env:GITHUB_WORKSPACE/build" ` + -G Ninja ` + -DPLATFORM=xboxone ` + -DBACKEND=sdl2 ` + -DGDK="$env:GDK" ` + -DGDKX="$env:GDKX" ` + -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` + -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` + -DCMAKE_BUILD_TYPE=Release ` + -DWERROR=ON + + - name: Build Butterscotch + shell: pwsh + run: | + cmake --build "$env:GITHUB_WORKSPACE/build" + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: butterscotch-xboxone + path: build/**/* \ No newline at end of file From 5859dd1d62040fd2734e5ae3cf6fb95d749eb37f Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:43:17 +0100 Subject: [PATCH 17/33] don't force xbox to be sdl3 --- CMakeLists.txt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e8c1622f..c344d2a81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,16 +27,13 @@ endif() set(BACKEND "sdl2") elseif(PLATFORM STREQUAL "xboxone") -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - if(NOT DEFINED ENV{GDK} AND NOT DEFINED ENV{GDKX}) - message(FATAL_ERROR "Please define GDK or GDKX to point to your Xbox GDK installation before configuring PLATFORM=xboxone!") + if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(NOT DEFINED ENV{GDK} AND NOT DEFINED ENV{GDKX}) + message(FATAL_ERROR "Please define GDK or GDKX to point to your Xbox GDK installation before configuring PLATFORM=xboxone!") + endif() endif() endif() -set(BACKEND "sdl3") - -endif() - project(butterscotch C) if (PLATFORM STREQUAL "vita") From 68d474c805db2c6bba66dc1b39fba0fccfa1ae9e Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:45:15 +0100 Subject: [PATCH 18/33] no_strings_h for msvc --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c344d2a81..57d439fc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,7 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) if (MSVC) target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/compat/getopt) + add_compile_definitions(NO_STRINGS_H) add_compile_definitions(NO_STRTOK_R) add_compile_definitions(NO_STRCASECMP) endif() From 8b387b640b96574a3cb1a7df514c202fae195121 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:48:07 +0100 Subject: [PATCH 19/33] no glad for xbone --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57d439fc5..b656cac20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,7 +351,7 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi target_include_directories(butterscotch PUBLIC vendor/stb/image) set(PLATFORM_LIBRARIES bzip2 stb_ds sha1 stb_vorbis) - if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") + if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch" AND NOT PLATFORM STREQUAL "xboxone") # GLAD add_library(glad STATIC vendor/glad/src/glad.c) target_include_directories(glad PUBLIC vendor/glad/include) From 3edd3a069114a32d800649c88f4f4818d006023e Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:50:19 +0100 Subject: [PATCH 20/33] actually just no -Wno-unused-but-set-variables for xbone --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b656cac20..b561659be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,11 +351,13 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi target_include_directories(butterscotch PUBLIC vendor/stb/image) set(PLATFORM_LIBRARIES bzip2 stb_ds sha1 stb_vorbis) - if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch" AND NOT PLATFORM STREQUAL "xboxone") + if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") # GLAD add_library(glad STATIC vendor/glad/src/glad.c) target_include_directories(glad PUBLIC vendor/glad/include) - target_compile_options(glad PRIVATE -Wno-unused-but-set-variable) + if(NOT PLATFORM STREQUAL "xboxone") + target_compile_options(glad PRIVATE -Wno-unused-but-set-variable) + endif() set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} glad) endif() if(NOT MSVC) From d83d935cfad3bbdc1035ebffc3600613a7dcb11e Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:52:02 +0100 Subject: [PATCH 21/33] only no_strings_h for xbone --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b561659be..001961cb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,7 +318,9 @@ if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "swi target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) if (MSVC) target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/compat/getopt) - add_compile_definitions(NO_STRINGS_H) + if (PLATFORM STREQUAL "xboxone") + add_compile_definitions(NO_STRINGS_H) + endif() add_compile_definitions(NO_STRTOK_R) add_compile_definitions(NO_STRCASECMP) endif() From 7c35226adddd80211c66485aeb57685ad07ccee5 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:54:43 +0100 Subject: [PATCH 22/33] add log --- src/xboxone/log.c | 22 ++++++++++++++++++++++ src/xboxone/stb_impl.c | 6 ++++++ 2 files changed, 28 insertions(+) create mode 100644 src/xboxone/log.c create mode 100644 src/xboxone/stb_impl.c diff --git a/src/xboxone/log.c b/src/xboxone/log.c new file mode 100644 index 000000000..b8c8673e3 --- /dev/null +++ b/src/xboxone/log.c @@ -0,0 +1,22 @@ +#include + +#include "log.h" + +void platformLog(const logType type, const char *format, va_list va) { + FILE *out = stderr; + switch (type) { + case LOG_TYPE_NORMAL: + out = stdout; + break; + case LOG_TYPE_WARNING: + fputs("Warning: ", out); + break; + case LOG_TYPE_ERROR: + fputs("Error: ", out); + break; + case LOG_TYPE_DEBUG: + fputs("Debug: ", out); + break; + } + vfprintf(out, format, va); +} diff --git a/src/xboxone/stb_impl.c b/src/xboxone/stb_impl.c new file mode 100644 index 000000000..873f3656b --- /dev/null +++ b/src/xboxone/stb_impl.c @@ -0,0 +1,6 @@ +#define STB_IMAGE_IMPLEMENTATION +#define STBI_NO_STDIO +#include "stb_image.h" + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" From 41241b671513c2e0bd1188f7d0472cfc13281e79 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 00:59:35 +0100 Subject: [PATCH 23/33] make sure to activate gdk --- .github/workflows/build-xboxone.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 9572f0f84..b43791430 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -122,6 +122,23 @@ jobs: - name: Configure Butterscotch shell: pwsh run: | + $setup = @( + Join-Path ${env:ProgramFiles} 'Microsoft GDK\SetEnvironment.cmd', + Join-Path ${env:ProgramFiles(x86)} 'Microsoft GDK\SetEnvironment.cmd' + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $setup) { + throw 'Microsoft GDK SetEnvironment.cmd was not found.' + } + + if (Test-Path "$env:GITHUB_WORKSPACE/build") { + Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force + } + + & $setup /release /x64 + cmake -S "$env:GITHUB_WORKSPACE" ` -B "$env:GITHUB_WORKSPACE/build" ` -G Ninja ` @@ -137,6 +154,18 @@ jobs: - name: Build Butterscotch shell: pwsh run: | + $setup = @( + Join-Path ${env:ProgramFiles} 'Microsoft GDK\SetEnvironment.cmd', + Join-Path ${env:ProgramFiles(x86)} 'Microsoft GDK\SetEnvironment.cmd' + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $setup) { + throw 'Microsoft GDK SetEnvironment.cmd was not found.' + } + + & $setup /release /x64 cmake --build "$env:GITHUB_WORKSPACE/build" - name: Upload artifact From 028cbe5030b0e84a9bff22a5403348062b58cb36 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 01:04:20 +0100 Subject: [PATCH 24/33] zzz --- .github/workflows/build-xboxone.yml | 79 ++++++++++++++++++----------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index b43791430..9ce01520b 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -122,51 +122,68 @@ jobs: - name: Configure Butterscotch shell: pwsh run: | - $setup = @( - Join-Path ${env:ProgramFiles} 'Microsoft GDK\SetEnvironment.cmd', - Join-Path ${env:ProgramFiles(x86)} 'Microsoft GDK\SetEnvironment.cmd' - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 + function Invoke-WithGdkPrompt { + param([string]$Command) - if (-not $setup) { - throw 'Microsoft GDK SetEnvironment.cmd was not found.' + $gdkPrompt = @( + "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", + "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkPrompt) { + throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' + } + + $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) + $target = $shortcut.TargetPath + $args = $shortcut.Arguments + + if (-not $target) { + throw 'The GDK command prompt shortcut target could not be resolved.' + } + + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + cmd.exe /d /c "$launcher && $Command" } if (Test-Path "$env:GITHUB_WORKSPACE/build") { Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force } - & $setup /release /x64 - - cmake -S "$env:GITHUB_WORKSPACE" ` - -B "$env:GITHUB_WORKSPACE/build" ` - -G Ninja ` - -DPLATFORM=xboxone ` - -DBACKEND=sdl2 ` - -DGDK="$env:GDK" ` - -DGDKX="$env:GDKX" ` - -DSDL2_DIR="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - -DCMAKE_PREFIX_PATH="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - -DCMAKE_BUILD_TYPE=Release ` - -DWERROR=ON + Invoke-WithGdkPrompt "cmake -S `"$env:GITHUB_WORKSPACE`" -B `"$env:GITHUB_WORKSPACE/build`" -G Ninja -DPLATFORM=xboxone -DBACKEND=sdl2 -DGDK=`"$env:GDK`" -DGDKX=`"$env:GDKX`" -DSDL2_DIR=`"$env:GITHUB_WORKSPACE/vendor/SDL2/install`" -DCMAKE_PREFIX_PATH=`"$env:GITHUB_WORKSPACE/vendor/SDL2/install`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" - name: Build Butterscotch shell: pwsh run: | - $setup = @( - Join-Path ${env:ProgramFiles} 'Microsoft GDK\SetEnvironment.cmd', - Join-Path ${env:ProgramFiles(x86)} 'Microsoft GDK\SetEnvironment.cmd' - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 + function Invoke-WithGdkPrompt { + param([string]$Command) + + $gdkPrompt = @( + "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", + "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkPrompt) { + throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' + } + + $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) + $target = $shortcut.TargetPath + $args = $shortcut.Arguments + + if (-not $target) { + throw 'The GDK command prompt shortcut target could not be resolved.' + } - if (-not $setup) { - throw 'Microsoft GDK SetEnvironment.cmd was not found.' + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + cmd.exe /d /c "$launcher && $Command" } - & $setup /release /x64 - cmake --build "$env:GITHUB_WORKSPACE/build" + Invoke-WithGdkPrompt 'cmake --build "${env:GITHUB_WORKSPACE}/build"' - name: Upload artifact uses: actions/upload-artifact@v7 From 43bb50c9725e67141afddbc743bc2a7cc62d53eb Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 01:07:51 +0100 Subject: [PATCH 25/33] sdl with gdk --- .github/workflows/build-xboxone.yml | 67 ++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index 9ce01520b..ce89bbf38 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -83,11 +83,6 @@ jobs: - name: Install Ninja uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Set up MSVC - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - name: Cache SDL2 build id: cache-sdl2 uses: actions/cache@v6 @@ -107,17 +102,41 @@ jobs: if: steps.cache-sdl2.outputs.cache-hit != 'true' shell: pwsh run: | - cmake -S "$env:GITHUB_WORKSPACE/vendor/SDL2" ` - -B "$env:GITHUB_WORKSPACE/vendor/SDL2/build" ` - -G Ninja ` - -DCMAKE_BUILD_TYPE=Release ` - -DCMAKE_INSTALL_PREFIX="$env:GITHUB_WORKSPACE/vendor/SDL2/install" ` - -DSDL_SHARED=OFF ` - -DSDL_STATIC=ON ` - -DSDL_TESTS=OFF ` - -DSDL_GDK=ON - cmake --build "$env:GITHUB_WORKSPACE/vendor/SDL2/build" - cmake --install "$env:GITHUB_WORKSPACE/vendor/SDL2/build" + function Invoke-WithGdkPrompt { + param([string]$Command) + + $gdkPrompt = @( + "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", + "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkPrompt) { + throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' + } + + $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) + $target = $shortcut.TargetPath + $args = $shortcut.Arguments + + if (-not $target) { + throw 'The GDK command prompt shortcut target could not be resolved.' + } + + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline + } + + $workspace = $env:GITHUB_WORKSPACE + $sdlSrc = Join-Path $workspace 'vendor\SDL2' + $sdlBuild = Join-Path $sdlSrc 'build' + $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' + $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" + Invoke-WithGdkPrompt $cmakeCommand + Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`"" + Invoke-WithGdkPrompt "cmake --install `"$sdlBuild`"" - name: Configure Butterscotch shell: pwsh @@ -145,14 +164,19 @@ jobs: } $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - cmd.exe /d /c "$launcher && $Command" + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline } if (Test-Path "$env:GITHUB_WORKSPACE/build") { Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force } - Invoke-WithGdkPrompt "cmake -S `"$env:GITHUB_WORKSPACE`" -B `"$env:GITHUB_WORKSPACE/build`" -G Ninja -DPLATFORM=xboxone -DBACKEND=sdl2 -DGDK=`"$env:GDK`" -DGDKX=`"$env:GDKX`" -DSDL2_DIR=`"$env:GITHUB_WORKSPACE/vendor/SDL2/install`" -DCMAKE_PREFIX_PATH=`"$env:GITHUB_WORKSPACE/vendor/SDL2/install`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" + $workspace = $env:GITHUB_WORKSPACE + $buildDir = Join-Path $workspace 'build' + $sdlDir = Join-Path $workspace 'vendor\SDL2\install' + $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G Ninja -DPLATFORM=xboxone -DBACKEND=sdl2 -DGDK=`"$env:GDK`" -DGDKX=`"$env:GDKX`" -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" + Invoke-WithGdkPrompt $cmakeCommand - name: Build Butterscotch shell: pwsh @@ -180,10 +204,13 @@ jobs: } $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - cmd.exe /d /c "$launcher && $Command" + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline } - Invoke-WithGdkPrompt 'cmake --build "${env:GITHUB_WORKSPACE}/build"' + $workspace = $env:GITHUB_WORKSPACE + $buildDir = Join-Path $workspace 'build' + Invoke-WithGdkPrompt "cmake --build `"$buildDir`"" - name: Upload artifact uses: actions/upload-artifact@v7 From a81c488ef76222208ea41460419cb28b4ef01637 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 01:09:45 +0100 Subject: [PATCH 26/33] remove sdl cache for a second --- .github/workflows/build-xboxone.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index ce89bbf38..e121f2f56 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -83,15 +83,15 @@ jobs: - name: Install Ninja uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Cache SDL2 build - id: cache-sdl2 - uses: actions/cache@v6 - with: - path: ${{ github.workspace }}/vendor/SDL2/install - key: sdl2-xboxone-${{ runner.os }}-2.32.10-rev2 + # - name: Cache SDL2 build + # id: cache-sdl2 + # uses: actions/cache@v6 + # with: + # path: ${{ github.workspace }}/vendor/SDL2/install + # key: sdl2-xboxone-${{ runner.os }}-2.32.10-rev2 - name: Checkout SDL2 - if: steps.cache-sdl2.outputs.cache-hit != 'true' + # if: steps.cache-sdl2.outputs.cache-hit != 'true' uses: actions/checkout@v7 with: repository: libsdl-org/SDL @@ -99,7 +99,7 @@ jobs: path: vendor/SDL2 - name: Build SDL2 from source - if: steps.cache-sdl2.outputs.cache-hit != 'true' + # if: steps.cache-sdl2.outputs.cache-hit != 'true' shell: pwsh run: | function Invoke-WithGdkPrompt { From 838601d11ac7127891522f190201483f2967d1a3 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 01:48:07 +0100 Subject: [PATCH 27/33] go go go --- .github/workflows/build-xboxone.yml | 38 +++++++++++++++++++++-------- CMakeLists.txt | 7 ------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-xboxone.yml index e121f2f56..92b8f83e9 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-xboxone.yml @@ -124,16 +124,22 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline + $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) + $batchLines = @( + '@echo off', + ('call "' + $target + '" ' + $args), + $Command + ) + [System.IO.File]::WriteAllLines($batchPath, $batchLines) + & $batchPath + Remove-Item $batchPath -Force -ErrorAction SilentlyContinue } $workspace = $env:GITHUB_WORKSPACE $sdlSrc = Join-Path $workspace 'vendor\SDL2' $sdlBuild = Join-Path $sdlSrc 'build' $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" + $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF" Invoke-WithGdkPrompt $cmakeCommand Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`"" Invoke-WithGdkPrompt "cmake --install `"$sdlBuild`"" @@ -163,9 +169,15 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline + $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) + $batchLines = @( + '@echo off', + ('call "' + $target + '" ' + $args), + $Command + ) + [System.IO.File]::WriteAllLines($batchPath, $batchLines) + & $batchPath + Remove-Item $batchPath -Force -ErrorAction SilentlyContinue } if (Test-Path "$env:GITHUB_WORKSPACE/build") { @@ -203,9 +215,15 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline + $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) + $batchLines = @( + '@echo off', + ('call "' + $target + '" ' + $args), + $Command + ) + [System.IO.File]::WriteAllLines($batchPath, $batchLines) + & $batchPath + Remove-Item $batchPath -Force -ErrorAction SilentlyContinue } $workspace = $env:GITHUB_WORKSPACE diff --git a/CMakeLists.txt b/CMakeLists.txt index 001961cb2..185d3a57b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,13 +25,6 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) endif() set(BACKEND "sdl2") - -elseif(PLATFORM STREQUAL "xboxone") - if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - if(NOT DEFINED ENV{GDK} AND NOT DEFINED ENV{GDKX}) - message(FATAL_ERROR "Please define GDK or GDKX to point to your Xbox GDK installation before configuring PLATFORM=xboxone!") - endif() - endif() endif() project(butterscotch C) From 316d2349816887e473ba188095691d37dd8aa106 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:40:04 +0100 Subject: [PATCH 28/33] generic gdk build --- .../{build-xboxone.yml => build-gdk.yml} | 50 +- CMakeLists.txt | 1736 ++++++++--------- src/xboxone/log.c | 22 - src/xboxone/main.c | 44 - src/xboxone/stb_impl.c | 6 - 5 files changed, 883 insertions(+), 975 deletions(-) rename .github/workflows/{build-xboxone.yml => build-gdk.yml} (77%) delete mode 100644 src/xboxone/log.c delete mode 100644 src/xboxone/main.c delete mode 100644 src/xboxone/stb_impl.c diff --git a/.github/workflows/build-xboxone.yml b/.github/workflows/build-gdk.yml similarity index 77% rename from .github/workflows/build-xboxone.yml rename to .github/workflows/build-gdk.yml index 92b8f83e9..83ac93f00 100644 --- a/.github/workflows/build-xboxone.yml +++ b/.github/workflows/build-gdk.yml @@ -1,11 +1,11 @@ -name: Xbox One builds +name: GDK builds on: workflow_call: jobs: build-xboxone: - name: Build (Xbox One) + name: Build (GDK) runs-on: windows-2025 steps: @@ -124,24 +124,18 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) - $batchLines = @( - '@echo off', - ('call "' + $target + '" ' + $args), - $Command - ) - [System.IO.File]::WriteAllLines($batchPath, $batchLines) - & $batchPath - Remove-Item $batchPath -Force -ErrorAction SilentlyContinue + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline } $workspace = $env:GITHUB_WORKSPACE $sdlSrc = Join-Path $workspace 'vendor\SDL2' $sdlBuild = Join-Path $sdlSrc 'build' $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF" + $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G "Visual Studio 18 2026" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" Invoke-WithGdkPrompt $cmakeCommand - Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`"" + Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`" --config Release" Invoke-WithGdkPrompt "cmake --install `"$sdlBuild`"" - name: Configure Butterscotch @@ -169,15 +163,9 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) - $batchLines = @( - '@echo off', - ('call "' + $target + '" ' + $args), - $Command - ) - [System.IO.File]::WriteAllLines($batchPath, $batchLines) - & $batchPath - Remove-Item $batchPath -Force -ErrorAction SilentlyContinue + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline } if (Test-Path "$env:GITHUB_WORKSPACE/build") { @@ -187,7 +175,7 @@ jobs: $workspace = $env:GITHUB_WORKSPACE $buildDir = Join-Path $workspace 'build' $sdlDir = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G Ninja -DPLATFORM=xboxone -DBACKEND=sdl2 -DGDK=`"$env:GDK`" -DGDKX=`"$env:GDKX`" -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" + $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G `"Visual Studio 18 2026`" -A x64 -DBACKEND=sdl2 -DIS_GDK=ON -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" Invoke-WithGdkPrompt $cmakeCommand - name: Build Butterscotch @@ -215,23 +203,17 @@ jobs: throw 'The GDK command prompt shortcut target could not be resolved.' } - $batchPath = Join-Path ([System.IO.Path]::GetTempPath()) ("gdk-run-{0}.cmd" -f [System.Guid]::NewGuid()) - $batchLines = @( - '@echo off', - ('call "' + $target + '" ' + $args), - $Command - ) - [System.IO.File]::WriteAllLines($batchPath, $batchLines) - & $batchPath - Remove-Item $batchPath -Force -ErrorAction SilentlyContinue + $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } + $cmdline = $launcher + ' && ' + $Command + cmd.exe /d /s /c $cmdline } $workspace = $env:GITHUB_WORKSPACE $buildDir = Join-Path $workspace 'build' - Invoke-WithGdkPrompt "cmake --build `"$buildDir`"" + Invoke-WithGdkPrompt "cmake --build `"$buildDir`" --config Release" - name: Upload artifact uses: actions/upload-artifact@v7 with: - name: butterscotch-xboxone + name: butterscotch-gdk path: build/**/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 185d3a57b..bb596aa41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,869 +1,867 @@ -cmake_minimum_required(VERSION 3.21) - -if(PLATFORM STREQUAL "ps3") -set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ppu.cmake) -endif() - -if(PLATFORM STREQUAL "vita") - -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - if(DEFINED ENV{VITASDK}) - set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") - else() - message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") - endif() -endif() - -set(BACKEND "sdl2") - -elseif(PLATFORM STREQUAL "switch") -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - if(NOT DEFINED ENV{DEVKITPRO}) - message(FATAL_ERROR "Please define DEVKITPRO to point to your SDK path!") - endif() - set(CMAKE_TOOLCHAIN_FILE "$ENV{DEVKITPRO}/cmake/Switch.cmake" CACHE PATH "toolchain file") -endif() - -set(BACKEND "sdl2") -endif() - -project(butterscotch C) - -if (PLATFORM STREQUAL "vita") -include("${VITASDK}/share/vita.cmake" REQUIRED) -set(VITA_APP_NAME "Butterscotch") -set(VITA_TITLEID "BUTTRSTCH") -set(VITA_VERSION "01.00") -set(VITA_MKSFOEX_FLAGS "-d ATTRIBUTE2=12") -endif() - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -if(MSVC) - if(WERROR) - add_compile_options(/WX) - endif() -else() - add_compile_options(-Wall -Wextra -Wvla) - if(WERROR) - add_compile_options(-Werror) - endif() -endif() - -if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - if(MSVC) - # equivalent to -fomit-frame-pointer - add_compile_options(/Oy) - else() - add_compile_options(-ffast-math -fno-finite-math-only) - - # some targets don't support -fomit-frame-pointer IIRC - include(CheckCCompilerFlag) - check_c_compiler_flag("-fomit-frame-pointer" HAS_FOMIT_FRAME_POINTER) - if(HAS_FOMIT_FRAME_POINTER) - add_compile_options(-fomit-frame-pointer) - endif() - endif() -endif() - -set(PLATFORM "cli" CACHE STRING "Platform backend") -set(BACKEND "" CACHE STRING "Desktop platform backend") -set(AUDIO_BACKEND "" CACHE STRING "Audio backend") - -if(PLATFORM STREQUAL "cli" AND BACKEND STREQUAL "") - message(FATAL_ERROR "You need to set a BACKEND!") -endif() - -# Build metadata -set(BUTTERSCOTCH_COMMIT_HASH "unknown" CACHE STRING "Git commit hash") -set(BUTTERSCOTCH_COMMIT_DATE "unknown" CACHE STRING "Git commit date") -add_compile_definitions( - BUTTERSCOTCH_COMMIT_HASH="${BUTTERSCOTCH_COMMIT_HASH}" - BUTTERSCOTCH_COMMIT_DATE="${BUTTERSCOTCH_COMMIT_DATE}" -) - -# Audio backend defaults -if(AUDIO_BACKEND STREQUAL "") - if(PLATFORM STREQUAL "web") - set(AUDIO_BACKEND "web") - elseif(PLATFORM STREQUAL "web-meta") - set(AUDIO_BACKEND "none") - elseif(PLATFORM STREQUAL "ps3" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") - set(AUDIO_BACKEND "openal") - elseif(PLATFORM STREQUAL "ps2") - set(AUDIO_BACKEND "ps2") - else() - set(AUDIO_BACKEND "miniaudio") - endif() -endif() - -if(AUDIO_BACKEND STREQUAL "openal") - file(GLOB AUDIO_SOURCES src/audio/openal/*.c) -elseif(AUDIO_BACKEND STREQUAL "miniaudio") - file(GLOB AUDIO_SOURCES src/audio/miniaudio/*.c) - if(PLATFORM STREQUAL "vita") - add_compile_definitions(MA_NO_RUNTIME_LINKING) - endif() -elseif(AUDIO_BACKEND STREQUAL "web") - file(GLOB AUDIO_SOURCES src/audio/web/*.c src/audio/miniaudio/*.c) -elseif(AUDIO_BACKEND STREQUAL "ps2") - file(GLOB AUDIO_SOURCES src/audio/ps2/*.c) -elseif(NOT AUDIO_BACKEND STREQUAL "none") - message(FATAL_ERROR "Invalid AUDIO_BACKEND!") -endif() - -# To avoid unused code in production builds that are only used for a single game (example: PlayStation 2 target), we can enable/disable specific features -# -# If only a single WAD version is enabled, the checks will be collapsed and removed by the compiler during build time, reducing code size and improving -# performance on low end hardware! -option(ENABLE_WAD14 "Enable support for WAD Version 14 and below" ON) -option(ENABLE_WAD16 "Enable support for WAD Version 15/16" ON) -option(ENABLE_WAD17 "Enable support for WAD Version 17" ON) -option(ENABLE_LEGACY_GL "Enable the legacy OpenGL renderer" ON) -if(PLATFORM STREQUAL "switch") - set(ENABLE_LEGACY_GL OFF CACHE BOOL "Enable the legacy OpenGL renderer" FORCE) -endif() -option(ENABLE_MODERN_GL "Enable the modern OpenGL renderer" ON) -option(ENABLE_NOOP_RENDERER "Enable the no-op renderer (headless stub, no drawing)" OFF) -# Noop renderer is exclusive to the noop desktop backend (no window, no GL). -# Auto-enable for BACKEND=noop and reject otherwise. -if(BACKEND STREQUAL "noop") - set(ENABLE_NOOP_RENDERER ON CACHE BOOL "Enable the no-op renderer (headless stub, no drawing)" FORCE) - set(ENABLE_LEGACY_GL OFF CACHE BOOL "Enable the legacy OpenGL renderer" FORCE) - set(ENABLE_MODERN_GL OFF CACHE BOOL "Enable the modern OpenGL renderer" FORCE) -endif() -if(ENABLE_NOOP_RENDERER AND NOT BACKEND STREQUAL "noop") - message(FATAL_ERROR "ENABLE_NOOP_RENDERER is exclusive to BACKEND=noop") -endif() -if(NOT ENABLE_WAD14 AND NOT ENABLE_WAD16 AND NOT ENABLE_WAD17) - message(FATAL_ERROR "You need to build Butterscotch with at least one WAD version enabled!") -endif() -if(ENABLE_WAD14) - add_compile_definitions(ENABLE_WAD14) -endif() -if(ENABLE_WAD16) - add_compile_definitions(ENABLE_WAD16) -endif() -if(ENABLE_WAD17) - add_compile_definitions(ENABLE_WAD17) -endif() -if(ENABLE_LEGACY_GL) - add_compile_definitions(ENABLE_LEGACY_GL) -endif() -if(ENABLE_MODERN_GL) - add_compile_definitions(ENABLE_MODERN_GL) -endif() -if(ENABLE_NOOP_RENDERER) - add_compile_definitions(ENABLE_NOOP_RENDERER) -endif() - -if(PLATFORM STREQUAL "web-meta") - # Metadata-only build: just the data.win parser and its direct deps. No VM, no runner, no I/O subsystems. - set(SOURCES - src/data_win.c - src/binary_reader.c - src/log.c - src/stb_ds.c - ) -else() - file(GLOB SOURCES src/*.c) - # These platforms haven't been converted to the refactored system yet. - # This list should NEVER grow, all new platforms should use the new system. - if(PLATFORM STREQUAL "ps2" OR PLATFORM STREQUAL "ps3" OR PLATFORM STREQUAL "web" OR PLATFORM STREQUAL "android") - list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/loop.c") - endif() -endif() -# Platform specific files builds -file(GLOB PLATFORM_SOURCES src/${PLATFORM}/*.c) - -if(PLATFORM STREQUAL "android") - add_library(butterscotch SHARED ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) -else() - add_executable(butterscotch ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) -endif() - -target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src) -target_include_directories(butterscotch PRIVATE src/${PLATFORM}) - -if(AUDIO_BACKEND STREQUAL "openal") - target_include_directories(butterscotch PUBLIC src/audio/openal) - add_compile_definitions(USE_OPENAL) - if(APPLE) - set(AUDIO_LIBRARIES "-framework OpenAL") - elseif(PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") - set(AUDIO_LIBRARIES openal pthread) - elseif(NOT PLATFORM STREQUAL "ps3") - find_package(OpenAL REQUIRED) - target_include_directories(butterscotch PUBLIC "${OPENAL_INCLUDE_DIR}") - set(AUDIO_LIBRARIES "${OPENAL_LIBRARY}") - endif() -elseif(AUDIO_BACKEND STREQUAL "miniaudio") - target_include_directories(butterscotch SYSTEM PUBLIC vendor/miniaudio) - target_include_directories(butterscotch PUBLIC src/audio/miniaudio) - add_compile_definitions(USE_MINIAUDIO) - if (NOT WIN32) - set(AUDIO_LIBRARIES pthread) - endif() -elseif(AUDIO_BACKEND STREQUAL "web") - target_include_directories(butterscotch SYSTEM PUBLIC vendor/miniaudio) - target_include_directories(butterscotch PUBLIC src/audio/web) - target_include_directories(butterscotch PUBLIC src/audio/miniaudio) - add_compile_definitions(USE_WEB_AUDIO) -elseif(AUDIO_BACKEND STREQUAL "ps2") - target_include_directories(butterscotch PUBLIC src/audio/ps2) - add_compile_definitions(USE_PS2_AUDIO) -endif() - -# stb_ds -add_library(stb_ds INTERFACE) -target_include_directories(stb_ds SYSTEM INTERFACE ${CMAKE_SOURCE_DIR}/vendor/stb/ds) - -# stb_vorbis -add_library(stb_vorbis INTERFACE) -target_include_directories(stb_vorbis SYSTEM INTERFACE ${CMAKE_SOURCE_DIR}/vendor/stb/vorbis) - -# RFC 1321 reference MD5 implementation -target_sources(butterscotch PRIVATE vendor/md5/md5.c) -target_include_directories(butterscotch PUBLIC vendor/md5) - -# Steve Reid's SHA1 implementation -add_library(sha1 STATIC vendor/sha1/sha1.c) -target_include_directories(sha1 SYSTEM PUBLIC vendor/sha1) -target_compile_options(sha1 PRIVATE -w) - -# Base64 implementation -target_sources(butterscotch PRIVATE vendor/base64/base64.c) -target_include_directories(butterscotch PUBLIC vendor/base64) - -# bzip2 -add_library(bzip2 STATIC - vendor/bzip2/bz_internal_error.c - vendor/bzip2/bzlib.c - vendor/bzip2/crctable.c - vendor/bzip2/decompress.c - vendor/bzip2/huffman.c - vendor/bzip2/randtable.c -) -target_include_directories(bzip2 PUBLIC vendor/bzip2) -target_compile_options(bzip2 PRIVATE -w) - -# Spatial grid logs -option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) -if(ENABLE_SPATIAL_GRID_LOGS) - add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) -endif() - -# VM Exceptions logs -option(ENABLE_VM_EXCEPTIONS_LOGS "Enable VM Exceptions logs" OFF) -if(ENABLE_VM_EXCEPTIONS_LOGS) - add_compile_definitions(ENABLE_VM_EXCEPTIONS_LOGS) -endif() - -if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch" OR PLATFORM STREQUAL "xboxone") - if(PLATFORM STREQUAL "vita") - # Normally, __VITA__ should already be defined, but for some reason, - # in my case, this didn't really work... so just in case, when we're - # building for the Vita, just force-feed these... - add_compile_definitions(__VITA__) - add_compile_definitions(PLATFORM_VITA) - - set(VM_GML_PROFILER_DEFAULT OFF) - set(VM_TRACING_DEFAULT OFF) - set(VM_OPCODE_PROFILER_DEFAULT OFF) - set(VM_STUB_LOGS_DEFAULT OFF) - elseif(PLATFORM STREQUAL "switch") - add_compile_definitions(PLATFORM_SWITCH) - - set(VM_GML_PROFILER_DEFAULT OFF) - set(VM_TRACING_DEFAULT OFF) - set(VM_OPCODE_PROFILER_DEFAULT OFF) - set(VM_STUB_LOGS_DEFAULT OFF) - elseif(PLATFORM STREQUAL "xboxone") - add_compile_definitions(PLATFORM_XBOXONE) - - set(VM_GML_PROFILER_DEFAULT OFF) - set(VM_TRACING_DEFAULT OFF) - set(VM_OPCODE_PROFILER_DEFAULT OFF) - set(VM_STUB_LOGS_DEFAULT OFF) - else() - set(VM_GML_PROFILER_DEFAULT ON) - set(VM_TRACING_DEFAULT ON) - set(VM_OPCODE_PROFILER_DEFAULT ON) - set(VM_STUB_LOGS_DEFAULT ON) - endif() - # Matches the GitHub Actions container flags (FORTIFY requires building with optimizations enabled!) - target_compile_options(butterscotch PRIVATE "$<$:-U_FORTIFY_SOURCE;-D_FORTIFY_SOURCE=2>") - - if(NOT ENABLE_LEGACY_GL AND NOT ENABLE_MODERN_GL AND NOT ENABLE_NOOP_RENDERER) - message(FATAL_ERROR "You must enable at least one renderer!") - endif() - file(GLOB GL_SOURCES src/image/*.c src/gl_common/*.c) - if(ENABLE_LEGACY_GL) - file(GLOB GL_SOURCES ${GL_SOURCES} src/gl_legacy/*.c) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_legacy) - endif() - if(ENABLE_MODERN_GL) - file(GLOB GL_SOURCES ${GL_SOURCES} src/gl/*.c) - endif() - target_sources(butterscotch PRIVATE ${GL_SOURCES}) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) - if (MSVC) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/compat/getopt) - if (PLATFORM STREQUAL "xboxone") - add_compile_definitions(NO_STRINGS_H) - endif() - add_compile_definitions(NO_STRTOK_R) - add_compile_definitions(NO_STRCASECMP) - endif() - - # Butterscotch VM/interpreter profiler - option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" ${VM_GML_PROFILER_DEFAULT}) - if(ENABLE_VM_GML_PROFILER) - add_compile_definitions(ENABLE_VM_GML_PROFILER) - endif() - - # Butterscotch VM/interpreter tracing - option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" ${VM_TRACING_DEFAULT}) - if(ENABLE_VM_TRACING) - add_compile_definitions(ENABLE_VM_TRACING) - endif() - - # Butterscotch VM opcode count profiler - option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" ${VM_OPCODE_PROFILER_DEFAULT}) - if(ENABLE_VM_OPCODE_PROFILER) - add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) - endif() - - # VM unknown/stubbed function logs - option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" ${VM_STUB_LOGS_DEFAULT}) - if(ENABLE_VM_STUB_LOGS) - add_compile_definitions(ENABLE_VM_STUB_LOGS) - endif() - - # stb_image - target_include_directories(butterscotch PUBLIC vendor/stb/image) - - set(PLATFORM_LIBRARIES bzip2 stb_ds sha1 stb_vorbis) - if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") - # GLAD - add_library(glad STATIC vendor/glad/src/glad.c) - target_include_directories(glad PUBLIC vendor/glad/include) - if(NOT PLATFORM STREQUAL "xboxone") - target_compile_options(glad PRIVATE -Wno-unused-but-set-variable) - endif() - set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} glad) - endif() - if(NOT MSVC) - set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} m) - endif() - if(WIN32) - set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} opengl32 gdi32 winmm) - elseif(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") - set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${CMAKE_DL_LIBS}) - endif() - - if(BACKEND STREQUAL "glfw3") - add_compile_definitions(USE_GLFW3) - - if(MINGW) - find_package(glfw3 CONFIG REQUIRED) - - # Target Windows 7+ (avoids referencing newer APIs like MapViewOfFileNuma2 that MinGW import libs don't provide) - # https://github.com/mirror/mingw-w64/blob/master/mingw-w64-headers/include/sdkddkver.h - target_compile_definitions(butterscotch PRIVATE _WIN32_WINNT=0x0601 NTDDI_VERSION=0x06010000 WIN32_LEAN_AND_MEAN) - target_link_options(butterscotch PRIVATE -static) - set(BACKEND_LIBRARIES glfw opengl32 gdi32 winmm) - elseif(MSVC) - target_compile_definitions(butterscotch PRIVATE WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS) - find_package(glfw3 CONFIG REQUIRED) - set(BACKEND_LIBRARIES glfw opengl32 gdi32 winmm) - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(GLFW3 REQUIRED glfw3) - target_include_directories(butterscotch PRIVATE ${GLFW3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${GLFW3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${GLFW3_LIBRARIES}) - endif() - elseif(BACKEND STREQUAL "glfw2") - add_compile_definitions(USE_GLFW2) - - find_package(PkgConfig REQUIRED) - pkg_check_modules(GLFW2 REQUIRED libglfw) - target_include_directories(butterscotch PRIVATE ${GLFW2_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${GLFW2_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${GLFW2_LIBRARIES}) - elseif(BACKEND STREQUAL "sdl1") - add_compile_definitions(USE_SDL1) - - find_package(SDL REQUIRED) - target_include_directories(butterscotch PUBLIC ${SDL_INCLUDE_DIR}) - set(BACKEND_LIBRARIES ${SDL_LIBRARY}) - elseif(BACKEND STREQUAL "sdl2") - add_compile_definitions(USE_SDL2) - - if(MSVC) - if(DEFINED SDL2_DIR OR DEFINED ENV{SDL2_DIR}) - find_package(SDL2 CONFIG REQUIRED) - set(BACKEND_LIBRARIES SDL2::SDL2) - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL2 REQUIRED sdl2) - target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) - endif() - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL2 REQUIRED sdl2) - target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) - endif() - elseif(BACKEND STREQUAL "sdl3") - add_compile_definitions(USE_SDL3) - - if(MSVC) - if(DEFINED SDL3_DIR OR DEFINED ENV{SDL3_DIR}) - find_package(SDL3 CONFIG REQUIRED) - set(BACKEND_LIBRARIES SDL3::SDL3) - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL3 REQUIRED sdl3) - target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) - endif() - else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL3 REQUIRED sdl3) - target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) - target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) - set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) - endif() - elseif(BACKEND STREQUAL "appkit") - add_compile_definitions(USE_APPKIT) - target_compile_definitions(butterscotch PRIVATE GL_SILENCE_DEPRECATION) - set(BACKEND_LIBRARIES "-framework Cocoa" "-framework GameController") - elseif(BACKEND STREQUAL "noop") - if(NOT ENABLE_NOOP_RENDERER) - message(FATAL_ERROR "BACKEND=noop requires ENABLE_NOOP_RENDERER=ON") - endif() - add_compile_definitions(USE_NOOP) - set(BACKEND_LIBRARIES "") - endif() - if (PLATFORM STREQUAL "vita") - target_link_libraries(butterscotch PRIVATE - ${BACKEND_LIBRARIES} - ${AUDIO_LIBRARIES} - ${PLATFORM_LIBRARIES} - vitaGL - stdc++ - SceShaccCgExt - taihen_stub - SceShaccCg_stub - ) - - vita_create_self(eboot.bin butterscotch UNSAFE) - vita_create_vpk(Butterscotch.vpk ${VITA_TITLEID} eboot.bin - VERSION ${VITA_VERSION} - NAME ${VITA_APP_NAME} - ) - else() - target_link_libraries(butterscotch PRIVATE ${BACKEND_LIBRARIES} ${AUDIO_LIBRARIES} ${PLATFORM_LIBRARIES}) - - if (PLATFORM STREQUAL "switch") - target_link_libraries(butterscotch PRIVATE GLESv2 stdc++) - nx_generate_nacp(OUTPUT Butterscotch.nacp NAME "Butterscotch" AUTHOR "Butterscotch" VERSION "1.0.0") - nx_create_nro(butterscotch NACP Butterscotch.nacp) - endif() - endif() - if(BACKEND STREQUAL "appkit") - target_sources(butterscotch PRIVATE src/backends/${BACKEND}.m) - else() - target_sources(butterscotch PRIVATE src/backends/${BACKEND}.c) - endif() - - # Enable AddressSanitizer by default in Debug builds - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(ENABLE_ASAN_DEFAULT ON) - else() - set(ENABLE_ASAN_DEFAULT OFF) - endif() - set(ENABLE_ASAN ${ENABLE_ASAN_DEFAULT} CACHE BOOL "Enable AddressSanitizer") - if(ENABLE_ASAN AND NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") - target_compile_options(butterscotch PRIVATE -fsanitize=address -fno-omit-frame-pointer) - target_link_options(butterscotch PRIVATE -fsanitize=address) - endif() - - #gamecontrollerdb - add_custom_command(TARGET butterscotch POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/vendor/gamecontrollerdb.txt - $/gamecontrollerdb.txt - ) -elseif(PLATFORM STREQUAL "web") - if (NOT ENABLE_MODERN_GL) - message(FATAL_ERROR "Web requires modern gl!") - endif() - file(GLOB GL_SOURCES src/gl/*.c src/gl_common/*.c src/image/*.c) - target_sources(butterscotch PRIVATE ${GL_SOURCES}) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) - - # stb_image - target_include_directories(butterscotch PUBLIC vendor/stb/image) - - # bzip2 - target_link_libraries(butterscotch PRIVATE bzip2 stb_ds sha1 stb_vorbis) - - set_target_properties(butterscotch PROPERTIES SUFFIX ".mjs") - - target_link_options( - butterscotch - PRIVATE - "-sMODULARIZE=1" - "-sEXPORT_ES6=1" - "-sENVIRONMENT=worker" - "-sWASMFS=1" - "-sEXPORTED_RUNTIME_METHODS=['HEAP8', 'HEAPU8', 'HEAPF32', 'ccall', 'cwrap', 'specialHTMLTargets', 'UTF8ToString']" - "-sEXPORTED_FUNCTIONS=['_main', '_mountOpfs', '_startRunner', '_stopRunner', '_malloc', '_free', '_getKeyDownPtr', '_getKeyUpPtr', '_getKeyCount', '_setAudioSampleRate', '_pullAudioFrames']" - "-sOFFSCREENCANVAS_SUPPORT=1" - "-sOFFSCREEN_FRAMEBUFFER=1" - "-sMIN_WEBGL_VERSION=2" - "-sMAX_WEBGL_VERSION=2" - "-sFULL_ES3=1" - "-sALLOW_MEMORY_GROWTH" - "-sSHARED_MEMORY=1" - "-sPTHREAD_POOL_SIZE=4" - "-pthread" - ) - - target_compile_options(butterscotch PRIVATE "-pthread") -elseif(PLATFORM STREQUAL "web-meta") - set_target_properties(butterscotch PROPERTIES - SUFFIX ".mjs" - OUTPUT_NAME "butterscotch-meta" - ) - - target_link_libraries(butterscotch PRIVATE stb_ds) - - target_link_options( - butterscotch - PRIVATE - "-sMODULARIZE=1" - "-sEXPORT_ES6=1" - "-sENVIRONMENT=web" - "-sEXPORTED_RUNTIME_METHODS=['HEAPU8', 'ccall', 'cwrap', 'UTF8ToString', 'FS']" - "-sEXPORTED_FUNCTIONS=['_main', '_parseDataWin', '_freeDataWin', '_getGameName', '_getGameDisplayName', '_getMajorVersion', '_getMinorVersion', '_getRelease', '_getBuild', '_getDefaultWindowWidth', '_getDefaultWindowHeight', '_malloc', '_free']" - "-sALLOW_MEMORY_GROWTH=1" - "-sFORCE_FILESYSTEM=1" - ) -elseif(PLATFORM STREQUAL "android") - if (NOT ENABLE_MODERN_GL) - message(FATAL_ERROR "Android requires modern gl!") - endif() - file(GLOB GL_SOURCES src/gl/*.c src/gl_common/*.c src/image/*.c) - target_sources(butterscotch PRIVATE ${GL_SOURCES}) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) - add_compile_definitions(ENABLE_GLES PLATFORM_ANDROID) - - # Butterscotch VM/interpreter profiler - option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" ON) - if(ENABLE_VM_GML_PROFILER) - add_compile_definitions(ENABLE_VM_GML_PROFILER) - endif() - - # Butterscotch VM/interpreter tracing - option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" ON) - if(ENABLE_VM_TRACING) - add_compile_definitions(ENABLE_VM_TRACING) - endif() - - # Butterscotch VM opcode count profiler - option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) - if(ENABLE_VM_OPCODE_PROFILER) - add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) - endif() - - # Spatial grid logs - option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) - if(ENABLE_SPATIAL_GRID_LOGS) - add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) - endif() - - # VM unknown/stubbed function logs - option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" ON) - if(ENABLE_VM_STUB_LOGS) - add_compile_definitions(ENABLE_VM_STUB_LOGS) - endif() - - # stb_image - target_include_directories(butterscotch PUBLIC vendor/stb/image) - # stb_vorbis (for miniaudio's OGG decoding) - target_include_directories(butterscotch PUBLIC vendor/stb/vorbis) - # bzip2 - target_link_libraries(butterscotch PRIVATE bzip2) - - # Android NDK system libraries: - # - log: __android_log_* - # - GLESv3: OpenGL ES 3.0 functions - # - OpenSLES: miniaudio's OpenSL ES backend (it dlopen's libaaudio.so at runtime when available, so no link-time aaudio dep) - target_link_libraries(butterscotch PRIVATE log GLESv3 OpenSLES bzip2 stb_ds sha1 stb_vorbis) -elseif(PLATFORM STREQUAL "ps2") - file(GLOB DEBUG_FONT_SOURCES src/debug_font/*.c) - target_sources(butterscotch PRIVATE ${DEBUG_FONT_SOURCES}) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/debug_font) - - # The PS2 EE has a single-precision FPU only, so double is software-emulated - add_compile_definitions(USE_FLOAT_REALS) - # By disabling Int64 support, we can fit the entire RValue struct in 8 bytes, improving performance and memory usage - add_compile_definitions(NO_RVALUE_INT64) - - # Butterscotch VM/interpreter profiler - option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" OFF) - if(ENABLE_VM_GML_PROFILER) - add_compile_definitions(ENABLE_VM_GML_PROFILER) - endif() - - # Butterscotch VM/interpreter tracing - option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" OFF) - if(ENABLE_VM_TRACING) - add_compile_definitions(ENABLE_VM_TRACING) - endif() - - # Butterscotch VM opcode count profiler - option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) - if(ENABLE_VM_OPCODE_PROFILER) - add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) - endif() - - # Spatial grid logs - option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) - if(ENABLE_SPATIAL_GRID_LOGS) - add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) - endif() - - # VM unknown/stubbed function logs - option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" OFF) - if(ENABLE_VM_STUB_LOGS) - add_compile_definitions(ENABLE_VM_STUB_LOGS) - endif() - - # Platform identifier for PS2-specific code paths (e.g., scratchpad allocation) - add_compile_definitions(PLATFORM_PS2) - - # PS2 renderer hot path logs - option(ENABLE_PS2_RENDERER_LOGS "Enable hot path logs in the PS2 renderer" OFF) - if(ENABLE_PS2_RENDERER_LOGS) - add_compile_definitions(ENABLE_PS2_RENDERER_LOGS) - endif() - - # -fsingle-precision-constant: Treat unsuffixed float constants as single-precision to avoid accidental float->double promotions on platforms with no hardware double - # -Werror=double-promotion: Warn when something is being promoted to a double - # -Wno-format: because there are too many formatting issues that, at the end of the day, do not matter - target_compile_options(butterscotch PRIVATE -fsingle-precision-constant -Werror=double-promotion -Wno-format) - - if(PS2) - # Compiling on the Docker container - target_include_directories(butterscotch PRIVATE $ENV{PS2SDK}/ee/include $ENV{PS2SDK}/common/include $ENV{PS2DEV}/ee/include $ENV{GSKIT}/include) - target_link_directories(butterscotch PRIVATE $ENV{PS2SDK}/ee/lib $ENV{GSKIT}/lib) - target_link_libraries(${AUDIO_LIBRARIES} butterscotch gskit dmakit audsrv pad mc kbd patches kernel c m stb_ds sha1) - - # Embed ps2sdk IRX modules (freesio2, freepad) as C arrays via bin2c - # This avoids loading from rom0: which has compatibility issues between fat/slim PS2 - set(IRX_DIR $ENV{PS2SDK}/iop/irx) - set(IRX_GEN_DIR ${CMAKE_BINARY_DIR}/generated/irx) - file(MAKE_DIRECTORY ${IRX_GEN_DIR}) - - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/freesio2_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freesio2.irx ${IRX_GEN_DIR}/freesio2_irx.c freesio2_irx - DEPENDS ${IRX_DIR}/freesio2.irx - COMMENT "Embedding freesio2.irx" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/mcman_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/mcman.irx ${IRX_GEN_DIR}/mcman_irx.c mcman_irx - DEPENDS ${IRX_DIR}/mcman.irx - COMMENT "Embedding mcman.irx" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/mcserv_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/mcserv.irx ${IRX_GEN_DIR}/mcserv_irx.c mcserv_irx - DEPENDS ${IRX_DIR}/mcserv.irx - COMMENT "Embedding mcserv.irx" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/freepad_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freepad.irx ${IRX_GEN_DIR}/freepad_irx.c freepad_irx - DEPENDS ${IRX_DIR}/freepad.irx - COMMENT "Embedding freepad.irx" - ) - # We need the USB mass storage IRX modules for writing gmon.out when not running from host: and for keyboard support - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/usbd_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/usbd.irx ${IRX_GEN_DIR}/usbd_irx.c usbd_irx - DEPENDS ${IRX_DIR}/usbd.irx - COMMENT "Embedding usbd.irx" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/ps2kbd_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/ps2kbd.irx ${IRX_GEN_DIR}/ps2kbd_irx.c ps2kbd_irx - DEPENDS ${IRX_DIR}/ps2kbd.irx - COMMENT "Embedding ps2kbd.irx" - ) - if(AUDIO_BACKEND STREQUAL "ps2") - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/freesd_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freesd.irx ${IRX_GEN_DIR}/freesd_irx.c freesd_irx - DEPENDS ${IRX_DIR}/freesd.irx - COMMENT "Embedding freesd.irx" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/audsrv_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/audsrv.irx ${IRX_GEN_DIR}/audsrv_irx.c audsrv_irx - DEPENDS ${IRX_DIR}/audsrv.irx - COMMENT "Embedding audsrv.irx" - ) - endif() - - target_sources(butterscotch PRIVATE ${IRX_GEN_DIR}/freesio2_irx.c ${IRX_GEN_DIR}/mcman_irx.c ${IRX_GEN_DIR}/mcserv_irx.c ${IRX_GEN_DIR}/freepad_irx.c ${IRX_GEN_DIR}/usbd_irx.c ${IRX_GEN_DIR}/ps2kbd_irx.c) - if(AUDIO_BACKEND STREQUAL "ps2") - target_sources(butterscotch PRIVATE ${IRX_GEN_DIR}/freesd_irx.c ${IRX_GEN_DIR}/audsrv_irx.c) - endif() - target_include_directories(butterscotch PRIVATE ${IRX_GEN_DIR}) - - # ===[ gprof Profiling Support ]=== - option(ENABLE_GPROF_PROFILING "Enable gprof profiling for PS2" OFF) - if(ENABLE_GPROF_PROFILING) - add_compile_definitions(GPROF_PROFILING) - target_compile_options(butterscotch PRIVATE -pg) - target_link_options(butterscotch PRIVATE -pg) - - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/bdm_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/bdm.irx ${IRX_GEN_DIR}/bdm_irx.c bdm_irx - DEPENDS ${IRX_DIR}/bdm.irx - COMMENT "Embedding bdm.irx (profiler)" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/bdmfs_fatfs.irx ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c bdmfs_fatfs_irx - DEPENDS ${IRX_DIR}/bdmfs_fatfs.irx - COMMENT "Embedding bdmfs_fatfs.irx (profiler)" - ) - add_custom_command( - OUTPUT ${IRX_GEN_DIR}/usbmass_bd_irx.c - COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/usbmass_bd.irx ${IRX_GEN_DIR}/usbmass_bd_irx.c usbmass_bd_irx - DEPENDS ${IRX_DIR}/usbmass_bd.irx - COMMENT "Embedding usbmass_bd.irx (profiler)" - ) - target_sources(butterscotch PRIVATE - ${IRX_GEN_DIR}/bdm_irx.c - ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c - ${IRX_GEN_DIR}/usbmass_bd_irx.c - ) - endif() - else() - # This block is for when we are developing Butterscotch with CLion! - # ps2sdk and gsKit scatter headers across per-module subdirectories; - # the flat include/ layout only exists after building the SDK. - # We use file(GLOB) to discover all include dirs automatically. - file(GLOB PS2SDK_EE_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/*/include) - file(GLOB PS2SDK_EE_RPC_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/rpc/*/include) - file(GLOB PS2SDK_EE_NETWORK_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/network/*/include) - file(GLOB GSKIT_INCLUDES ${CMAKE_SOURCE_DIR}/gsKit/ee/*/include) - - # _EE is normally set by the PS2 toolchain; without it, tamtypes.h - # refuses to define u64/u32/etc. We set it so CLion can resolve them. - target_compile_definitions(butterscotch PRIVATE _EE) - - target_include_directories(butterscotch PRIVATE - ${PS2SDK_EE_INCLUDES} - ${PS2SDK_EE_RPC_INCLUDES} - ${PS2SDK_EE_NETWORK_INCLUDES} - ${CMAKE_SOURCE_DIR}/ps2sdk/common/include - ${GSKIT_INCLUDES} - # Newlib and GCC built-in headers are build artifacts (not in any repo), - # so these are still extracted from Docker by setup.sh. - ${CMAKE_SOURCE_DIR}/ps2dev-headers/newlib-include - ${CMAKE_SOURCE_DIR}/ps2dev-headers/gcc-include - ) - endif() -elseif(PLATFORM STREQUAL "ps3") - if (NOT ENABLE_LEGACY_GL) - message(FATAL_ERROR "PS3 requires legacy gl!") - endif() - file(GLOB GL_SOURCES src/gl_common/*.c src/gl_legacy/*.c src/image/*.c) - file(GLOB DEBUG_FONT_SOURCES src/debug_font/*.c) - target_sources(butterscotch PRIVATE ${GL_SOURCES} ${DEBUG_FONT_SOURCES}) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_legacy) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/debug_font) - target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) - - # ps3gl - file(GLOB PS3GL_SOURCES vendor/ps3gl/*.c) - add_library(ps3gl STATIC ${PS3GL_SOURCES}) - target_include_directories(ps3gl SYSTEM PUBLIC vendor/ps3gl) - target_compile_options(ps3gl PRIVATE -w) - - # mojoal - add_library(mojoal STATIC vendor/mojoal/mojoal.c) - target_include_directories(mojoal SYSTEM PUBLIC vendor/mojoal) - target_compile_definitions(mojoal PRIVATE AL_LIBTYPE_STATIC) - target_compile_options(mojoal PRIVATE -w) - - # Butterscotch VM/interpreter profiler - option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" OFF) - if(ENABLE_VM_GML_PROFILER) - add_compile_definitions(ENABLE_VM_GML_PROFILER) - endif() - - # Butterscotch VM/interpreter tracing - option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" OFF) - if(ENABLE_VM_TRACING) - add_compile_definitions(ENABLE_VM_TRACING) - endif() - - # Butterscotch VM opcode count profiler - option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) - if(ENABLE_VM_OPCODE_PROFILER) - add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) - endif() - - # Spatial grid logs - option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) - if(ENABLE_SPATIAL_GRID_LOGS) - add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) - endif() - - # VM unknown/stubbed function logs - option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" OFF) - if(ENABLE_VM_STUB_LOGS) - add_compile_definitions(ENABLE_VM_STUB_LOGS) - endif() - - # stb_image - target_include_directories(butterscotch PUBLIC vendor/stb/image) - - # Platform identifier for PS3-specific code paths - add_compile_definitions(PLATFORM_PS3) - add_compile_definitions(AL_LIBTYPE_STATIC) - - set(CMAKE_EXE_LINKER_FLAGS "-mhard-float -fmodulo-sched -Wl,--gc-sections -L$ENV{PS3DEV}/ppu/lib -L$ENV{PS3DEV}/portlibs/ppu/lib") - - find_package(SDL2 REQUIRED) - target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) - # mojoal calls SDL atomics/threads, so SDL2 must link after it (static link order) - target_link_libraries(mojoal PUBLIC ${SDL2_LIBRARIES}) - target_link_libraries(butterscotch PRIVATE bzip2 sha1 ps3gl mojoal ${SDL2_LIBRARIES} gcm_sys rsx sysutil io audio rt lv2 m stb_ds stb_vorbis) -elseif(PLATFORM STREQUAL "vita") -else() - message(FATAL_ERROR "Unknown platform! ${PLATFORM}") -endif() +cmake_minimum_required(VERSION 3.21) + +if(PLATFORM STREQUAL "ps3") +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ppu.cmake) +endif() + +if(PLATFORM STREQUAL "vita") + +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(DEFINED ENV{VITASDK}) + set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") + else() + message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") + endif() +endif() + +set(BACKEND "sdl2") + +elseif(PLATFORM STREQUAL "switch") +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(NOT DEFINED ENV{DEVKITPRO}) + message(FATAL_ERROR "Please define DEVKITPRO to point to your SDK path!") + endif() + set(CMAKE_TOOLCHAIN_FILE "$ENV{DEVKITPRO}/cmake/Switch.cmake" CACHE PATH "toolchain file") +endif() + +set(BACKEND "sdl2") + +endif() + +project(butterscotch C) + +if (PLATFORM STREQUAL "vita") +include("${VITASDK}/share/vita.cmake" REQUIRED) +set(VITA_APP_NAME "Butterscotch") +set(VITA_TITLEID "BUTTRSTCH") +set(VITA_VERSION "01.00") +set(VITA_MKSFOEX_FLAGS "-d ATTRIBUTE2=12") +endif() + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +if(MSVC) + if(WERROR) + add_compile_options(/WX) + endif() +else() + add_compile_options(-Wall -Wextra -Wvla) + if(WERROR) + add_compile_options(-Werror) + endif() +endif() + +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + if(MSVC) + # equivalent to -fomit-frame-pointer + add_compile_options(/Oy) + else() + add_compile_options(-ffast-math -fno-finite-math-only) + + # some targets don't support -fomit-frame-pointer IIRC + include(CheckCCompilerFlag) + check_c_compiler_flag("-fomit-frame-pointer" HAS_FOMIT_FRAME_POINTER) + if(HAS_FOMIT_FRAME_POINTER) + add_compile_options(-fomit-frame-pointer) + endif() + endif() +endif() + +set(PLATFORM "cli" CACHE STRING "Platform backend") +set(BACKEND "" CACHE STRING "Desktop platform backend") +set(AUDIO_BACKEND "" CACHE STRING "Audio backend") + +if(PLATFORM STREQUAL "cli" AND BACKEND STREQUAL "") + message(FATAL_ERROR "You need to set a BACKEND!") +endif() + +# Build metadata +set(BUTTERSCOTCH_COMMIT_HASH "unknown" CACHE STRING "Git commit hash") +set(BUTTERSCOTCH_COMMIT_DATE "unknown" CACHE STRING "Git commit date") +add_compile_definitions( + BUTTERSCOTCH_COMMIT_HASH="${BUTTERSCOTCH_COMMIT_HASH}" + BUTTERSCOTCH_COMMIT_DATE="${BUTTERSCOTCH_COMMIT_DATE}" +) + +# Audio backend defaults +if(AUDIO_BACKEND STREQUAL "") + if(PLATFORM STREQUAL "web") + set(AUDIO_BACKEND "web") + elseif(PLATFORM STREQUAL "web-meta") + set(AUDIO_BACKEND "none") + elseif(PLATFORM STREQUAL "ps3" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") + set(AUDIO_BACKEND "openal") + elseif(PLATFORM STREQUAL "ps2") + set(AUDIO_BACKEND "ps2") + else() + set(AUDIO_BACKEND "miniaudio") + endif() +endif() + +if(AUDIO_BACKEND STREQUAL "openal") + file(GLOB AUDIO_SOURCES src/audio/openal/*.c) +elseif(AUDIO_BACKEND STREQUAL "miniaudio") + file(GLOB AUDIO_SOURCES src/audio/miniaudio/*.c) + if(PLATFORM STREQUAL "vita") + add_compile_definitions(MA_NO_RUNTIME_LINKING) + endif() +elseif(AUDIO_BACKEND STREQUAL "web") + file(GLOB AUDIO_SOURCES src/audio/web/*.c src/audio/miniaudio/*.c) +elseif(AUDIO_BACKEND STREQUAL "ps2") + file(GLOB AUDIO_SOURCES src/audio/ps2/*.c) +elseif(NOT AUDIO_BACKEND STREQUAL "none") + message(FATAL_ERROR "Invalid AUDIO_BACKEND!") +endif() + +# To avoid unused code in production builds that are only used for a single game (example: PlayStation 2 target), we can enable/disable specific features +# +# If only a single WAD version is enabled, the checks will be collapsed and removed by the compiler during build time, reducing code size and improving +# performance on low end hardware! +option(ENABLE_WAD14 "Enable support for WAD Version 14 and below" ON) +option(ENABLE_WAD16 "Enable support for WAD Version 15/16" ON) +option(ENABLE_WAD17 "Enable support for WAD Version 17" ON) +option(ENABLE_LEGACY_GL "Enable the legacy OpenGL renderer" ON) +if(PLATFORM STREQUAL "switch") + set(ENABLE_LEGACY_GL OFF CACHE BOOL "Enable the legacy OpenGL renderer" FORCE) +endif() +option(ENABLE_MODERN_GL "Enable the modern OpenGL renderer" ON) +option(ENABLE_NOOP_RENDERER "Enable the no-op renderer (headless stub, no drawing)" OFF) +# Noop renderer is exclusive to the noop desktop backend (no window, no GL). +# Auto-enable for BACKEND=noop and reject otherwise. +if(BACKEND STREQUAL "noop") + set(ENABLE_NOOP_RENDERER ON CACHE BOOL "Enable the no-op renderer (headless stub, no drawing)" FORCE) + set(ENABLE_LEGACY_GL OFF CACHE BOOL "Enable the legacy OpenGL renderer" FORCE) + set(ENABLE_MODERN_GL OFF CACHE BOOL "Enable the modern OpenGL renderer" FORCE) +endif() +if(ENABLE_NOOP_RENDERER AND NOT BACKEND STREQUAL "noop") + message(FATAL_ERROR "ENABLE_NOOP_RENDERER is exclusive to BACKEND=noop") +endif() +if(NOT ENABLE_WAD14 AND NOT ENABLE_WAD16 AND NOT ENABLE_WAD17) + message(FATAL_ERROR "You need to build Butterscotch with at least one WAD version enabled!") +endif() +if(ENABLE_WAD14) + add_compile_definitions(ENABLE_WAD14) +endif() +if(ENABLE_WAD16) + add_compile_definitions(ENABLE_WAD16) +endif() +if(ENABLE_WAD17) + add_compile_definitions(ENABLE_WAD17) +endif() +if(ENABLE_LEGACY_GL) + add_compile_definitions(ENABLE_LEGACY_GL) +endif() +if(ENABLE_MODERN_GL) + add_compile_definitions(ENABLE_MODERN_GL) +endif() +if(ENABLE_NOOP_RENDERER) + add_compile_definitions(ENABLE_NOOP_RENDERER) +endif() + +if(PLATFORM STREQUAL "web-meta") + # Metadata-only build: just the data.win parser and its direct deps. No VM, no runner, no I/O subsystems. + set(SOURCES + src/data_win.c + src/binary_reader.c + src/log.c + src/stb_ds.c + ) +else() + file(GLOB SOURCES src/*.c) + # These platforms haven't been converted to the refactored system yet. + # This list should NEVER grow, all new platforms should use the new system. + if(PLATFORM STREQUAL "ps2" OR PLATFORM STREQUAL "ps3" OR PLATFORM STREQUAL "web" OR PLATFORM STREQUAL "android") + list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/loop.c") + endif() +endif() +# Platform specific files builds +file(GLOB PLATFORM_SOURCES src/${PLATFORM}/*.c) + +if(PLATFORM STREQUAL "android") + add_library(butterscotch SHARED ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) +else() + add_executable(butterscotch ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) +endif() + +target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src) +target_include_directories(butterscotch PRIVATE src/${PLATFORM}) + +if(AUDIO_BACKEND STREQUAL "openal") + target_include_directories(butterscotch PUBLIC src/audio/openal) + add_compile_definitions(USE_OPENAL) + if(APPLE) + set(AUDIO_LIBRARIES "-framework OpenAL") + elseif(PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") + set(AUDIO_LIBRARIES openal pthread) + elseif(NOT PLATFORM STREQUAL "ps3") + find_package(OpenAL REQUIRED) + target_include_directories(butterscotch PUBLIC "${OPENAL_INCLUDE_DIR}") + set(AUDIO_LIBRARIES "${OPENAL_LIBRARY}") + endif() +elseif(AUDIO_BACKEND STREQUAL "miniaudio") + target_include_directories(butterscotch SYSTEM PUBLIC vendor/miniaudio) + target_include_directories(butterscotch PUBLIC src/audio/miniaudio) + add_compile_definitions(USE_MINIAUDIO) + if (NOT WIN32) + set(AUDIO_LIBRARIES pthread) + endif() +elseif(AUDIO_BACKEND STREQUAL "web") + target_include_directories(butterscotch SYSTEM PUBLIC vendor/miniaudio) + target_include_directories(butterscotch PUBLIC src/audio/web) + target_include_directories(butterscotch PUBLIC src/audio/miniaudio) + add_compile_definitions(USE_WEB_AUDIO) +elseif(AUDIO_BACKEND STREQUAL "ps2") + target_include_directories(butterscotch PUBLIC src/audio/ps2) + add_compile_definitions(USE_PS2_AUDIO) +endif() + +# stb_ds +add_library(stb_ds INTERFACE) +target_include_directories(stb_ds SYSTEM INTERFACE ${CMAKE_SOURCE_DIR}/vendor/stb/ds) + +# stb_vorbis +add_library(stb_vorbis INTERFACE) +target_include_directories(stb_vorbis SYSTEM INTERFACE ${CMAKE_SOURCE_DIR}/vendor/stb/vorbis) + +# RFC 1321 reference MD5 implementation +target_sources(butterscotch PRIVATE vendor/md5/md5.c) +target_include_directories(butterscotch PUBLIC vendor/md5) + +# Steve Reid's SHA1 implementation +add_library(sha1 STATIC vendor/sha1/sha1.c) +target_include_directories(sha1 SYSTEM PUBLIC vendor/sha1) +target_compile_options(sha1 PRIVATE -w) + +# Base64 implementation +target_sources(butterscotch PRIVATE vendor/base64/base64.c) +target_include_directories(butterscotch PUBLIC vendor/base64) + +# bzip2 +add_library(bzip2 STATIC + vendor/bzip2/bz_internal_error.c + vendor/bzip2/bzlib.c + vendor/bzip2/crctable.c + vendor/bzip2/decompress.c + vendor/bzip2/huffman.c + vendor/bzip2/randtable.c +) +target_include_directories(bzip2 PUBLIC vendor/bzip2) +target_compile_options(bzip2 PRIVATE -w) + +# Spatial grid logs +option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) +if(ENABLE_SPATIAL_GRID_LOGS) + add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) +endif() + +# VM Exceptions logs +option(ENABLE_VM_EXCEPTIONS_LOGS "Enable VM Exceptions logs" OFF) +if(ENABLE_VM_EXCEPTIONS_LOGS) + add_compile_definitions(ENABLE_VM_EXCEPTIONS_LOGS) +endif() + +if(PLATFORM STREQUAL "cli" OR PLATFORM STREQUAL "vita" OR PLATFORM STREQUAL "switch") + if(PLATFORM STREQUAL "vita") + # Normally, __VITA__ should already be defined, but for some reason, + # in my case, this didn't really work... so just in case, when we're + # building for the Vita, just force-feed these... + add_compile_definitions(__VITA__) + add_compile_definitions(PLATFORM_VITA) + + set(VM_GML_PROFILER_DEFAULT OFF) + set(VM_TRACING_DEFAULT OFF) + set(VM_OPCODE_PROFILER_DEFAULT OFF) + set(VM_STUB_LOGS_DEFAULT OFF) + elseif(PLATFORM STREQUAL "switch") + add_compile_definitions(PLATFORM_SWITCH) + + set(VM_GML_PROFILER_DEFAULT OFF) + set(VM_TRACING_DEFAULT OFF) + set(VM_OPCODE_PROFILER_DEFAULT OFF) + set(VM_STUB_LOGS_DEFAULT OFF) + else() + set(VM_GML_PROFILER_DEFAULT ON) + set(VM_TRACING_DEFAULT ON) + set(VM_OPCODE_PROFILER_DEFAULT ON) + set(VM_STUB_LOGS_DEFAULT ON) + endif() + # Matches the GitHub Actions container flags (FORTIFY requires building with optimizations enabled!) + target_compile_options(butterscotch PRIVATE "$<$:-U_FORTIFY_SOURCE;-D_FORTIFY_SOURCE=2>") + + if(NOT ENABLE_LEGACY_GL AND NOT ENABLE_MODERN_GL AND NOT ENABLE_NOOP_RENDERER) + message(FATAL_ERROR "You must enable at least one renderer!") + endif() + file(GLOB GL_SOURCES src/image/*.c src/gl_common/*.c) + if(ENABLE_LEGACY_GL) + file(GLOB GL_SOURCES ${GL_SOURCES} src/gl_legacy/*.c) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_legacy) + endif() + if(ENABLE_MODERN_GL) + file(GLOB GL_SOURCES ${GL_SOURCES} src/gl/*.c) + endif() + target_sources(butterscotch PRIVATE ${GL_SOURCES}) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) + if (MSVC) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/compat/getopt) + if (IS_GDK) + add_compile_definitions(NO_STRINGS_H) + endif() + add_compile_definitions(NO_STRTOK_R) + add_compile_definitions(NO_STRCASECMP) + endif() + + # Butterscotch VM/interpreter profiler + option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" ${VM_GML_PROFILER_DEFAULT}) + if(ENABLE_VM_GML_PROFILER) + add_compile_definitions(ENABLE_VM_GML_PROFILER) + endif() + + # Butterscotch VM/interpreter tracing + option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" ${VM_TRACING_DEFAULT}) + if(ENABLE_VM_TRACING) + add_compile_definitions(ENABLE_VM_TRACING) + endif() + + # Butterscotch VM opcode count profiler + option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" ${VM_OPCODE_PROFILER_DEFAULT}) + if(ENABLE_VM_OPCODE_PROFILER) + add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) + endif() + + # VM unknown/stubbed function logs + option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" ${VM_STUB_LOGS_DEFAULT}) + if(ENABLE_VM_STUB_LOGS) + add_compile_definitions(ENABLE_VM_STUB_LOGS) + endif() + + # stb_image + target_include_directories(butterscotch PUBLIC vendor/stb/image) + + set(PLATFORM_LIBRARIES bzip2 stb_ds sha1 stb_vorbis) + if(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") + # GLAD + add_library(glad STATIC vendor/glad/src/glad.c) + target_include_directories(glad PUBLIC vendor/glad/include) + if(NOT IS_GDK) + target_compile_options(glad PRIVATE -Wno-unused-but-set-variable) + endif() + set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} glad) + endif() + if(NOT MSVC) + set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} m) + endif() + if(WIN32) + set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} opengl32 gdi32 winmm) + elseif(NOT PLATFORM STREQUAL "vita" AND NOT PLATFORM STREQUAL "switch") + set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${CMAKE_DL_LIBS}) + endif() + + if(BACKEND STREQUAL "glfw3") + add_compile_definitions(USE_GLFW3) + + if(MINGW) + find_package(glfw3 CONFIG REQUIRED) + + # Target Windows 7+ (avoids referencing newer APIs like MapViewOfFileNuma2 that MinGW import libs don't provide) + # https://github.com/mirror/mingw-w64/blob/master/mingw-w64-headers/include/sdkddkver.h + target_compile_definitions(butterscotch PRIVATE _WIN32_WINNT=0x0601 NTDDI_VERSION=0x06010000 WIN32_LEAN_AND_MEAN) + target_link_options(butterscotch PRIVATE -static) + set(BACKEND_LIBRARIES glfw opengl32 gdi32 winmm) + elseif(MSVC) + target_compile_definitions(butterscotch PRIVATE WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS) + find_package(glfw3 CONFIG REQUIRED) + set(BACKEND_LIBRARIES glfw opengl32 gdi32 winmm) + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(GLFW3 REQUIRED glfw3) + target_include_directories(butterscotch PRIVATE ${GLFW3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${GLFW3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${GLFW3_LIBRARIES}) + endif() + elseif(BACKEND STREQUAL "glfw2") + add_compile_definitions(USE_GLFW2) + + find_package(PkgConfig REQUIRED) + pkg_check_modules(GLFW2 REQUIRED libglfw) + target_include_directories(butterscotch PRIVATE ${GLFW2_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${GLFW2_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${GLFW2_LIBRARIES}) + elseif(BACKEND STREQUAL "sdl1") + add_compile_definitions(USE_SDL1) + + find_package(SDL REQUIRED) + target_include_directories(butterscotch PUBLIC ${SDL_INCLUDE_DIR}) + set(BACKEND_LIBRARIES ${SDL_LIBRARY}) + elseif(BACKEND STREQUAL "sdl2") + add_compile_definitions(USE_SDL2) + + if(MSVC) + if(DEFINED SDL2_DIR OR DEFINED ENV{SDL2_DIR}) + find_package(SDL2 CONFIG REQUIRED) + if(TARGET SDL2::SDL2main) + set(BACKEND_LIBRARIES SDL2::SDL2main SDL2::SDL2) + else() + set(BACKEND_LIBRARIES SDL2::SDL2) + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 REQUIRED sdl2) + target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 REQUIRED sdl2) + target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) + endif() + elseif(BACKEND STREQUAL "sdl3") + add_compile_definitions(USE_SDL3) + + if(MSVC) + if(DEFINED SDL3_DIR OR DEFINED ENV{SDL3_DIR}) + find_package(SDL3 CONFIG REQUIRED) + set(BACKEND_LIBRARIES SDL3::SDL3) + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + endif() + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL3 REQUIRED sdl3) + target_include_directories(butterscotch PRIVATE ${SDL3_INCLUDE_DIRS}) + target_link_directories(butterscotch PRIVATE ${SDL3_LIBRARY_DIRS}) + set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) + endif() + elseif(BACKEND STREQUAL "appkit") + add_compile_definitions(USE_APPKIT) + target_compile_definitions(butterscotch PRIVATE GL_SILENCE_DEPRECATION) + set(BACKEND_LIBRARIES "-framework Cocoa" "-framework GameController") + elseif(BACKEND STREQUAL "noop") + if(NOT ENABLE_NOOP_RENDERER) + message(FATAL_ERROR "BACKEND=noop requires ENABLE_NOOP_RENDERER=ON") + endif() + add_compile_definitions(USE_NOOP) + set(BACKEND_LIBRARIES "") + endif() + if (PLATFORM STREQUAL "vita") + target_link_libraries(butterscotch PRIVATE + ${BACKEND_LIBRARIES} + ${AUDIO_LIBRARIES} + ${PLATFORM_LIBRARIES} + vitaGL + stdc++ + SceShaccCgExt + taihen_stub + SceShaccCg_stub + ) + + vita_create_self(eboot.bin butterscotch UNSAFE) + vita_create_vpk(Butterscotch.vpk ${VITA_TITLEID} eboot.bin + VERSION ${VITA_VERSION} + NAME ${VITA_APP_NAME} + ) + else() + target_link_libraries(butterscotch PRIVATE ${BACKEND_LIBRARIES} ${AUDIO_LIBRARIES} ${PLATFORM_LIBRARIES}) + + if (PLATFORM STREQUAL "switch") + target_link_libraries(butterscotch PRIVATE GLESv2 stdc++) + nx_generate_nacp(OUTPUT Butterscotch.nacp NAME "Butterscotch" AUTHOR "Butterscotch" VERSION "1.0.0") + nx_create_nro(butterscotch NACP Butterscotch.nacp) + endif() + endif() + if(BACKEND STREQUAL "appkit") + target_sources(butterscotch PRIVATE src/backends/${BACKEND}.m) + else() + target_sources(butterscotch PRIVATE src/backends/${BACKEND}.c) + endif() + + # Enable AddressSanitizer by default in Debug builds + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(ENABLE_ASAN_DEFAULT ON) + else() + set(ENABLE_ASAN_DEFAULT OFF) + endif() + set(ENABLE_ASAN ${ENABLE_ASAN_DEFAULT} CACHE BOOL "Enable AddressSanitizer") + if(ENABLE_ASAN AND NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") + target_compile_options(butterscotch PRIVATE -fsanitize=address -fno-omit-frame-pointer) + target_link_options(butterscotch PRIVATE -fsanitize=address) + endif() + + #gamecontrollerdb + add_custom_command(TARGET butterscotch POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_SOURCE_DIR}/vendor/gamecontrollerdb.txt + $/gamecontrollerdb.txt + ) +elseif(PLATFORM STREQUAL "web") + if (NOT ENABLE_MODERN_GL) + message(FATAL_ERROR "Web requires modern gl!") + endif() + file(GLOB GL_SOURCES src/gl/*.c src/gl_common/*.c src/image/*.c) + target_sources(butterscotch PRIVATE ${GL_SOURCES}) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) + + # stb_image + target_include_directories(butterscotch PUBLIC vendor/stb/image) + + # bzip2 + target_link_libraries(butterscotch PRIVATE bzip2 stb_ds sha1 stb_vorbis) + + set_target_properties(butterscotch PROPERTIES SUFFIX ".mjs") + + target_link_options( + butterscotch + PRIVATE + "-sMODULARIZE=1" + "-sEXPORT_ES6=1" + "-sENVIRONMENT=worker" + "-sWASMFS=1" + "-sEXPORTED_RUNTIME_METHODS=['HEAP8', 'HEAPU8', 'HEAPF32', 'ccall', 'cwrap', 'specialHTMLTargets', 'UTF8ToString']" + "-sEXPORTED_FUNCTIONS=['_main', '_mountOpfs', '_startRunner', '_stopRunner', '_malloc', '_free', '_getKeyDownPtr', '_getKeyUpPtr', '_getKeyCount', '_setAudioSampleRate', '_pullAudioFrames']" + "-sOFFSCREENCANVAS_SUPPORT=1" + "-sOFFSCREEN_FRAMEBUFFER=1" + "-sMIN_WEBGL_VERSION=2" + "-sMAX_WEBGL_VERSION=2" + "-sFULL_ES3=1" + "-sALLOW_MEMORY_GROWTH" + "-sSHARED_MEMORY=1" + "-sPTHREAD_POOL_SIZE=4" + "-pthread" + ) + + target_compile_options(butterscotch PRIVATE "-pthread") +elseif(PLATFORM STREQUAL "web-meta") + set_target_properties(butterscotch PROPERTIES + SUFFIX ".mjs" + OUTPUT_NAME "butterscotch-meta" + ) + + target_link_libraries(butterscotch PRIVATE stb_ds) + + target_link_options( + butterscotch + PRIVATE + "-sMODULARIZE=1" + "-sEXPORT_ES6=1" + "-sENVIRONMENT=web" + "-sEXPORTED_RUNTIME_METHODS=['HEAPU8', 'ccall', 'cwrap', 'UTF8ToString', 'FS']" + "-sEXPORTED_FUNCTIONS=['_main', '_parseDataWin', '_freeDataWin', '_getGameName', '_getGameDisplayName', '_getMajorVersion', '_getMinorVersion', '_getRelease', '_getBuild', '_getDefaultWindowWidth', '_getDefaultWindowHeight', '_malloc', '_free']" + "-sALLOW_MEMORY_GROWTH=1" + "-sFORCE_FILESYSTEM=1" + ) +elseif(PLATFORM STREQUAL "android") + if (NOT ENABLE_MODERN_GL) + message(FATAL_ERROR "Android requires modern gl!") + endif() + file(GLOB GL_SOURCES src/gl/*.c src/gl_common/*.c src/image/*.c) + target_sources(butterscotch PRIVATE ${GL_SOURCES}) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) + add_compile_definitions(ENABLE_GLES PLATFORM_ANDROID) + + # Butterscotch VM/interpreter profiler + option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" ON) + if(ENABLE_VM_GML_PROFILER) + add_compile_definitions(ENABLE_VM_GML_PROFILER) + endif() + + # Butterscotch VM/interpreter tracing + option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" ON) + if(ENABLE_VM_TRACING) + add_compile_definitions(ENABLE_VM_TRACING) + endif() + + # Butterscotch VM opcode count profiler + option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) + if(ENABLE_VM_OPCODE_PROFILER) + add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) + endif() + + # Spatial grid logs + option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) + if(ENABLE_SPATIAL_GRID_LOGS) + add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) + endif() + + # VM unknown/stubbed function logs + option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" ON) + if(ENABLE_VM_STUB_LOGS) + add_compile_definitions(ENABLE_VM_STUB_LOGS) + endif() + + # stb_image + target_include_directories(butterscotch PUBLIC vendor/stb/image) + # stb_vorbis (for miniaudio's OGG decoding) + target_include_directories(butterscotch PUBLIC vendor/stb/vorbis) + # bzip2 + target_link_libraries(butterscotch PRIVATE bzip2) + + # Android NDK system libraries: + # - log: __android_log_* + # - GLESv3: OpenGL ES 3.0 functions + # - OpenSLES: miniaudio's OpenSL ES backend (it dlopen's libaaudio.so at runtime when available, so no link-time aaudio dep) + target_link_libraries(butterscotch PRIVATE log GLESv3 OpenSLES bzip2 stb_ds sha1 stb_vorbis) +elseif(PLATFORM STREQUAL "ps2") + file(GLOB DEBUG_FONT_SOURCES src/debug_font/*.c) + target_sources(butterscotch PRIVATE ${DEBUG_FONT_SOURCES}) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/debug_font) + + # The PS2 EE has a single-precision FPU only, so double is software-emulated + add_compile_definitions(USE_FLOAT_REALS) + # By disabling Int64 support, we can fit the entire RValue struct in 8 bytes, improving performance and memory usage + add_compile_definitions(NO_RVALUE_INT64) + + # Butterscotch VM/interpreter profiler + option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" OFF) + if(ENABLE_VM_GML_PROFILER) + add_compile_definitions(ENABLE_VM_GML_PROFILER) + endif() + + # Butterscotch VM/interpreter tracing + option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" OFF) + if(ENABLE_VM_TRACING) + add_compile_definitions(ENABLE_VM_TRACING) + endif() + + # Butterscotch VM opcode count profiler + option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) + if(ENABLE_VM_OPCODE_PROFILER) + add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) + endif() + + # Spatial grid logs + option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) + if(ENABLE_SPATIAL_GRID_LOGS) + add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) + endif() + + # VM unknown/stubbed function logs + option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" OFF) + if(ENABLE_VM_STUB_LOGS) + add_compile_definitions(ENABLE_VM_STUB_LOGS) + endif() + + # Platform identifier for PS2-specific code paths (e.g., scratchpad allocation) + add_compile_definitions(PLATFORM_PS2) + + # PS2 renderer hot path logs + option(ENABLE_PS2_RENDERER_LOGS "Enable hot path logs in the PS2 renderer" OFF) + if(ENABLE_PS2_RENDERER_LOGS) + add_compile_definitions(ENABLE_PS2_RENDERER_LOGS) + endif() + + # -fsingle-precision-constant: Treat unsuffixed float constants as single-precision to avoid accidental float->double promotions on platforms with no hardware double + # -Werror=double-promotion: Warn when something is being promoted to a double + # -Wno-format: because there are too many formatting issues that, at the end of the day, do not matter + target_compile_options(butterscotch PRIVATE -fsingle-precision-constant -Werror=double-promotion -Wno-format) + + if(PS2) + # Compiling on the Docker container + target_include_directories(butterscotch PRIVATE $ENV{PS2SDK}/ee/include $ENV{PS2SDK}/common/include $ENV{PS2DEV}/ee/include $ENV{GSKIT}/include) + target_link_directories(butterscotch PRIVATE $ENV{PS2SDK}/ee/lib $ENV{GSKIT}/lib) + target_link_libraries(${AUDIO_LIBRARIES} butterscotch gskit dmakit audsrv pad mc kbd patches kernel c m stb_ds sha1) + + # Embed ps2sdk IRX modules (freesio2, freepad) as C arrays via bin2c + # This avoids loading from rom0: which has compatibility issues between fat/slim PS2 + set(IRX_DIR $ENV{PS2SDK}/iop/irx) + set(IRX_GEN_DIR ${CMAKE_BINARY_DIR}/generated/irx) + file(MAKE_DIRECTORY ${IRX_GEN_DIR}) + + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/freesio2_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freesio2.irx ${IRX_GEN_DIR}/freesio2_irx.c freesio2_irx + DEPENDS ${IRX_DIR}/freesio2.irx + COMMENT "Embedding freesio2.irx" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/mcman_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/mcman.irx ${IRX_GEN_DIR}/mcman_irx.c mcman_irx + DEPENDS ${IRX_DIR}/mcman.irx + COMMENT "Embedding mcman.irx" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/mcserv_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/mcserv.irx ${IRX_GEN_DIR}/mcserv_irx.c mcserv_irx + DEPENDS ${IRX_DIR}/mcserv.irx + COMMENT "Embedding mcserv.irx" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/freepad_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freepad.irx ${IRX_GEN_DIR}/freepad_irx.c freepad_irx + DEPENDS ${IRX_DIR}/freepad.irx + COMMENT "Embedding freepad.irx" + ) + # We need the USB mass storage IRX modules for writing gmon.out when not running from host: and for keyboard support + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/usbd_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/usbd.irx ${IRX_GEN_DIR}/usbd_irx.c usbd_irx + DEPENDS ${IRX_DIR}/usbd.irx + COMMENT "Embedding usbd.irx" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/ps2kbd_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/ps2kbd.irx ${IRX_GEN_DIR}/ps2kbd_irx.c ps2kbd_irx + DEPENDS ${IRX_DIR}/ps2kbd.irx + COMMENT "Embedding ps2kbd.irx" + ) + if(AUDIO_BACKEND STREQUAL "ps2") + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/freesd_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/freesd.irx ${IRX_GEN_DIR}/freesd_irx.c freesd_irx + DEPENDS ${IRX_DIR}/freesd.irx + COMMENT "Embedding freesd.irx" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/audsrv_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/audsrv.irx ${IRX_GEN_DIR}/audsrv_irx.c audsrv_irx + DEPENDS ${IRX_DIR}/audsrv.irx + COMMENT "Embedding audsrv.irx" + ) + endif() + + target_sources(butterscotch PRIVATE ${IRX_GEN_DIR}/freesio2_irx.c ${IRX_GEN_DIR}/mcman_irx.c ${IRX_GEN_DIR}/mcserv_irx.c ${IRX_GEN_DIR}/freepad_irx.c ${IRX_GEN_DIR}/usbd_irx.c ${IRX_GEN_DIR}/ps2kbd_irx.c) + if(AUDIO_BACKEND STREQUAL "ps2") + target_sources(butterscotch PRIVATE ${IRX_GEN_DIR}/freesd_irx.c ${IRX_GEN_DIR}/audsrv_irx.c) + endif() + target_include_directories(butterscotch PRIVATE ${IRX_GEN_DIR}) + + # ===[ gprof Profiling Support ]=== + option(ENABLE_GPROF_PROFILING "Enable gprof profiling for PS2" OFF) + if(ENABLE_GPROF_PROFILING) + add_compile_definitions(GPROF_PROFILING) + target_compile_options(butterscotch PRIVATE -pg) + target_link_options(butterscotch PRIVATE -pg) + + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/bdm_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/bdm.irx ${IRX_GEN_DIR}/bdm_irx.c bdm_irx + DEPENDS ${IRX_DIR}/bdm.irx + COMMENT "Embedding bdm.irx (profiler)" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/bdmfs_fatfs.irx ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c bdmfs_fatfs_irx + DEPENDS ${IRX_DIR}/bdmfs_fatfs.irx + COMMENT "Embedding bdmfs_fatfs.irx (profiler)" + ) + add_custom_command( + OUTPUT ${IRX_GEN_DIR}/usbmass_bd_irx.c + COMMAND $ENV{PS2SDK}/bin/bin2c ${IRX_DIR}/usbmass_bd.irx ${IRX_GEN_DIR}/usbmass_bd_irx.c usbmass_bd_irx + DEPENDS ${IRX_DIR}/usbmass_bd.irx + COMMENT "Embedding usbmass_bd.irx (profiler)" + ) + target_sources(butterscotch PRIVATE + ${IRX_GEN_DIR}/bdm_irx.c + ${IRX_GEN_DIR}/bdmfs_fatfs_irx.c + ${IRX_GEN_DIR}/usbmass_bd_irx.c + ) + endif() + else() + # This block is for when we are developing Butterscotch with CLion! + # ps2sdk and gsKit scatter headers across per-module subdirectories; + # the flat include/ layout only exists after building the SDK. + # We use file(GLOB) to discover all include dirs automatically. + file(GLOB PS2SDK_EE_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/*/include) + file(GLOB PS2SDK_EE_RPC_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/rpc/*/include) + file(GLOB PS2SDK_EE_NETWORK_INCLUDES ${CMAKE_SOURCE_DIR}/ps2sdk/ee/network/*/include) + file(GLOB GSKIT_INCLUDES ${CMAKE_SOURCE_DIR}/gsKit/ee/*/include) + + # _EE is normally set by the PS2 toolchain; without it, tamtypes.h + # refuses to define u64/u32/etc. We set it so CLion can resolve them. + target_compile_definitions(butterscotch PRIVATE _EE) + + target_include_directories(butterscotch PRIVATE + ${PS2SDK_EE_INCLUDES} + ${PS2SDK_EE_RPC_INCLUDES} + ${PS2SDK_EE_NETWORK_INCLUDES} + ${CMAKE_SOURCE_DIR}/ps2sdk/common/include + ${GSKIT_INCLUDES} + # Newlib and GCC built-in headers are build artifacts (not in any repo), + # so these are still extracted from Docker by setup.sh. + ${CMAKE_SOURCE_DIR}/ps2dev-headers/newlib-include + ${CMAKE_SOURCE_DIR}/ps2dev-headers/gcc-include + ) + endif() +elseif(PLATFORM STREQUAL "ps3") + if (NOT ENABLE_LEGACY_GL) + message(FATAL_ERROR "PS3 requires legacy gl!") + endif() + file(GLOB GL_SOURCES src/gl_common/*.c src/gl_legacy/*.c src/image/*.c) + file(GLOB DEBUG_FONT_SOURCES src/debug_font/*.c) + target_sources(butterscotch PRIVATE ${GL_SOURCES} ${DEBUG_FONT_SOURCES}) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_legacy) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/image) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/debug_font) + target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src/gl_common) + + # ps3gl + file(GLOB PS3GL_SOURCES vendor/ps3gl/*.c) + add_library(ps3gl STATIC ${PS3GL_SOURCES}) + target_include_directories(ps3gl SYSTEM PUBLIC vendor/ps3gl) + target_compile_options(ps3gl PRIVATE -w) + + # mojoal + add_library(mojoal STATIC vendor/mojoal/mojoal.c) + target_include_directories(mojoal SYSTEM PUBLIC vendor/mojoal) + target_compile_definitions(mojoal PRIVATE AL_LIBTYPE_STATIC) + target_compile_options(mojoal PRIVATE -w) + + # Butterscotch VM/interpreter profiler + option(ENABLE_VM_GML_PROFILER "Enable Butterscotch VM/interpreter profiler" OFF) + if(ENABLE_VM_GML_PROFILER) + add_compile_definitions(ENABLE_VM_GML_PROFILER) + endif() + + # Butterscotch VM/interpreter tracing + option(ENABLE_VM_TRACING "Enable Butterscotch VM/interpreter tracing checks" OFF) + if(ENABLE_VM_TRACING) + add_compile_definitions(ENABLE_VM_TRACING) + endif() + + # Butterscotch VM opcode count profiler + option(ENABLE_VM_OPCODE_PROFILER "Enable Butterscotch VM opcode count profiler" OFF) + if(ENABLE_VM_OPCODE_PROFILER) + add_compile_definitions(ENABLE_VM_OPCODE_PROFILER) + endif() + + # Spatial grid logs + option(ENABLE_SPATIAL_GRID_LOGS "Enable Spatial Grid logs" OFF) + if(ENABLE_SPATIAL_GRID_LOGS) + add_compile_definitions(ENABLE_SPATIAL_GRID_LOGS) + endif() + + # VM unknown/stubbed function logs + option(ENABLE_VM_STUB_LOGS "Enable VM unknown/stubbed function logs" OFF) + if(ENABLE_VM_STUB_LOGS) + add_compile_definitions(ENABLE_VM_STUB_LOGS) + endif() + + # stb_image + target_include_directories(butterscotch PUBLIC vendor/stb/image) + + # Platform identifier for PS3-specific code paths + add_compile_definitions(PLATFORM_PS3) + add_compile_definitions(AL_LIBTYPE_STATIC) + + set(CMAKE_EXE_LINKER_FLAGS "-mhard-float -fmodulo-sched -Wl,--gc-sections -L$ENV{PS3DEV}/ppu/lib -L$ENV{PS3DEV}/portlibs/ppu/lib") + + find_package(SDL2 REQUIRED) + target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) + # mojoal calls SDL atomics/threads, so SDL2 must link after it (static link order) + target_link_libraries(mojoal PUBLIC ${SDL2_LIBRARIES}) + target_link_libraries(butterscotch PRIVATE bzip2 sha1 ps3gl mojoal ${SDL2_LIBRARIES} gcm_sys rsx sysutil io audio rt lv2 m stb_ds stb_vorbis) +elseif(PLATFORM STREQUAL "vita") +else() + message(FATAL_ERROR "Unknown platform! ${PLATFORM}") +endif() diff --git a/src/xboxone/log.c b/src/xboxone/log.c deleted file mode 100644 index b8c8673e3..000000000 --- a/src/xboxone/log.c +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#include "log.h" - -void platformLog(const logType type, const char *format, va_list va) { - FILE *out = stderr; - switch (type) { - case LOG_TYPE_NORMAL: - out = stdout; - break; - case LOG_TYPE_WARNING: - fputs("Warning: ", out); - break; - case LOG_TYPE_ERROR: - fputs("Error: ", out); - break; - case LOG_TYPE_DEBUG: - fputs("Debug: ", out); - break; - } - vfprintf(out, format, va); -} diff --git a/src/xboxone/main.c b/src/xboxone/main.c deleted file mode 100644 index 4d6010484..000000000 --- a/src/xboxone/main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include - -/* For SDL_main */ -#if defined(USE_SDL1) -#include -#elif defined(USE_SDL2) -#include -#elif defined(USE_SDL3) -#include -#endif - -int main(int argc, char* argv[]) { - (void)argc; - setbuf(stdout, NULL); - setbuf(stderr, NULL); - - CommandLineArgs args = {0}; - - args.exitAtFrame = -1; -#ifdef ENABLE_VM_TRACING - args.traceBytecodeAfterFrame = 0; -#endif - args.speedMultiplier = 1.0; - args.fastForwardSpeed = 0.0; - args.osType = OS_XBOXONE; - args.profilerFramesBetween = 0; - args.loadType = DATAWINLOADTYPE_LOAD_PER_CHUNK; - args.lazyRooms = true; - args.lazyTextures = true; - args.lazyAudio = true; -#if defined(ENABLE_MODERN_GL) - args.renderer = MODERN_GL; -#elif defined(ENABLE_LEGACY_GL) - args.renderer = LEGACY_GL; -#else - args.renderer = SOFTWARE; -#endif - args.dataWinPath = "data.win"; - args.saveFolder = "."; - - int ret = loop(args, argv[0]); - freeCommandLineArgs(&args); - return ret; -} diff --git a/src/xboxone/stb_impl.c b/src/xboxone/stb_impl.c deleted file mode 100644 index 873f3656b..000000000 --- a/src/xboxone/stb_impl.c +++ /dev/null @@ -1,6 +0,0 @@ -#define STB_IMAGE_IMPLEMENTATION -#define STBI_NO_STDIO -#include "stb_image.h" - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "stb_image_write.h" From 1e3717c34e1ed06c9ba40f60f0b43d93bed108d2 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:41:54 +0100 Subject: [PATCH 29/33] fix make build.yml --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d2893834..cccb613a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,8 +25,8 @@ jobs: # Other: # uses: ./.github/workflows/build-other.yml - XboxOne: - uses: ./.github/workflows/build-xboxone.yml + GDK: + uses: ./.github/workflows/build-gdk.yml # Compilers: # uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file From a735269219c7fdf1d58bd8938bf04f4ee0fbc03b Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:44:10 +0100 Subject: [PATCH 30/33] syntax --- .github/workflows/build-gdk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-gdk.yml b/.github/workflows/build-gdk.yml index 83ac93f00..244d0e9f6 100644 --- a/.github/workflows/build-gdk.yml +++ b/.github/workflows/build-gdk.yml @@ -133,7 +133,7 @@ jobs: $sdlSrc = Join-Path $workspace 'vendor\SDL2' $sdlBuild = Join-Path $sdlSrc 'build' $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G "Visual Studio 18 2026" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" + $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G `"Visual Studio 18 2026`" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" Invoke-WithGdkPrompt $cmakeCommand Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`" --config Release" Invoke-WithGdkPrompt "cmake --install `"$sdlBuild`"" From 13c16f918849ba3afe0d2d5692d0dbf5e34fa594 Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:47:30 +0100 Subject: [PATCH 31/33] re-enable cache --- .github/workflows/build-gdk.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-gdk.yml b/.github/workflows/build-gdk.yml index 244d0e9f6..03320376a 100644 --- a/.github/workflows/build-gdk.yml +++ b/.github/workflows/build-gdk.yml @@ -83,15 +83,15 @@ jobs: - name: Install Ninja uses: seanmiddleditch/gha-setup-ninja@v5 - # - name: Cache SDL2 build - # id: cache-sdl2 - # uses: actions/cache@v6 - # with: - # path: ${{ github.workspace }}/vendor/SDL2/install - # key: sdl2-xboxone-${{ runner.os }}-2.32.10-rev2 + - name: Cache SDL2 build + id: cache-sdl2 + uses: actions/cache@v6 + with: + path: ${{ github.workspace }}/vendor/SDL2/install + key: sdl2-gdk-${{ runner.os }}-2.32.10-rev2 - name: Checkout SDL2 - # if: steps.cache-sdl2.outputs.cache-hit != 'true' + if: steps.cache-sdl2.outputs.cache-hit != 'true' uses: actions/checkout@v7 with: repository: libsdl-org/SDL @@ -99,7 +99,7 @@ jobs: path: vendor/SDL2 - name: Build SDL2 from source - # if: steps.cache-sdl2.outputs.cache-hit != 'true' + if: steps.cache-sdl2.outputs.cache-hit != 'true' shell: pwsh run: | function Invoke-WithGdkPrompt { From 2ae841ac83c16490ebc087402dbd56d9177b737d Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:49:23 +0100 Subject: [PATCH 32/33] separate script to invoke gdk --- .github/workflows/build-gdk.yml | 94 +++------------------------------ scripts/invoke-gdk.ps1 | 28 ++++++++++ 2 files changed, 36 insertions(+), 86 deletions(-) create mode 100644 scripts/invoke-gdk.ps1 diff --git a/.github/workflows/build-gdk.yml b/.github/workflows/build-gdk.yml index 03320376a..f11d4cef5 100644 --- a/.github/workflows/build-gdk.yml +++ b/.github/workflows/build-gdk.yml @@ -102,115 +102,37 @@ jobs: if: steps.cache-sdl2.outputs.cache-hit != 'true' shell: pwsh run: | - function Invoke-WithGdkPrompt { - param([string]$Command) - - $gdkPrompt = @( - "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", - "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $gdkPrompt) { - throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' - } - - $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) - $target = $shortcut.TargetPath - $args = $shortcut.Arguments - - if (-not $target) { - throw 'The GDK command prompt shortcut target could not be resolved.' - } - - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline - } - $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' $sdlSrc = Join-Path $workspace 'vendor\SDL2' $sdlBuild = Join-Path $sdlSrc 'build' $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G `"Visual Studio 18 2026`" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" - Invoke-WithGdkPrompt $cmakeCommand - Invoke-WithGdkPrompt "cmake --build `"$sdlBuild`" --config Release" - Invoke-WithGdkPrompt "cmake --install `"$sdlBuild`"" + & $gdkScript $cmakeCommand + & $gdkScript "cmake --build `"$sdlBuild`" --config Release" + & $gdkScript "cmake --install `"$sdlBuild`"" - name: Configure Butterscotch shell: pwsh run: | - function Invoke-WithGdkPrompt { - param([string]$Command) - - $gdkPrompt = @( - "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", - "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $gdkPrompt) { - throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' - } - - $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) - $target = $shortcut.TargetPath - $args = $shortcut.Arguments - - if (-not $target) { - throw 'The GDK command prompt shortcut target could not be resolved.' - } - - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline - } - if (Test-Path "$env:GITHUB_WORKSPACE/build") { Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force } $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' $buildDir = Join-Path $workspace 'build' $sdlDir = Join-Path $workspace 'vendor\SDL2\install' $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G `"Visual Studio 18 2026`" -A x64 -DBACKEND=sdl2 -DIS_GDK=ON -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" - Invoke-WithGdkPrompt $cmakeCommand + & $gdkScript $cmakeCommand - name: Build Butterscotch shell: pwsh run: | - function Invoke-WithGdkPrompt { - param([string]$Command) - - $gdkPrompt = @( - "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", - "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $gdkPrompt) { - throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' - } - - $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) - $target = $shortcut.TargetPath - $args = $shortcut.Arguments - - if (-not $target) { - throw 'The GDK command prompt shortcut target could not be resolved.' - } - - $launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } - $cmdline = $launcher + ' && ' + $Command - cmd.exe /d /s /c $cmdline - } - $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' $buildDir = Join-Path $workspace 'build' - Invoke-WithGdkPrompt "cmake --build `"$buildDir`" --config Release" + & $gdkScript "cmake --build `"$buildDir`" --config Release" - name: Upload artifact uses: actions/upload-artifact@v7 diff --git a/scripts/invoke-gdk.ps1 b/scripts/invoke-gdk.ps1 new file mode 100644 index 000000000..4d038b3b7 --- /dev/null +++ b/scripts/invoke-gdk.ps1 @@ -0,0 +1,28 @@ +param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Command +) + +$gdkPrompt = @( + "${env:ProgramFiles(x86)}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk", + "${env:ProgramFiles}\Microsoft GDK\Command Prompts\Desktop VS 2026 Gaming Command Prompt.lnk" +) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + +if (-not $gdkPrompt) { + throw 'Microsoft GDK Desktop VS 2026 Gaming Command Prompt.lnk was not found.' +} + +$shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($gdkPrompt) +$target = $shortcut.TargetPath +$args = $shortcut.Arguments + +if (-not $target) { + throw 'The GDK command prompt shortcut target could not be resolved.' +} + +$launcher = if ($args) { '"{0}" {1}' -f $target, $args } else { '"{0}"' -f $target } +$cmdline = $launcher + ' && ' + $Command + +cmd.exe /d /s /c $cmdline From c9fcbd04c624eaf2ec2fbad6890f5bdafc66511e Mon Sep 17 00:00:00 2001 From: emiyl Date: Sat, 12 Sep 2026 12:50:58 +0100 Subject: [PATCH 33/33] move to the windows file --- .github/workflows/build-gdk.yml | 141 ---------------------------- .github/workflows/build-windows.yml | 137 +++++++++++++++++++++++++++ .github/workflows/build.yml | 33 +++---- 3 files changed, 152 insertions(+), 159 deletions(-) delete mode 100644 .github/workflows/build-gdk.yml diff --git a/.github/workflows/build-gdk.yml b/.github/workflows/build-gdk.yml deleted file mode 100644 index f11d4cef5..000000000 --- a/.github/workflows/build-gdk.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: GDK builds - -on: - workflow_call: - -jobs: - build-xboxone: - name: Build (GDK) - runs-on: windows-2025 - - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Cache GDK - id: cache-gdk - uses: actions/cache@v4 - with: - path: ${{ runner.temp }}\gdk-cache - key: gdk-${{ runner.os }}-x64 - - - name: Install or restore GDK - shell: pwsh - run: | - $cacheRoot = Join-Path '${{ runner.temp }}' 'gdk-cache' - $installRoots = @( - "${env:ProgramFiles}\Microsoft GDK", - "${env:ProgramFiles(x86)}\Microsoft GDK" - ) - - $gdkRoot = $installRoots | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if ("${{ steps.cache-gdk.outputs.cache-hit }}" -eq "true") { - $cached = @( - (Join-Path $cacheRoot 'Microsoft GDK'), - (Join-Path $cacheRoot 'MicrosoftGDK'), - $cacheRoot - ) | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $cached) { - throw "Cached GDK directory was not found in $cacheRoot." - } - - if (-not $gdkRoot) { - $gdkRoot = "${env:ProgramFiles}\Microsoft GDK" - } - - if (Test-Path $gdkRoot) { - Remove-Item $gdkRoot -Recurse -Force - } - - Copy-Item $cached $gdkRoot -Recurse -Force - } - else { - winget install Microsoft.Gaming.GDK ` - --accept-package-agreements ` - --accept-source-agreements ` - --silent - - $gdkRoot = $installRoots | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $gdkRoot) { - throw "Microsoft GDK was not found under Program Files after installation." - } - - New-Item -ItemType Directory -Force -Path $cacheRoot | Out-Null - Copy-Item $gdkRoot (Join-Path $cacheRoot 'Microsoft GDK') -Recurse -Force - } - - if (-not $gdkRoot) { - throw "Microsoft GDK was not found under Program Files after restore." - } - - "GDK=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append - "GDKX=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Install Ninja - uses: seanmiddleditch/gha-setup-ninja@v5 - - - name: Cache SDL2 build - id: cache-sdl2 - uses: actions/cache@v6 - with: - path: ${{ github.workspace }}/vendor/SDL2/install - key: sdl2-gdk-${{ runner.os }}-2.32.10-rev2 - - - name: Checkout SDL2 - if: steps.cache-sdl2.outputs.cache-hit != 'true' - uses: actions/checkout@v7 - with: - repository: libsdl-org/SDL - ref: release-2.32.10 - path: vendor/SDL2 - - - name: Build SDL2 from source - if: steps.cache-sdl2.outputs.cache-hit != 'true' - shell: pwsh - run: | - $workspace = $env:GITHUB_WORKSPACE - $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' - $sdlSrc = Join-Path $workspace 'vendor\SDL2' - $sdlBuild = Join-Path $sdlSrc 'build' - $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G `"Visual Studio 18 2026`" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" - & $gdkScript $cmakeCommand - & $gdkScript "cmake --build `"$sdlBuild`" --config Release" - & $gdkScript "cmake --install `"$sdlBuild`"" - - - name: Configure Butterscotch - shell: pwsh - run: | - if (Test-Path "$env:GITHUB_WORKSPACE/build") { - Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force - } - - $workspace = $env:GITHUB_WORKSPACE - $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' - $buildDir = Join-Path $workspace 'build' - $sdlDir = Join-Path $workspace 'vendor\SDL2\install' - $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G `"Visual Studio 18 2026`" -A x64 -DBACKEND=sdl2 -DIS_GDK=ON -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" - & $gdkScript $cmakeCommand - - - name: Build Butterscotch - shell: pwsh - run: | - $workspace = $env:GITHUB_WORKSPACE - $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' - $buildDir = Join-Path $workspace 'build' - & $gdkScript "cmake --build `"$buildDir`" --config Release" - - - name: Upload artifact - uses: actions/upload-artifact@v7 - with: - name: butterscotch-gdk - path: build/**/* \ No newline at end of file diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 7722c39a8..20c8d8547 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -162,3 +162,140 @@ jobs: with: name: butterscotch-windows-${{ matrix.arch }} path: build/butterscotch.exe + + + build-x64-gdk: + name: Build (x64 GDK) + runs-on: windows-2025 + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Cache GDK + id: cache-gdk + uses: actions/cache@v4 + with: + path: ${{ runner.temp }}\gdk-cache + key: gdk-${{ runner.os }}-x64 + + - name: Install or restore GDK + shell: pwsh + run: | + $cacheRoot = Join-Path '${{ runner.temp }}' 'gdk-cache' + $installRoots = @( + "${env:ProgramFiles}\Microsoft GDK", + "${env:ProgramFiles(x86)}\Microsoft GDK" + ) + + $gdkRoot = $installRoots | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if ("${{ steps.cache-gdk.outputs.cache-hit }}" -eq "true") { + $cached = @( + (Join-Path $cacheRoot 'Microsoft GDK'), + (Join-Path $cacheRoot 'MicrosoftGDK'), + $cacheRoot + ) | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $cached) { + throw "Cached GDK directory was not found in $cacheRoot." + } + + if (-not $gdkRoot) { + $gdkRoot = "${env:ProgramFiles}\Microsoft GDK" + } + + if (Test-Path $gdkRoot) { + Remove-Item $gdkRoot -Recurse -Force + } + + Copy-Item $cached $gdkRoot -Recurse -Force + } + else { + winget install Microsoft.Gaming.GDK ` + --accept-package-agreements ` + --accept-source-agreements ` + --silent + + $gdkRoot = $installRoots | + Where-Object { $_ -and (Test-Path $_) } | + Select-Object -First 1 + + if (-not $gdkRoot) { + throw "Microsoft GDK was not found under Program Files after installation." + } + + New-Item -ItemType Directory -Force -Path $cacheRoot | Out-Null + Copy-Item $gdkRoot (Join-Path $cacheRoot 'Microsoft GDK') -Recurse -Force + } + + if (-not $gdkRoot) { + throw "Microsoft GDK was not found under Program Files after restore." + } + + "GDK=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append + "GDKX=$gdkRoot" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Install Ninja + uses: seanmiddleditch/gha-setup-ninja@v5 + + - name: Cache SDL2 build + id: cache-sdl2 + uses: actions/cache@v6 + with: + path: ${{ github.workspace }}/vendor/SDL2/install + key: sdl2-gdk-${{ runner.os }}-2.32.10-rev2 + + - name: Checkout SDL2 + if: steps.cache-sdl2.outputs.cache-hit != 'true' + uses: actions/checkout@v7 + with: + repository: libsdl-org/SDL + ref: release-2.32.10 + path: vendor/SDL2 + + - name: Build SDL2 from source + if: steps.cache-sdl2.outputs.cache-hit != 'true' + shell: pwsh + run: | + $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' + $sdlSrc = Join-Path $workspace 'vendor\SDL2' + $sdlBuild = Join-Path $sdlSrc 'build' + $sdlInstall = Join-Path $workspace 'vendor\SDL2\install' + $cmakeCommand = "cmake -S `"$sdlSrc`" -B `"$sdlBuild`" -G `"Visual Studio 18 2026`" -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`"$sdlInstall`" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TESTS=OFF -DSDL_GDK=ON" + & $gdkScript $cmakeCommand + & $gdkScript "cmake --build `"$sdlBuild`" --config Release" + & $gdkScript "cmake --install `"$sdlBuild`"" + + - name: Configure Butterscotch + shell: pwsh + run: | + if (Test-Path "$env:GITHUB_WORKSPACE/build") { + Remove-Item "$env:GITHUB_WORKSPACE/build" -Recurse -Force + } + + $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' + $buildDir = Join-Path $workspace 'build' + $sdlDir = Join-Path $workspace 'vendor\SDL2\install' + $cmakeCommand = "cmake -S `"$workspace`" -B `"$buildDir`" -G `"Visual Studio 18 2026`" -A x64 -DBACKEND=sdl2 -DIS_GDK=ON -DSDL2_DIR=`"$sdlDir`" -DCMAKE_PREFIX_PATH=`"$sdlDir`" -DCMAKE_BUILD_TYPE=Release -DWERROR=ON" + & $gdkScript $cmakeCommand + + - name: Build Butterscotch + shell: pwsh + run: | + $workspace = $env:GITHUB_WORKSPACE + $gdkScript = Join-Path $workspace 'scripts\invoke-gdk.ps1' + $buildDir = Join-Path $workspace 'build' + & $gdkScript "cmake --build `"$buildDir`" --config Release" + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: butterscotch-gdk + path: build/**/* \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cccb613a5..d03010b8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,26 +7,23 @@ on: branches: [main] jobs: - # Unix: - # uses: ./.github/workflows/build-desktop.yml + Unix: + uses: ./.github/workflows/build-desktop.yml - # Windows: - # uses: ./.github/workflows/build-windows.yml + Windows: + uses: ./.github/workflows/build-windows.yml - # macOS: - # uses: ./.github/workflows/build-macos.yml + macOS: + uses: ./.github/workflows/build-macos.yml - # Haiku: - # uses: ./.github/workflows/build-haiku.yml + Haiku: + uses: ./.github/workflows/build-haiku.yml - # Consoles: - # uses: ./.github/workflows/build-console.yml + Consoles: + uses: ./.github/workflows/build-console.yml - # Other: - # uses: ./.github/workflows/build-other.yml - - GDK: - uses: ./.github/workflows/build-gdk.yml - - # Compilers: - # uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file + Other: + uses: ./.github/workflows/build-other.yml + + Compilers: + uses: ./.github/workflows/build-old-compilers.yml \ No newline at end of file