summary refs log tree commit diff
path: root/.github
diff options
context:
space:
mode:
Diffstat (limited to '.github')
-rw-r--r--.github/actions/notify_failure/action.yml30
-rw-r--r--.github/actions/notify_success/action.yml19
-rw-r--r--.github/actions/upload_build/action.yml19
-rw-r--r--.github/workflows/build_3ds.yml57
-rw-r--r--.github/workflows/build_dreamcast.yml53
-rw-r--r--.github/workflows/build_freebsd.yml80
-rw-r--r--.github/workflows/build_haiku.yml48
-rw-r--r--.github/workflows/build_ios.yml46
-rw-r--r--.github/workflows/build_linux.yml122
-rw-r--r--.github/workflows/build_mac32.yml55
-rw-r--r--.github/workflows/build_mac64.yml60
-rw-r--r--.github/workflows/build_macclassic.yml45
-rw-r--r--.github/workflows/build_n64.yml60
-rw-r--r--.github/workflows/build_nds.yml54
-rw-r--r--.github/workflows/build_netbsd.yml61
-rw-r--r--.github/workflows/build_ps1.yml61
-rw-r--r--.github/workflows/build_ps2.yml46
-rw-r--r--.github/workflows/build_ps3.yml63
-rw-r--r--.github/workflows/build_psp.yml52
-rw-r--r--.github/workflows/build_rpi.yml108
-rw-r--r--.github/workflows/build_saturn.yml51
-rw-r--r--.github/workflows/build_switch.yml51
-rw-r--r--.github/workflows/build_vita.yml51
-rw-r--r--.github/workflows/build_webclient.yml45
-rw-r--r--.github/workflows/build_wiigc.yml78
-rw-r--r--.github/workflows/build_wiiu.yml57
-rw-r--r--.github/workflows/build_win-arm.yml80
-rw-r--r--.github/workflows/build_windows.yml136
-rw-r--r--.github/workflows/build_xbox.yml54
-rw-r--r--.github/workflows/build_xbox360.yml55
-rw-r--r--.github/workflows/release.yml178
31 files changed, 1975 insertions, 0 deletions
diff --git a/.github/actions/notify_failure/action.yml b/.github/actions/notify_failure/action.yml
new file mode 100644
index 0000000..3ca4019
--- /dev/null
+++ b/.github/actions/notify_failure/action.yml
@@ -0,0 +1,30 @@
+name: Notify failure
+description: Sends a notification that compiling a build has failed
+inputs:
+  BOT_USERNAME:
+    description: 'Username to use for the discord bot message'
+    default: 'CC BuildBot'
+    required: false
+    type: string
+  BOT_AVATAR:
+    description: 'URL to use for the avatar of the discord bot message'
+    default: 'https://static.classicube.net/img/cc-cube-small.png'
+    required: false
+    type: string
+  NOTIFY_MESSAGE:
+    description: 'Notification message to send'
+    required: true
+    type: string
+  WEBHOOK_URL:
+    description: 'Discord webhook URL'
+    required: true
+    type: string
+
+runs:
+  using: "composite"
+  steps:
+    - name: Notify failure
+      shell: sh
+      if: ${{ inputs.WEBHOOK_URL != '' }}
+      run: |
+        curl ${{ inputs.WEBHOOK_URL }} -H "Accept: application/json" -H "Content-Type:application/json" -X POST --data "{\"username\": \"${{ inputs.BOT_USERNAME }}\", \"avatar_url\": \"${{ inputs.BOT_AVATAR }}\", \"content\": \"${{ inputs.NOTIFY_MESSAGE }}\" }"
\ No newline at end of file
diff --git a/.github/actions/notify_success/action.yml b/.github/actions/notify_success/action.yml
new file mode 100644
index 0000000..712ca0d
--- /dev/null
+++ b/.github/actions/notify_success/action.yml
@@ -0,0 +1,19 @@
+name: Notify success
+description: Sends a notification that a workflow has finished
+inputs:
+  DESTINATION_URL:
+    description: 'Webhook notification URL'
+    type: string
+  WORKFLOW_NAME:
+    description: 'Workflow name'
+    required: true
+    type: string
+
+runs:
+  using: "composite"
+  steps:
+    - name: Notify failure
+      if: ${{ inputs.DESTINATION_URL != '' }}
+      shell: sh
+      run: |
+        curl ${{ inputs.DESTINATION_URL }}/${{ inputs.WORKFLOW_NAME }}/${{ github.sha }}
\ No newline at end of file
diff --git a/.github/actions/upload_build/action.yml b/.github/actions/upload_build/action.yml
new file mode 100644
index 0000000..7609946
--- /dev/null
+++ b/.github/actions/upload_build/action.yml
@@ -0,0 +1,19 @@
+name: Upload binary
+description: Uploads a compiled binary
+inputs:
+  SOURCE_FILE:
+    description: 'Path to file to upload'
+    required: true
+    type: string
+  DEST_NAME:
+    description: 'Name to use for the uploaded artifact'
+    required: true
+    type: string
+
+runs:
+  using: "composite"
+  steps:
+    - uses: actions/upload-artifact@v4
+      with:
+        name: ${{ inputs.DEST_NAME }}
+        path: ${{ inputs.SOURCE_FILE }}
\ No newline at end of file
diff --git a/.github/workflows/build_3ds.yml b/.github/workflows/build_3ds.yml
new file mode 100644
index 0000000..ac26726
--- /dev/null
+++ b/.github/workflows/build_3ds.yml
@@ -0,0 +1,57 @@
+name: Build latest (3DS)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-3ds
+  cancel-in-progress: true
+
+jobs:
+  build-3DS:
+    runs-on: ubuntu-latest
+    container:
+      image: devkitpro/devkitarm:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 3DS build
+        id: compile
+        run: |
+          make 3ds
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 3DS build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-3ds.cia'
+          DEST_NAME: 'ClassiCube-3ds.cia'
+                    
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-3ds.3dsx'
+          DEST_NAME: 'ClassiCube-3ds.3dsx'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-3ds.elf'
+          DEST_NAME: 'ClassiCube-3ds.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: '3ds'
\ No newline at end of file
diff --git a/.github/workflows/build_dreamcast.yml b/.github/workflows/build_dreamcast.yml
new file mode 100644
index 0000000..7cc9bee
--- /dev/null
+++ b/.github/workflows/build_dreamcast.yml
@@ -0,0 +1,53 @@
+name: Build latest (Dreamcast)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-dreamcast
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: kazade/dreamcast-sdk
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Dreamcast build
+        id: compile
+        run: |
+          source /opt/toolchains/dc/kos/environ.sh
+          export PATH=/opt/toolchains/dc/kos/utils/img4dc/build/cdi4dc/:$PATH
+          make dreamcast
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Dreamcast build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-dc.cdi'
+          DEST_NAME: 'ClassiCube-dc.cdi'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-dc.elf'
+          DEST_NAME: 'ClassiCube-dc.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'dreamcast'
\ No newline at end of file
diff --git a/.github/workflows/build_freebsd.yml b/.github/workflows/build_freebsd.yml
new file mode 100644
index 0000000..e6eea21
--- /dev/null
+++ b/.github/workflows/build_freebsd.yml
@@ -0,0 +1,80 @@
+name: Build latest (FreeBSD)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-freebsd
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: empterdose/freebsd-cross-build:11.4
+    steps:
+      - uses: actions/checkout@v4
+      - name: Install prerequisites
+        run: apk add bash wget
+      - name: Retrieve OpenGL and X11 dev files (64 bit)
+        run: |
+          mkdir src/freebsd64
+          cd src/freebsd64
+          wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/freebsd64.zip
+          unzip freebsd64.zip
+      - name: Retrieve OpenGL and X11 dev files (32 bit)
+        run: |
+          mkdir src/freebsd32
+          cd src/freebsd32
+          wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/freebsd32.zip
+          unzip freebsd32.zip  
+      - name: Compile FreeBSD builds
+        id: compile
+        shell: bash
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          PLAT32_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON -I freebsd32/include -L freebsd32/lib"
+          PLAT64_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON -I freebsd64/include -L freebsd64/lib"
+        run: |
+          apk add curl
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
+          
+          cd src
+          i386-freebsd11-clang *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT32_FLAGS }} $LATEST_FLAG -o cc-fbsd32-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo
+          x86_64-freebsd11-clang *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-fbsd64-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo
+
+
+      # otherwise notify_failure doesn't work
+      - name: Install curl when necessary
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        run: apk add curl
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile FreeBSD build(s)'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-fbsd32-gl1'
+          DEST_NAME: 'ClassiCube-FreeBSD-32'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-fbsd64-gl1'
+          DEST_NAME: 'ClassiCube-FreeBSD-64'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'freebsd'
\ No newline at end of file
diff --git a/.github/workflows/build_haiku.yml b/.github/workflows/build_haiku.yml
new file mode 100644
index 0000000..8d332a7
--- /dev/null
+++ b/.github/workflows/build_haiku.yml
@@ -0,0 +1,48 @@
+name: Build latest (Haiku)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-haiku
+  cancel-in-progress: true
+
+jobs:
+  build-haiku:
+    runs-on: ubuntu-latest
+    container:
+      image: haiku/cross-compiler:x86_64-r1beta4
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile haiku build
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+        run: |
+          cd src        
+          x86_64-unknown-haiku-gcc *.c Platform_BeOS.cpp Window_BeOS.cpp -o ClassiCube-haiku ${{ env.COMMON_FLAGS }} -lm -lGL -lnetwork -lstdc++ -lbe -lgame -ltracker
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Haiku build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome  == 'success' }}
+        with:
+          SOURCE_FILE: 'src/ClassiCube-haiku'
+          DEST_NAME: 'ClassiCube-haiku'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'haiku'
\ No newline at end of file
diff --git a/.github/workflows/build_ios.yml b/.github/workflows/build_ios.yml
new file mode 100644
index 0000000..b095e02
--- /dev/null
+++ b/.github/workflows/build_ios.yml
@@ -0,0 +1,46 @@
+name: Build latest (iOS)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-ios
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: macOS-11
+    steps:
+      - uses: actions/checkout@v3
+      - name: Compile iOS build
+        id: compile
+        run: |
+          cd ios
+          xcodebuild -sdk iphoneos -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
+          cd build/Release-iphoneos
+          mkdir Payload
+          mv ClassiCube.app Payload/ClassiCube.app
+          zip -r cc.ipa Payload
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile iOS build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ios/build/Release-iphoneos/cc.ipa'
+          DEST_NAME: 'cc.ipa'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'ios'
\ No newline at end of file
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
new file mode 100644
index 0000000..04e98b6
--- /dev/null
+++ b/.github/workflows/build_linux.yml
@@ -0,0 +1,122 @@
+name: Build latest (Linux)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+      - ModernLighting
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-linux
+  cancel-in-progress: true
+
+jobs:
+#============================================
+# =============== 32 BIT LINUX ==============
+# ===========================================
+  build-32:
+    runs-on: ubuntu-20.04
+    steps:
+      - uses: actions/checkout@v4
+      - name: Install packages
+        shell: bash
+        run: |
+          sudo dpkg --add-architecture i386
+          sudo apt-get -y update
+          sudo apt-get -y install gcc-multilib libx11-dev:i386 libxi-dev:i386 libgl1-mesa-dev:i386
+      - name: Compile 32 bit Linux builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          NIX32_FLAGS:  "-no-pie -fno-pie -m32 -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$(git rev-parse --short "$GITHUB_SHA")\"
+          
+          cd src
+          gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -o cc-nix32-gl1 -lX11 -lXi -lpthread -lGL -lm -ldl
+          gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix32-gl2 -lX11 -lXi -lpthread -lGL -lm -ldl
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 32 bit Linux build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+      
+      
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-nix32-gl1'
+          DEST_NAME: 'ClassiCube-Linux32-OpenGL'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-nix32-gl2'
+          DEST_NAME: 'ClassiCube-Linux32-ModernGL'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'linux32'
+
+#============================================
+# =============== 64 BIT LINUX ==============
+# ===========================================
+  build-64:
+    runs-on: ubuntu-20.04
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 64 bit Linux builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          NIX64_FLAGS:  "-no-pie -fno-pie -m64 -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON"
+        run: |
+          sudo apt-get -y install libx11-dev libxi-dev libgl1-mesa-dev libsdl2-dev
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$(git rev-parse --short "$GITHUB_SHA")\"  
+          
+          cd src
+          gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -o cc-nix64-gl1 -lX11 -lXi -lpthread -lGL -lm -ldl
+          gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix64-gl2 -lX11 -lXi -lpthread -lGL -lm -ldl
+          gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL2 -o cc-sdl64-gl2 -lSDL2 -lpthread -lGL -lm -ldl
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 64 bit Linux build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-nix64-gl1'
+          DEST_NAME: 'ClassiCube-Linux64-OpenGL'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-nix64-gl2'
+          DEST_NAME: 'ClassiCube-Linux64-ModernGL'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-sdl64-gl2'
+          DEST_NAME: 'ClassiCube-Linux64-SDL2'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'linux64'
\ No newline at end of file
diff --git a/.github/workflows/build_mac32.yml b/.github/workflows/build_mac32.yml
new file mode 100644
index 0000000..905f8e1
--- /dev/null
+++ b/.github/workflows/build_mac32.yml
@@ -0,0 +1,55 @@
+name: Build latest (macOS 32 bit)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-mac32
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/classicube/minimal-osxcross:latest
+      credentials:
+        username: UnknownShadow200
+        password: ${{ secrets.GHCR_ACCESS_KEY }}
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 32 bit macOS builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -fvisibility=hidden -rdynamic -DCC_BUILD_ICON"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
+ 
+          cd src
+          PATH=$PATH:/usr/local/compiler/target/bin
+          i386-apple-darwin8-clang *.c Window_cocoa.m ${{ env.COMMON_FLAGS }} $LATEST_FLAG -o cc-mac32-gl1 -framework Cocoa -framework OpenGL -framework IOKit -lobjc -lgcc_s.1
+          i386-apple-darwin8-clang *.c Window_cocoa.m ${{ env.COMMON_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-mac32-gl2 -framework Cocoa -framework OpenGL -framework IOKit -lobjc -lgcc_s.1
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 32 bit macOS build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-mac32-gl1'
+          DEST_NAME: 'ClassiCube-mac32-Intel'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-mac32-gl2'
+          DEST_NAME: 'ClassiCube-mac32-Intel-ModernGL'
diff --git a/.github/workflows/build_mac64.yml b/.github/workflows/build_mac64.yml
new file mode 100644
index 0000000..d4dbf95
--- /dev/null
+++ b/.github/workflows/build_mac64.yml
@@ -0,0 +1,60 @@
+name: Build latest (macOS 64 bit)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+
+concurrency:
+  group: ${{ github.ref }}-mac64
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: macOS-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 64 bit macOS builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS:      "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          MAC_ARM64_FLAGS:   "-fvisibility=hidden -rdynamic -DCC_BUILD_ICON -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -arch arm64"
+          MAC_INTEL64_FLAGS: "-fvisibility=hidden -rdynamic -DCC_BUILD_ICON -arch x86_64"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$(git rev-parse --short "$GITHUB_SHA")\"
+          cd src
+          
+          MACOSX_DEPLOYMENT_TARGET=10.5 clang *.c Window_cocoa.m ${{ env.COMMON_FLAGS }} ${{ env.MAC_INTEL64_FLAGS }} $LATEST_FLAG -o cc-mac64-gl1 -framework Cocoa -framework OpenGL -framework IOKit -lobjc
+          MACOSX_DEPLOYMENT_TARGET=10.5 clang *.c Window_cocoa.m ${{ env.COMMON_FLAGS }} ${{ env.MAC_INTEL64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-mac64-gl2 -framework Cocoa -framework OpenGL -framework IOKit -lobjc
+          
+          clang *.c Window_cocoa.m ${{ env.COMMON_FLAGS }} ${{ env.MAC_ARM64_FLAGS }} $LATEST_FLAG -o cc-mac-arm64 -framework Cocoa -framework OpenGL -framework IOKit -lobjc
+          # https://wiki.freepascal.org/Code_Signing_for_macOS#Ad_hoc_signing
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 64 bit macOS builds'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+   
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-mac64-gl1'
+          DEST_NAME: 'ClassiCube-mac64'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-mac64-gl2'
+          DEST_NAME: 'ClassiCube-mac64-ModernGL'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-mac-arm64'
+          DEST_NAME: 'ClassiCube-mac-ARM64'
diff --git a/.github/workflows/build_macclassic.yml b/.github/workflows/build_macclassic.yml
new file mode 100644
index 0000000..a95e0c0
--- /dev/null
+++ b/.github/workflows/build_macclassic.yml
@@ -0,0 +1,45 @@
+name: Build latest (Mac Classic)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-mac-classic
+  cancel-in-progress: true
+
+jobs:
+  build-mac-classic:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/autc04/retro68
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Mac classic build
+        id: compile
+        run: |
+          make macclassic_68k RETRO68=/Retro68-build/toolchain
+          make macclassic_ppc RETRO68=/Retro68-build/toolchain
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Mac Classic build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-68k.dsk'
+          DEST_NAME: 'ClassiCube-68k.dsk'
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-ppc.dsk'
+          DEST_NAME: 'ClassiCube-ppc.dsk'
diff --git a/.github/workflows/build_n64.yml b/.github/workflows/build_n64.yml
new file mode 100644
index 0000000..5746236
--- /dev/null
+++ b/.github/workflows/build_n64.yml
@@ -0,0 +1,60 @@
+name: Build latest (N64)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-n64
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/dragonminded/libdragon:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile N64 build
+        id: compile
+        run: |
+          apt-get update
+          apt-get -y install curl
+          REAL_DIR=`pwd`
+          cd /tmp
+          git clone -b opengl https://github.com/DragonMinded/libdragon.git --depth=1
+          cd libdragon
+          make install
+          make tools-install
+          cd $REAL_DIR
+          make n64
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile N64 build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'build-n64/ClassiCube-n64.elf'
+          DEST_NAME: 'ClassiCube-n64.elf'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-n64.z64'
+          DEST_NAME: 'ClassiCube-n64.z64'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'n64'
diff --git a/.github/workflows/build_nds.yml b/.github/workflows/build_nds.yml
new file mode 100644
index 0000000..c00d614
--- /dev/null
+++ b/.github/workflows/build_nds.yml
@@ -0,0 +1,54 @@
+name: Build latest (NDS)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-nds
+  cancel-in-progress: true
+
+jobs:
+  build-DS:
+    runs-on: ubuntu-latest
+    container:
+      image: skylyrac/blocksds:dev-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile NDS build
+        id: compile
+        run: |
+          apt-get -y install curl
+          export BLOCKSDS=/opt/blocksds/core
+          export BLOCKSDSEXT=/opt/blocksds/external
+          make ds
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile NDS build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+ 
+         
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube.nds'
+          DEST_NAME: 'ClassiCube.nds'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'build-nds/ClassiCube.elf'
+          DEST_NAME: 'ClassiCube-nds.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'nds'
diff --git a/.github/workflows/build_netbsd.yml b/.github/workflows/build_netbsd.yml
new file mode 100644
index 0000000..e169ea3
--- /dev/null
+++ b/.github/workflows/build_netbsd.yml
@@ -0,0 +1,61 @@
+name: Build latest (NetBSD)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-netbsd
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/cross-rs/x86_64-unknown-netbsd:edge
+    steps:
+      - uses: actions/checkout@v3
+      - name: Install prerequisites
+        run: apt install wget unzip
+      - name: Retrieve OpenGL and X11 dev files (64 bit)
+        run: |
+          mkdir src/netbsd64
+          cd src/netbsd64
+          wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/netbsd64.zip
+          unzip netbsd64.zip
+      - name: Compile NetBSD builds
+        id: compile
+        shell: bash
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          PLAT64_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -DCC_BUILD_ICON -I netbsd64/include -L netbsd64/lib -Wl,--unresolved-symbols=ignore-in-shared-libs"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
+          echo $LATEST_FLAG
+          
+          cd src
+          x86_64-unknown-netbsd-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-netbsd64-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile NetBSD build(s)'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-netbsd64-gl1'
+          DEST_NAME: 'ClassiCube-NetBSD-64'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'netbsd'
\ No newline at end of file
diff --git a/.github/workflows/build_ps1.yml b/.github/workflows/build_ps1.yml
new file mode 100644
index 0000000..bcff36c
--- /dev/null
+++ b/.github/workflows/build_ps1.yml
@@ -0,0 +1,61 @@
+name: Build latest (PS1)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-ps1
+  cancel-in-progress: true
+
+jobs:
+  build-PS1:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/classicube/minimal-psn00b:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile PS1 build
+        id: compile
+        run: |
+          apt-get update
+          apt-get install -y curl
+          export PSNOOB=/usr/local/psnoob
+          export PATH=$PATH:$PSNOOB/bin
+          export PSN00BSDK_LIBS=$PSNOOB/lib/libpsn00b
+          make ps1
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile PS1 build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'misc/ps1/build/template.elf'
+          DEST_NAME: 'ClassiCube-PS1.elf'
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'misc/ps1/build/template.exe'
+          DEST_NAME: 'ClassiCube-PS1.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'misc/ps1/build/template.bin'
+          DEST_NAME: 'ClassiCube-PS1.bin'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'misc/ps1/build/template.cue'
+          DEST_NAME: 'ClassiCube-PS1.cue'
diff --git a/.github/workflows/build_ps2.yml b/.github/workflows/build_ps2.yml
new file mode 100644
index 0000000..e1ca063
--- /dev/null
+++ b/.github/workflows/build_ps2.yml
@@ -0,0 +1,46 @@
+name: Build latest (PS2)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-ps2
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/ps2dev/ps2sdk:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile PS2 build
+        id: compile
+        run: |
+          apk add make mpc1 curl
+          make ps2
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile PS2 build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-ps2.elf'
+          DEST_NAME: 'ClassiCube-ps2.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'ps2'
\ No newline at end of file
diff --git a/.github/workflows/build_ps3.yml b/.github/workflows/build_ps3.yml
new file mode 100644
index 0000000..b618d14
--- /dev/null
+++ b/.github/workflows/build_ps3.yml
@@ -0,0 +1,63 @@
+name: Build latest (PS3)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-ps3
+  cancel-in-progress: true
+
+jobs:
+  build-PS3:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/classicube/minimal-psl1ght:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile PS3 build
+        id: compile
+        run: |
+          apt-get update
+          apt-get install -y curl
+          export PS3DEV=/usr/local/ps3dev
+          export PSL1GHT=/usr/local/ps3dev
+          export PATH=$PATH:$PS3DEV/bin
+          export PATH=$PATH:$PS3DEV/ppu/bin
+          make ps3
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile PS3 build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-PS3.elf'
+          DEST_NAME: 'ClassiCube-PS3.elf'
+
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-PS3.self'
+          DEST_NAME: 'ClassiCube-PS3.self'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-PS3.pkg'
+          DEST_NAME: 'ClassiCube-PS3.pkg'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'ps3'
diff --git a/.github/workflows/build_psp.yml b/.github/workflows/build_psp.yml
new file mode 100644
index 0000000..3438dd7
--- /dev/null
+++ b/.github/workflows/build_psp.yml
@@ -0,0 +1,52 @@
+name: Build latest (PSP)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-psp
+  cancel-in-progress: true
+
+jobs:
+  build-PSP:
+    runs-on: ubuntu-latest
+    container:
+      image: pspdev/pspdev:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile PSP build
+        id: compile
+        run: |
+          apk add curl curl-dev
+          make psp
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile PSP build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'EBOOT.PBP'
+          DEST_NAME: 'EBOOT.PBP'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-psp.elf'
+          DEST_NAME: 'ClassiCube-psp.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'psp'
\ No newline at end of file
diff --git a/.github/workflows/build_rpi.yml b/.github/workflows/build_rpi.yml
new file mode 100644
index 0000000..97e40a2
--- /dev/null
+++ b/.github/workflows/build_rpi.yml
@@ -0,0 +1,108 @@
+name: Build latest (RPI)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-rpi
+  cancel-in-progress: true
+
+jobs:
+#============================================
+# ================ 32 BIT RPI ===============
+# ===========================================
+  build-RPI32:
+    runs-on: ubuntu-latest
+    container:
+      image: dockcross/linux-armv6-lts
+    steps:
+      - uses: actions/checkout@v4
+      - name: Retrieve OpenGL and X11 dev files
+        run: |
+          mkdir src/rpi
+          cd src/rpi
+          wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/rpi32.zip
+          unzip rpi32.zip
+      - name: Compile RPI 32 bit build
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          RPI32_FLAGS: "-fvisibility=hidden -rdynamic -DCC_BUILD_ICON -DCC_BUILD_RPI -I rpi/include -L rpi/lib -Wl,--unresolved-symbols=ignore-in-shared-libs"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$GITHUB_SHA\"
+          
+          cd src
+          $CC *.c ${{ env.COMMON_FLAGS }} ${{ env.RPI32_FLAGS }} $LATEST_FLAG -o cc-rpi32 -lGLESv2 -lEGL -lX11 -lXi -lm -lpthread -ldl -lrt
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile RPI 32 bit build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-rpi32'
+          DEST_NAME: 'cc-rpi32'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'rpi32'
+
+
+#============================================
+# ================ 64 BIT RPI ===============
+# ===========================================
+  build-RPI64:
+    runs-on: ubuntu-latest
+    container:
+      image: dockcross/linux-arm64-lts
+    steps:
+      - uses: actions/checkout@v4
+      - name: Retrieve OpenGL and X11 dev files
+        run: |
+          mkdir src/rpi
+          cd src/rpi
+          wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/rpi64.zip
+          unzip rpi64.zip     
+      - name: Compile RPI 64 bit build
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          RPI64_FLAGS: "-fvisibility=hidden -rdynamic -DCC_BUILD_ICON -DCC_BUILD_RPI -I rpi/include -L rpi/lib -Wl,--unresolved-symbols=ignore-in-shared-libs"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$GITHUB_SHA\"
+          
+          cd src
+          $CC *.c ${{ env.COMMON_FLAGS }} ${{ env.RPI64_FLAGS }} $LATEST_FLAG -o cc-rpi64 -lGLESv2 -lEGL -lX11 -lXi -lm -lpthread -ldl -lrt
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile RPI 64 bit build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-rpi64'
+          DEST_NAME: 'cc-rpi64'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'rpi64'
\ No newline at end of file
diff --git a/.github/workflows/build_saturn.yml b/.github/workflows/build_saturn.yml
new file mode 100644
index 0000000..3115c40
--- /dev/null
+++ b/.github/workflows/build_saturn.yml
@@ -0,0 +1,51 @@
+name: Build latest (Saturn)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-saturn
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: ijacquez/yaul
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Saturn build
+        id: compile
+        run: |
+          apt-get update
+          apt-get -y install curl
+          make saturn
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Saturn build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'build-saturn/ClassiCube-saturn.elf'
+          DEST_NAME: 'ClassiCube-saturn.elf'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-saturn.iso'
+          DEST_NAME: 'ClassiCube-saturn.iso'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-saturn.cue'
+          DEST_NAME: 'ClassiCube-saturn.cue'
\ No newline at end of file
diff --git a/.github/workflows/build_switch.yml b/.github/workflows/build_switch.yml
new file mode 100644
index 0000000..b419e4f
--- /dev/null
+++ b/.github/workflows/build_switch.yml
@@ -0,0 +1,51 @@
+name: Build latest (Switch)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-switch
+  cancel-in-progress: true
+
+jobs:
+  build-switch:
+    runs-on: ubuntu-latest
+    container:
+      image: devkitpro/devkita64:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Switch build
+        id: compile
+        run: |
+          make switch
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Switch build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-switch.nro'
+          DEST_NAME: 'ClassiCube-switch.nro'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-switch.elf'
+          DEST_NAME: 'ClassiCube-switch.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'switch'
\ No newline at end of file
diff --git a/.github/workflows/build_vita.yml b/.github/workflows/build_vita.yml
new file mode 100644
index 0000000..05abd34
--- /dev/null
+++ b/.github/workflows/build_vita.yml
@@ -0,0 +1,51 @@
+name: Build latest (Vita)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-vita
+  cancel-in-progress: true
+
+jobs:
+  build-Vita:
+    runs-on: ubuntu-latest
+    container:
+      image: vitasdk/vitasdk:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Vita build
+        id: compile
+        run: |
+          make vita
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Vita build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-vita.vpk'
+          DEST_NAME: 'ClassiCube-vita.vpk'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-vita.elf'
+          DEST_NAME: 'ClassiCube-vita.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'vita'
\ No newline at end of file
diff --git a/.github/workflows/build_webclient.yml b/.github/workflows/build_webclient.yml
new file mode 100644
index 0000000..7d8afd0
--- /dev/null
+++ b/.github/workflows/build_webclient.yml
@@ -0,0 +1,45 @@
+name: Build latest (Webclient)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-webclient
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: trzeci/emscripten-fastcomp:1.39.0
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compiles webclient
+        id: compile
+        run: |
+          cd src
+          emcc *.c -o ClassiCube.js -s WASM=0 -s NO_EXIT_RUNTIME=1 -s LEGACY_VM_SUPPORT=1 -s ALLOW_MEMORY_GROWTH=1 -s ABORTING_MALLOC=0 -s ENVIRONMENT=web -s TOTAL_STACK=256Kb --js-library interop_web.js -Os -g2 -s SINGLE_FILE
+          sed -i 's#eventHandler.useCapture);#{ useCapture: eventHandler.useCapture, passive: false });#g' ClassiCube.js
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Webclient'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/ClassiCube.js'
+          DEST_NAME: 'ClassiCube.js'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'webclient'
\ No newline at end of file
diff --git a/.github/workflows/build_wiigc.yml b/.github/workflows/build_wiigc.yml
new file mode 100644
index 0000000..2b9400a
--- /dev/null
+++ b/.github/workflows/build_wiigc.yml
@@ -0,0 +1,78 @@
+name: Build latest (Wii/GameCube)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-wiigc
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: devkitpro/devkitppc:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Wii and GameCube build
+        id: compile
+        run: |
+          make wii
+          make clean
+          make gamecube
+          
+      - name: Create Wii homebrew
+        run: |
+          mkdir -p wiitest/apps/ClassiCube
+          cp ClassiCube-wii.dol wiitest/apps/ClassiCube/boot.dol
+          cp misc/wii/icon.png wiitest/apps/ClassiCube/icon.png
+          cp misc/wii/meta.xml wiitest/apps/ClassiCube/meta.xml
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Wii/Gamecube build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-wii.dol'
+          DEST_NAME: 'ClassiCube-wii.dol'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-gc.dol'
+          DEST_NAME: 'ClassiCube-gc.dol'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-wii.elf'
+          DEST_NAME: 'ClassiCube-wii.elf'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-gc.elf'
+          DEST_NAME: 'ClassiCube-gc.elf'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'wiitest'
+          DEST_NAME: 'ClassiCube-Wii-Homebrew'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'wiigc'
\ No newline at end of file
diff --git a/.github/workflows/build_wiiu.yml b/.github/workflows/build_wiiu.yml
new file mode 100644
index 0000000..a7282d2
--- /dev/null
+++ b/.github/workflows/build_wiiu.yml
@@ -0,0 +1,57 @@
+name: Build latest (WiiU)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-wiiu
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    container:
+      image: devkitpro/devkitppc:latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Wii U build
+        id: compile
+        run: |
+          make wiiu
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile WiiU build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-wiiu.wuhb'
+          DEST_NAME: 'ClassiCube-wiiu.wuhb'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-wiiu.rpx'
+          DEST_NAME: 'ClassiCube-wiiu.rpx'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-wiiu.elf'
+          DEST_NAME: 'ClassiCube-wiiu.elf'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'wiiu'
\ No newline at end of file
diff --git a/.github/workflows/build_win-arm.yml b/.github/workflows/build_win-arm.yml
new file mode 100644
index 0000000..6ea54dc
--- /dev/null
+++ b/.github/workflows/build_win-arm.yml
@@ -0,0 +1,80 @@
+name: Build latest (Windows ARM32/64)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-windows-arm
+  cancel-in-progress: true
+
+jobs:
+#============================================
+# ============== ARM32 WINDOWS ==============
+# ===========================================
+  build-32:
+    runs-on: ubuntu-latest
+    container:
+      image: dockcross/windows-armv7
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile ARM32 Windows builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          WIN32_FLAGS:  "-mwindows -nostartfiles -Wl,-emain_real -DCC_NOMAIN -DCC_GFX_BACKEND=CC_GFX_BACKEND_D3D11"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
+          
+          cd src
+          armv7-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -o cc-arm32-d3d11.exe $LATEST_FLAG -lwinmm -limagehlp
+          
+          
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 32 bit Windows build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-arm32-d3d11.exe'
+          DEST_NAME: 'ClassiCube-arm32-Direct3D11.exe'
+#============================================
+# ============== ARM64 WINDOWS ==============
+# ===========================================
+  build-64:
+    runs-on: ubuntu-latest
+    container:
+      image: dockcross/windows-arm64
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile ARM64 Windows builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          WIN64_FLAGS:  "-mwindows -nostartfiles -Wl,-emain_real -DCC_NOMAIN -DCC_GFX_BACKEND=CC_GFX_BACKEND_D3D11"
+        run: |
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
+          
+          cd src
+          aarch64-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN64_FLAGS }} -o cc-arm64-d3d11.exe $LATEST_FLAG -lwinmm -limagehlp
+          
+          
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 64 bit Windows build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-arm64-d3d11.exe'
+          DEST_NAME: 'ClassiCube-arm64-Direct3D11.exe'
\ No newline at end of file
diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml
new file mode 100644
index 0000000..9527415
--- /dev/null
+++ b/.github/workflows/build_windows.yml
@@ -0,0 +1,136 @@
+name: Build latest (Windows)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+      - ModernLighting
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-windows
+  cancel-in-progress: true
+
+jobs:
+#============================================
+# ============== 32 BIT WINDOWS =============
+# ===========================================
+  build-32:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 32 bit Windows builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          WIN32_FLAGS:  "-mwindows -nostartfiles -Wl,-e_main_real -DCC_NOMAIN CCicon_32.res"
+        run: |
+          sudo apt-get -y install gcc-mingw-w64-i686
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$(git rev-parse --short "$GITHUB_SHA")\"  
+          
+          cp misc/windows/CCicon_32.res src/CCicon_32.res
+          cd src
+          i686-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -o cc-w32-d3d9.exe  $LATEST_FLAG -lwinmm -limagehlp
+          i686-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -o cc-w32-ogl.exe   $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL1 -lwinmm -limagehlp -lopengl32
+          i686-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -o cc-w32-d3d11.exe $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_D3D11 -lwinmm -limagehlp
+          
+          # mingw defaults to i686, but some really old CPUs only support i586
+          i686-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -march=i586 -o cc-w9x-ogl.exe $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL1 -DCC_BUILD_NOSTDLIB -lwinmm -limagehlp -lopengl32
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 32 bit Windows build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w32-d3d9.exe'
+          DEST_NAME: 'ClassiCube-Win32-Direct3D9.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w32-ogl.exe'
+          DEST_NAME: 'ClassiCube-Win32-OpenGL.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w32-d3d11.exe'
+          DEST_NAME: 'ClassiCube-Win32-Direct3D11.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w9x-ogl.exe'
+          DEST_NAME: 'ClassiCube-Win9x.exe'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'win32'
+          
+          
+#============================================
+# ============== 64 BIT WINDOWS =============
+# ===========================================
+  build-64:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile 64 bit Windows builds
+        shell: bash
+        id: compile
+        env: 
+          COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
+          WIN64_FLAGS:  "-mwindows -nostartfiles -Wl,-emain_real -DCC_NOMAIN CCicon_64.res"
+        run: |
+          sudo apt-get -y install gcc-mingw-w64-x86-64
+          LATEST_FLAG=-DCC_COMMIT_SHA=\"$(git rev-parse --short "$GITHUB_SHA")\"  
+          
+          cp misc/windows/CCicon_64.res src/CCicon_64.res
+          cd src
+          x86_64-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN64_FLAGS }} -o cc-w64-d3d9.exe  $LATEST_FLAG -lwinmm -limagehlp
+          x86_64-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN64_FLAGS }} -o cc-w64-ogl.exe   $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL1 -lwinmm -limagehlp -lopengl32
+          x86_64-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN64_FLAGS }} -o cc-w64-d3d11.exe $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_D3D11 -lwinmm -limagehlp
+          
+          
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile 64 bit Windows build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w64-d3d9.exe'
+          DEST_NAME: 'ClassiCube-Win64-Direct3D9.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w64-ogl.exe'
+          DEST_NAME: 'ClassiCube-Win64-OpenGL.exe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'src/cc-w64-d3d11.exe'
+          DEST_NAME: 'ClassiCube-Win64-Direct3D11.exe'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'win64'
\ No newline at end of file
diff --git a/.github/workflows/build_xbox.yml b/.github/workflows/build_xbox.yml
new file mode 100644
index 0000000..61426ad
--- /dev/null
+++ b/.github/workflows/build_xbox.yml
@@ -0,0 +1,54 @@
+name: Build latest (Xbox)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-xbox
+  cancel-in-progress: true
+
+jobs:
+  build-Xbox:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/xboxdev/nxdk:git-e955705a
+    steps:
+      - uses: actions/checkout@v4
+      - name: Compile Xbox build
+        id: compile
+        run: |
+          apk add curl curl-dev
+          eval $(/usr/src/nxdk/bin/activate -s)
+          make xbox
+          cp bin/default.xbe ClassiCube-xbox.xbe
+          
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Xbox build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-xbox.xbe'
+          DEST_NAME: 'ClassiCube-xbox.xbe'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-xbox.iso'
+          DEST_NAME: 'ClassiCube-xbox.iso'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'xbox'
\ No newline at end of file
diff --git a/.github/workflows/build_xbox360.yml b/.github/workflows/build_xbox360.yml
new file mode 100644
index 0000000..a813de3
--- /dev/null
+++ b/.github/workflows/build_xbox360.yml
@@ -0,0 +1,55 @@
+name: Build latest (Xbox 360)
+# trigger via either push to selected branches or on manual run
+on:
+  push:
+    branches:
+      - main
+      - master
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.ref }}-xbox360
+  cancel-in-progress: true
+
+jobs:
+  build-360:
+    runs-on: ubuntu-latest
+    container:
+      image: free60/libxenon
+    steps:
+      - uses: actions/checkout@v3
+      - name: Compile 360 build
+        id: compile
+        run: |
+          sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
+          apt-get update
+          apt-get install -y curl
+          export DEVKITXENON=/usr/local/xenon
+          export PATH=$PATH:$DEVKITXENON/bin:$DEVKITXENON/usr/bin
+          make xbox360
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to compile Xbox 360 build'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-xbox360.elf'
+          DEST_NAME: 'ClassiCube-xbox360.elf'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'ClassiCube-xbox360.elf32'
+          DEST_NAME: 'ClassiCube-xbox360.elf32'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'xbox360'
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..6a32d29
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,178 @@
+name: Produce release
+on: [workflow_dispatch]
+
+concurrency:
+  group: ${{ github.ref }}-release
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      # Download resources
+      - name: Retrieve classicube texture pack
+        run: |
+          wget https://www.classicube.net/static/default.zip
+      - name: Retrieve classicube audio pack
+        run: |
+          wget https://www.classicube.net/static/audio.zip
+          
+      # Download windows artifacts
+      - name: Retrieve Windows binaries
+        run: |
+          wget https://cdn.classicube.net/client/latest/ClassiCube.64.exe -O cc-w64.exe
+          wget https://cdn.classicube.net/client/latest/ClassiCube.exe -O cc-w32.exe
+          
+      # Download Linux artifacts
+      - name: Retrieve Linux binaries
+        run: |
+          wget https://cdn.classicube.net/client/latest/ClassiCube -O cc-linux-64
+          wget https://cdn.classicube.net/client/latest/ClassiCube.32 -O cc-linux-32
+          
+      # Download macOS artifacts
+      - name: Retrieve macOS binaries
+        run: |
+          wget https://cdn.classicube.net/client/latest/ClassiCube.64.osx -O cc-mac-64
+          wget https://cdn.classicube.net/client/latest/ClassiCube.osx -O cc-mac-32
+          
+      # Download RPI artifacts
+      - name: Retrieve RPI binaries
+        run: |
+          wget https://cdn.classicube.net/client/latest/cc-rpi64 -O cc-rpi-64
+          wget https://cdn.classicube.net/client/latest/ClassiCube.rpi -O cc-rpi-32
+          
+      # Download FreeBSD artifacts
+      - name: Retrieve macOS binaries
+        run: |
+          wget https://cdn.classicube.net/client/latest/cc-freebsd-64 -O cc-freebsd-64
+          wget https://cdn.classicube.net/client/latest/cc-freebsd-32 -O cc-freebsd-32
+          
+      - name: Generate builds
+        id: compile
+        shell: bash
+        run: |
+          mkdir ClassiCube
+          mkdir ClassiCube/audio
+          mkdir ClassiCube/texpacks
+          cp audio.zip ClassiCube/audio/classicube.zip
+          cp default.zip ClassiCube/texpacks/classicube.zip
+          
+          # ./ClassiCube
+          make_unix_tar() {
+            cp $2 ClassiCube/ClassiCube
+            chmod +x ClassiCube/ClassiCube
+            tar -zcvf $1 ClassiCube
+            rm ClassiCube/ClassiCube
+          }
+           
+          # ./ClassiCube
+          make_windows_zip() {
+            cp $2 ClassiCube/ClassiCube.exe
+            zip -r $1 ClassiCube
+            rm ClassiCube/ClassiCube.exe
+          }
+          
+          # Generate FreeBSD builds
+          make_unix_tar cc-freebsd32.tar.gz cc-freebsd-32
+          make_unix_tar cc-freebsd64.tar.gz cc-freebsd-64
+          
+          # Generate RPI builds
+          make_unix_tar cc-rpi32.tar.gz cc-rpi-32
+          make_unix_tar cc-rpi64.tar.gz cc-rpi-64
+          
+          # Generate Linux builds
+          make_unix_tar cc-linux32.tar.gz cc-linux-32
+          make_unix_tar cc-linux64.tar.gz cc-linux-64
+          
+          # Generate macOS builds
+          make_unix_tar cc-mac32.tar.gz cc-mac-32
+          make_unix_tar cc-mac64.tar.gz cc-mac-64
+          
+          # Generate Windows builds
+          make_windows_zip cc-win32.zip cc-w32.exe
+          make_windows_zip cc-win64.zip cc-w64.exe
+
+
+      - uses: ./.github/actions/notify_failure
+        if: ${{ always() && steps.compile.outcome == 'failure' }}
+        with:
+          NOTIFY_MESSAGE: 'Failed to produce release'
+          WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
+          
+        
+      # Generate Linux release files
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-linux32.tar.gz'
+          DEST_NAME: 'cc-linux32.tar.gz'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-linux64.tar.gz'
+          DEST_NAME: 'cc-linux64.tar.gz'
+          
+          
+      # Generate macOS release files
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-mac32.tar.gz'
+          DEST_NAME: 'cc-mac32.tar.gz'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-mac64.tar.gz'
+          DEST_NAME: 'cc-mac64.tar.gz'
+          
+          
+      # Generate Windows release files
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-win32.zip'
+          DEST_NAME: 'cc-win32.zip'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-win64.zip'
+          DEST_NAME: 'cc-win64.zip'
+          
+          
+      # Generate RPI release files
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-rpi32.tar.gz'
+          DEST_NAME: 'cc-rpi32.tar.gz'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-rpi64.tar.gz'
+          DEST_NAME: 'cc-rpi64.tar.gz'
+          
+          
+      # Generate FreeBSD release files
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-freebsd32.tar.gz'
+          DEST_NAME: 'cc-freebsd32.tar.gz'
+          
+      - uses: ./.github/actions/upload_build
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          SOURCE_FILE: 'cc-freebsd64.tar.gz'
+          DEST_NAME: 'cc-freebsd64.tar.gz'
+          
+          
+      - uses: ./.github/actions/notify_success
+        if: ${{ always() && steps.compile.outcome == 'success' }}
+        with:
+          DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
+          WORKFLOW_NAME: 'release'
\ No newline at end of file