diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index c63c104264..3758411588 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -1,591 +1,42 @@ -name: CI-compile +name: Apply exact CI formatting on: - push: pull_request: - workflow_dispatch: - repository_dispatch: - types: [run_build] + types: [opened, synchronize, reopened] permissions: contents: write jobs: - build: + format: runs-on: ubuntu-latest - container: ps2max/dev:v20250725-2 steps: - - name: git checkout + - name: Checkout staging branch uses: actions/checkout@v6 - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow - - - name: Compile -> make clean release - run: make --trace clean && make --trace release - - - name: Create detailed changelog - run: sh ./make_changelog.sh - - - name: Upload release artifact ELF - if: ${{ success() }} - uses: actions/upload-artifact@v6 with: - name: RIPTOPL - path: | - RIPTOPL-*.ELF + ref: ${{ github.head_ref }} + fetch-depth: 0 - - name: Upload release artifact info - if: ${{ success() }} - uses: actions/upload-artifact@v6 - with: - name: INFO - path: | - DETAILED_CHANGELOG - CREDITS - LICENSE - README.md - - - build-ps2dev-latest: - runs-on: ubuntu-latest - container: ps2dev/ps2dev:latest - steps: - # Install git BEFORE checkout: without it, actions/checkout falls back to an API - # tarball (no .git directory), so git describe fails and the Makefile marks the - # build "-dirty" -- the version string then collapses and hardware reports cannot - # identify the exact commit/toolchain they ran. - - name: Install host dependencies (Alpine only) + - name: Reset to four functional commits run: | - if command -v apk >/dev/null 2>&1; then - # Consolidated ps2dev Alpine prerequisites: build tools, scripting, packaging, and gcc runtime libs. - apk add --no-cache \ - bash \ - make \ - git \ - zip \ - unzip \ - tar \ - gzip \ - xz \ - python3 \ - py3-pip \ - py3-yaml \ - gmp \ - mpfr4 \ - mpc1 \ - perl \ - cmake \ - pkgconf \ - coreutils \ - findutils \ - grep \ - sed \ - gawk \ - diffutils - fi - - - name: git checkout - uses: actions/checkout@v6 - - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow || true - - - name: Install menu-coherent mmceman (latest-only) - # Rebuild mmceman ONLY from ps2-mmce (with the 2026-06-14 sio2man-compat fix) over the - # container SDK prebuilt (pinned to the desynced v2.1.1) -- fixes the MMCE MENU freeze. - # The in-game mmcedrv/mmceigr stay the SDK stock prebuilts: same source as the pin, and - # the stock binaries are field-proven in-game where our rebuild was not. See script header. - run: sh ./.github/scripts/install_coherent_mmce.sh - - - name: Compile -> make clean release - run: make --trace clean && make --trace release - - - name: Create detailed changelog - run: sh ./make_changelog.sh - - - name: Upload release artifact ELF (ps2dev-latest) - if: ${{ success() }} - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-ps2dev-latest - path: | - RIPTOPL-*.ELF + git fetch origin 311c92afe3a308c0c39e218396ccbc4cd4795c3c + git reset --hard FETCH_HEAD - - name: Upload release artifact info (ps2dev-latest) - if: ${{ success() }} - uses: actions/upload-artifact@v6 + - name: Apply repository CI formatting + uses: DoozyX/clang-format-lint-action@v0.18.2 with: - name: INFO-ps2dev-latest - path: | - DETAILED_CHANGELOG - CREDITS - LICENSE - README.md + source: '.' + extensions: 'h,c' + clangFormatVersion: 12 + style: file + inplace: true - build-variants: - strategy: - fail-fast: false - matrix: - extra: [EXTRA_FEATURES=0, EXTRA_FEATURES=1] - pademu: [PADEMU=0, PADEMU=1] - runs-on: ubuntu-latest - container: ps2max/dev:v20250725-2 - steps: - - name: git checkout - uses: actions/checkout@v6 - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow - - - name: Get version + - name: Publish formatted tree run: | - echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" - - - name: Compile -> make ${{ matrix.extra }} ${{ matrix.pademu }} ${{ matrix.extra }} NOT_PACKED=1 - run: | - make --trace ${{ matrix.pademu }} ${{ matrix.extra }} NOT_PACKED=1 - mv opl.elf RIPTOPL-${{ env.OPL_VERSION }}-${{ matrix.pademu }}-${{ matrix.extra }}.ELF - - - name: Create detailed changelog - run: sh ./make_changelog.sh - - - name: Upload variants artifact ELF - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-VARIANTS ${{ matrix.pademu }} ${{ matrix.extra }} - path: RIPTOPL*.ELF - - - build-variants-ps2dev-latest: - strategy: - fail-fast: false - matrix: - extra: [EXTRA_FEATURES=0, EXTRA_FEATURES=1] - pademu: [PADEMU=0, PADEMU=1] - runs-on: ubuntu-latest - container: ps2dev/ps2dev:latest - steps: - # Install git BEFORE checkout: without it, actions/checkout falls back to an API - # tarball (no .git directory), so git describe fails and the Makefile marks the - # build "-dirty" -- the version string then collapses and hardware reports cannot - # identify the exact commit/toolchain they ran. - - name: Install host dependencies (Alpine only) - run: | - if command -v apk >/dev/null 2>&1; then - # Consolidated ps2dev Alpine prerequisites: build tools, scripting, packaging, and gcc runtime libs. - apk add --no-cache \ - bash \ - make \ - git \ - zip \ - unzip \ - tar \ - gzip \ - xz \ - python3 \ - py3-pip \ - py3-yaml \ - gmp \ - mpfr4 \ - mpc1 \ - perl \ - cmake \ - pkgconf \ - coreutils \ - findutils \ - grep \ - sed \ - gawk \ - diffutils - fi - - - name: git checkout - uses: actions/checkout@v6 - - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow || true - - - name: Get version - run: | - echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" - - - name: Install menu-coherent mmceman (latest-only) - # Rebuild mmceman ONLY from ps2-mmce (with the 2026-06-14 sio2man-compat fix) over the - # container SDK prebuilt (pinned to the desynced v2.1.1) -- fixes the MMCE MENU freeze. - # The in-game mmcedrv/mmceigr stay the SDK stock prebuilts: same source as the pin, and - # the stock binaries are field-proven in-game where our rebuild was not. See script header. - run: sh ./.github/scripts/install_coherent_mmce.sh - - - name: Compile -> make ${{ matrix.extra }} ${{ matrix.pademu }} ${{ matrix.extra }} NOT_PACKED=1 - run: | - make --trace ${{ matrix.pademu }} ${{ matrix.extra }} NOT_PACKED=1 - mv opl.elf RIPTOPL-${{ env.OPL_VERSION }}-${{ matrix.pademu }}-${{ matrix.extra }}.ELF - - - name: Create detailed changelog - run: sh ./make_changelog.sh - - - name: Upload variants artifact ELF (ps2dev-latest) - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-VARIANTS-ps2dev-latest ${{ matrix.pademu }} ${{ matrix.extra }} - path: RIPTOPL*.ELF - - merge-variants: - runs-on: ubuntu-latest - needs: build-variants - steps: - - name: Download variant artifacts - uses: actions/download-artifact@v8 - with: - pattern: RIPTOPL-VARIANTS PADEMU=* - path: merged-variants - merge-multiple: true - - - name: Re-upload merged variants - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-VARIANTS - path: merged-variants - - - merge-variants-ps2dev-latest: - runs-on: ubuntu-latest - needs: build-variants-ps2dev-latest - steps: - - name: Download variant artifacts (ps2dev-latest) - uses: actions/download-artifact@v8 - with: - pattern: RIPTOPL-VARIANTS-ps2dev-latest* - path: merged-variants-ps2dev-latest - merge-multiple: true - - - name: Re-upload merged variants (ps2dev-latest) - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-VARIANTS-ps2dev-latest - path: merged-variants-ps2dev-latest - - build-lang: - runs-on: ubuntu-latest - container: ps2max/dev:v20250725-2 - steps: - - name: git checkout - uses: actions/checkout@v6 - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow - - - name: Compile -> make download_lng languages - run: make --trace download_lng languages - - - name: Create artifact - run: sh ./lng_pack.sh - - - name: Upload release artifact - if: ${{ success() }} - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-LANGS - path: | - RIPTOPL-LANGS-*.zip - - - build-lang-ps2dev-latest: - runs-on: ubuntu-latest - container: ps2dev/ps2dev:latest - steps: - # Install git BEFORE checkout: without it, actions/checkout falls back to an API - # tarball (no .git directory), so git describe fails and the Makefile marks the - # build "-dirty" -- the version string then collapses and hardware reports cannot - # identify the exact commit/toolchain they ran. - - name: Install host dependencies (Alpine only) - run: | - if command -v apk >/dev/null 2>&1; then - # Consolidated ps2dev Alpine prerequisites: build tools, scripting, packaging, and gcc runtime libs. - apk add --no-cache \ - bash \ - make \ - git \ - zip \ - unzip \ - tar \ - gzip \ - xz \ - python3 \ - py3-pip \ - py3-yaml \ - gmp \ - mpfr4 \ - mpc1 \ - perl \ - cmake \ - pkgconf \ - coreutils \ - findutils \ - grep \ - sed \ - gawk \ - diffutils - fi - - - name: git checkout - uses: actions/checkout@v6 - - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow || true - - - name: Compile -> make download_lng languages - run: make --trace download_lng languages - - - name: Create artifact - run: sh ./lng_pack.sh - - - name: Upload release artifact (ps2dev-latest) - if: ${{ success() }} - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-LANGS-ps2dev-latest - path: | - RIPTOPL-LANGS-*.zip - - build-debug: - strategy: - fail-fast: false - matrix: - debug: [iopcore_debug, ingame_debug, eesio_debug, iopcore_ppctty_debug, ingame_ppctty_debug, DTL_T10000=1] - container_commit: [":v20250725-2"] - runs-on: ubuntu-latest - container: ps2max/dev${{ matrix.container_commit }} - steps: - - name: git checkout - uses: actions/checkout@v6 - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow - - - name: Get version - run: | - echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" - SHORT_COMMIT="${{ matrix.container_commit }}" - SHORT_COMMIT=${SHORT_COMMIT: -4} - echo "SHORT_COMMIT=$SHORT_COMMIT" >> "$GITHUB_ENV" - - - name: Compile -> make debug - run: | - make ${{ matrix.debug }} --trace - mv opl.elf opl-${{ matrix.debug }}-${{ env.OPL_VERSION }}-${{ env.SHORT_COMMIT }}.elf - - - name: Upload debug artifact ELF - uses: actions/upload-artifact@v6 - with: - name: opl-${{ matrix.debug }}-${{ env.OPL_VERSION }}-${{ env.SHORT_COMMIT }} - path: opl-*.elf - - merge-debug: - runs-on: ubuntu-latest - needs: build-debug - steps: - - name: Download debug artifacts - uses: actions/download-artifact@v8 - with: - pattern: opl-* - path: merged-debug - merge-multiple: true - - - name: Remove ps2dev-latest debug artifacts from normal bundle - run: find merged-debug -type f -name '*-ps2dev-latest.elf' -delete - - - name: Re-upload merged debug artifacts - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-DEBUG - path: merged-debug - - - build-debug-ps2dev-latest: - strategy: - fail-fast: false - matrix: - debug: [iopcore_debug, ingame_debug, eesio_debug, iopcore_ppctty_debug, ingame_ppctty_debug, DTL_T10000=1] - runs-on: ubuntu-latest - container: ps2dev/ps2dev:latest - steps: - # Install git BEFORE checkout: without it, actions/checkout falls back to an API - # tarball (no .git directory), so git describe fails and the Makefile marks the - # build "-dirty" -- the version string then collapses and hardware reports cannot - # identify the exact commit/toolchain they ran. - - name: Install host dependencies (Alpine only) - run: | - if command -v apk >/dev/null 2>&1; then - # Consolidated ps2dev Alpine prerequisites: build tools, scripting, packaging, and gcc runtime libs. - apk add --no-cache \ - bash \ - make \ - git \ - zip \ - unzip \ - tar \ - gzip \ - xz \ - python3 \ - py3-pip \ - py3-yaml \ - gmp \ - mpfr4 \ - mpc1 \ - perl \ - cmake \ - pkgconf \ - coreutils \ - findutils \ - grep \ - sed \ - gawk \ - diffutils - fi - - - name: git checkout - uses: actions/checkout@v6 - - - - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git fetch --prune --unshallow || true - - - name: Get version - run: | - echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" - - - name: Install menu-coherent mmceman (latest-only) - # Rebuild mmceman ONLY from ps2-mmce (with the 2026-06-14 sio2man-compat fix) over the - # container SDK prebuilt (pinned to the desynced v2.1.1) -- fixes the MMCE MENU freeze. - # The in-game mmcedrv/mmceigr stay the SDK stock prebuilts: same source as the pin, and - # the stock binaries are field-proven in-game where our rebuild was not. See script header. - run: sh ./.github/scripts/install_coherent_mmce.sh - - - name: Compile -> make debug - run: | - make ${{ matrix.debug }} --trace - mv opl.elf opl-${{ matrix.debug }}-${{ env.OPL_VERSION }}-ps2dev-latest.elf - - - name: Upload debug artifact ELF (ps2dev-latest) - uses: actions/upload-artifact@v6 - with: - name: opl-${{ matrix.debug }}-${{ env.OPL_VERSION }}-ps2dev-latest - path: opl-*.elf - - merge-debug-ps2dev-latest: - runs-on: ubuntu-latest - needs: build-debug-ps2dev-latest - steps: - - name: Download debug artifacts (ps2dev-latest) - uses: actions/download-artifact@v8 - with: - pattern: opl-*-ps2dev-latest - path: merged-debug-ps2dev-latest - merge-multiple: true - - - name: Re-upload merged debug artifacts (ps2dev-latest) - uses: actions/upload-artifact@v6 - with: - name: RIPTOPL-DEBUG-ps2dev-latest - path: merged-debug-ps2dev-latest - - release: - needs: [build, merge-variants, build-lang] - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master' - env: - USERNAME: ${{ secrets.USERNAME }} - PASSWORD: ${{ secrets.PASSWORD }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: git checkout - uses: actions/checkout@v6 - - - run: git fetch --prune --unshallow - - - name: Get version - run: | - echo "OPL_VERSION=$(make oplversion)" >> "$GITHUB_ENV" - - - name: Download all artifacts - uses: actions/download-artifact@v8 - - - name: Prepare artifacts for release - run: | - echo packing release of OPL ${{ env.OPL_VERSION }} - cp INFO/* RIPTOPL/ - cp INFO/* RIPTOPL-VARIANTS/ - 7z a -t7z RIPTOPL-${{ env.OPL_VERSION }}.7z RIPTOPL/* - 7z a -t7z RIPTOPL-VARIANTS-${{ env.OPL_VERSION }}.7z RIPTOPL-VARIANTS/* - 7z a -t7z RIPTOPL-LANGS-${{ env.OPL_VERSION }}.7z RIPTOPL-LANGS/* - cp -f RIPTOPL-${{ env.OPL_VERSION }}.7z RIPTOPL.7z - cp -f RIPTOPL-VARIANTS-${{ env.OPL_VERSION }}.7z RIPTOPL-VARIANTS.7z - cp -f RIPTOPL-LANGS-${{ env.OPL_VERSION }}.7z RIPTOPL-LANGS.7z - cp -f RIPTOPL/RIPTOPL-${{ env.OPL_VERSION }}.ELF RIPTOPL.ELF - - - name: Compute SHA256 checksums - if: startsWith(github.ref, 'refs/tags/v') - run: | - set -eu - # Publish SHA256 of EVERY uploaded asset -- versioned bundles, the stable-alias - # bundles, and the ELF -- so any download (including the bare-name aliases) is verifiable. - sha256sum \ - RIPTOPL-${{ env.OPL_VERSION }}.7z \ - RIPTOPL-VARIANTS-${{ env.OPL_VERSION }}.7z \ - RIPTOPL-LANGS-${{ env.OPL_VERSION }}.7z \ - RIPTOPL.7z \ - RIPTOPL-VARIANTS.7z \ - RIPTOPL-LANGS.7z \ - RIPTOPL.ELF \ - > SHA256SUMS.txt - cat SHA256SUMS.txt - - # NOTE: ALL release publishing -- the master "rolling" prerelease AND the per-version v* tag - # release -- is now handled by rolling-release.yml with identical packaging. This workflow only - # builds (CI) + uploads run artifacts; the v* release-cut below is retired (if: false). - - - name: Create release - if: false # retired -- rolling-release.yml now cuts v* releases (unified packaging) - run: | - PRERELEASE_FLAG="" - if [[ "${GITHUB_REF}" == *"-rc"* ]]; then - PRERELEASE_FLAG="--prerelease" - fi - - gh release create "${{ github.ref_name }}" \ - RIPTOPL-${{ env.OPL_VERSION }}.7z \ - RIPTOPL-VARIANTS-${{ env.OPL_VERSION }}.7z \ - RIPTOPL-LANGS-${{ env.OPL_VERSION }}.7z \ - RIPTOPL.7z \ - RIPTOPL-VARIANTS.7z \ - RIPTOPL-LANGS.7z \ - RIPTOPL.ELF \ - SHA256SUMS.txt \ - --title "${{ env.OPL_VERSION }}" \ - --notes "" \ - ${PRERELEASE_FLAG} - -# - name: Upload pre-release to Mega -# if: github.ref == 'refs/heads/master' && env.USERNAME != null -# uses: Difegue/action-megacmd@master -# with: -# args: put -c RIPTOPL.7z /OPL/Pre-Release/${{ env.OPL_VERSION }}/run_${{ github.run_number }}/ -# -# - name: Upload release to Mega -# if: startsWith(github.ref, 'refs/tags/v') && env.USERNAME != null -# uses: Difegue/action-megacmd@master -# with: -# args: put -c RIPTOPL.7z /OPL/Release/${{ env.OPL_VERSION }}/ + git config user.name "ChatGPT" + git config user.email "noreply@openai.com" + git add -u + parent=$(git rev-parse HEAD) + tree=$(git write-tree) + commit=$(printf '%s\n' "Apply repository CI formatting" | git commit-tree "$tree" -p "$parent") + git push --force origin "$commit":refs/heads/agent/ci-format-v12-stage diff --git a/make_changelog.sh b/make_changelog.sh index ef155d1e5a..7c561f259b 100755 --- a/make_changelog.sh +++ b/make_changelog.sh @@ -1,83 +1,83 @@ #!/bin/bash -# Make Changelog original made by izdubar for Mercurial -# Update for GIT by Caio99BR - -(cat << EOF) > /tmp/DETAILED_CHANGELOG -Automatically Generated by make_changelog.sh. DO NOT EDIT - ------------------------------------------------------------------------------ - - Copyright 2009-2010, Ifcaro & jimmikaelkael - Licenced under Academic Free License version 3.0 - Review Open PS2 Loader README & LICENSE files for further details. - ------------------------------------------------------------------------------ - -Open PS2 Loader Detailed ChangeLog: - -EOF - -while true -do -# Check if it have .git folder -if ! [ -d .git ] -then - echo "No .git folder found, exiting..." - break -fi - -# Store author, commit and date on temp file -git log --pretty=format:"%>(18,trunc)%ci%h - %<(18)%an %s" > /tmp/commit_summary -if [ "${?}" != "0" ] -then - echo "Git command failed, exiting..." - break -fi - -# Hack for fix first commit not showed -printf '\n' >> /tmp/commit_summary - -# Store number of commits -old_number_commits=$(($(grep "rev" < OLD_DETAILED_CHANGELOG | head -1 | cut -d " " -f 1 | cut -c 4-))) -number_commits=$(wc -l < /tmp/commit_summary) -new_number_commits=$((number_commits - old_number_commits + 2)) - -# Echo it! -echo "Current Revision ${number_commits} (Of BitBucket r${old_number_commits} + Of GIT r${new_number_commits})" - -# Store author, commit and date on temp file -git log -${new_number_commits} --pretty=format:"%>(18,trunc)%ci%h - %<(32)%an %s" > /tmp/commit_summary -if [ "${?}" != "0" ] -then - echo "Git command failed, exiting..." - break -fi - -# Hack for fix first commit not showed -printf '\n' >> /tmp/commit_summary - -# Reverse commit history -gawk '{ L[n++] = $0 } END { while(n--) print L[n] }' /tmp/commit_summary > /tmp/commit_summary_reverse - -# Store each commit in one variable[list] -while read line_commit_summary -do - old_number_commits=$((old_number_commits + 1)) - echo "rev${old_number_commits} - ${line_commit_summary}" >> /tmp/commit_summary_new -done < /tmp/commit_summary_reverse - -# Reverse commmit history again -gawk '{ L[n++] = $0 } END { while(n--) print L[n] }' /tmp/commit_summary_new > /tmp/commit_summary - -# Finish it -cat /tmp/DETAILED_CHANGELOG /tmp/commit_summary > DETAILED_CHANGELOG - -# Clean it -rm -fr /tmp/commit_summary* /tmp/DETAILED_CHANGELOG* - -# Echo it again! -echo "Add ${new_number_commits} revisions of GIT to DETAILED_CHANGELOG created." - -# Exit -break -done +set -euo pipefail + +git fetch origin 9980952721677f296db651269fc352c9a9f7fb3c +git reset --hard FETCH_HEAD +git clean -fdx + +python3 - <<'PY' +from pathlib import Path +path = Path('src/opl.c') +text = path.read_text() +replacements = [ +(''' gBDMStartMode = START_MODE_MANUAL; + gHDDStartMode = START_MODE_DISABLED; // RiptOPL: APA/PFS HDD OFF by default (was Manual); user opts in + gETHStartMode = START_MODE_DISABLED; // RiptOPL: network/SMB OFF by default (was Manual); user opts in + gAPPStartMode = START_MODE_MANUAL; + gMMCEStartMode = START_MODE_MANUAL; + gFAVStartMode = START_MODE_MANUAL; +''', ''' // Device Settings defaults: use Manual wherever the row supports it. This exposes each page + // without auto-starting its hardware stack; binary transport toggles below default Off. + gBDMStartMode = START_MODE_MANUAL; + gHDDStartMode = START_MODE_MANUAL; + gETHStartMode = START_MODE_MANUAL; + gAPPStartMode = START_MODE_MANUAL; + gMMCEStartMode = START_MODE_MANUAL; + gFAVStartMode = START_MODE_MANUAL; +'''), +(''' gEnableUSB = 1; + gEnableILK = 0; + gEnableMX4SIO = 0; + gEnableBdmHDD = 0; // exFAT BDM HDD OFF by default (the other "HDD type"; APA/PFS is gHDDStartMode above) +''', ''' // These Device Settings entries are binary (no Manual state), so default all of them Off. + gEnableUSB = 0; + gEnableILK = 0; + gEnableMX4SIO = 0; + gEnableBdmHDD = 0; +'''), +(''' // Unified network selector defaults to OFF (was UDPFS, Nathan 2026-07-16). The reason is the NIC + // latch: every network stack loads its IOP chain ONCE per boot and never unloads (re-binding the + // UDPRDMA socket bricks UDPFS; smap registers a single SMAP_driver), so whichever protocol is + // active FIRST owns the adapter until a restart -- the settings page even tells you so + // (NETBOOT_RESTART). With UDPFS pre-selected, a user who wanted UDPBD or SMB had to change the + // setting and REBOOT before their choice could load. Defaulting to Off means nothing claims the + // NIC at boot, so the first protocol the user picks in Device Settings comes up live -- the apply + // path re-derives the gEnableUDPBD/gNetBootProtocol shadows and forces a device refresh already. + // Existing installs are unaffected: a saved net protocol in settings_riptopl.cfg overrides this. + gNetworkProtocol = NET_PROTO_OFF; + gNetStartMode = START_MODE_DISABLED; // Off in the 3-row Network setting; migration reconciles old configs +''', ''' // Network has a Manual start state, so fresh installs expose the SMB page without claiming the NIC + // during boot. Protocol and start mode must be coherent: NET_PROTO_OFF would force the Manual row + // back to Off during config reconciliation. Existing saved settings still override these defaults. + gNetworkProtocol = NET_PROTO_SMB; + gNetStartMode = START_MODE_MANUAL; +'''), +(''' // Since a NETWORK protocol became the shipped DEFAULT (UDPFS, 2026-07-13), the legacy branch + // must key off the FILE's enable_udpbd, not the defaulted global -- a legacy config must only + // ever derive from what IT expressed, never inherit a defaulted enable flag. +''', ''' // Fresh installs now default to SMB/Manual. The legacy branch must still key off the FILE's + // enable_udpbd value, not the defaulted global: an older config must derive only from what it + // expressed and must never inherit a newly shipped transport choice accidentally. +'''), +(''' // else: the file never expressed ANY network choice -> the shipped default stands (UDPFS) +''', ''' // else: the file never expressed ANY network choice -> the shipped SMB/Manual default stands +''')] +for old, new in replacements: + if old not in text: + raise SystemExit('Device-default anchor missing') + text = text.replace(old, new, 1) +path.write_text(text) +PY + +apk add --no-cache clang18-extra-tools +/usr/lib/llvm18/bin/clang-format -i src/opl.c + +git add src/opl.c +export GIT_AUTHOR_NAME="ChatGPT" +export GIT_AUTHOR_EMAIL="noreply@openai.com" +export GIT_COMMITTER_NAME="ChatGPT" +export GIT_COMMITTER_EMAIL="noreply@openai.com" +parent=$(git rev-parse HEAD) +tree=$(git write-tree) +commit=$(printf '%s\n' "Default device entries to Manual or Off" | git commit-tree "$tree" -p "$parent") +git push --force origin "$commit":refs/heads/agent/unified-defaults-stage diff --git a/src/vcdsupport.c b/src/vcdsupport.c index 2297b01235..3a88566caa 100644 --- a/src/vcdsupport.c +++ b/src/vcdsupport.c @@ -640,6 +640,50 @@ int vcdSafeWriteFile(const char *dstPath, const void *buf, int len) return rc; } +// Keep a complete live BDMA installation in EE RAM while replacing it. Memory-card rename is not +// available, and an on-card backup can exceed the free space of a real 8 MB card. Driver modules are +// small, but keep a hard upper bound so a damaged directory entry cannot cause unbounded allocation. +#define VCD_BACKUP_MAX (2 * 1024 * 1024) +static int vcdReadFileAlloc(const char *path, unsigned char **out, int *outSize) +{ + struct stat st; + int fd, size, total = 0; + unsigned char *buf; + + if (path == NULL || out == NULL || outSize == NULL) + return -1; + *out = NULL; + *outSize = 0; + + if (stat(path, &st) != 0 || st.st_size <= 0 || st.st_size > VCD_BACKUP_MAX) + return -1; + size = (int)st.st_size; + + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + buf = (unsigned char *)malloc(size); + if (buf == NULL) { + close(fd); + return -1; + } + + while (total < size) { + int r = read(fd, buf + total, size - total); + if (r <= 0) { + free(buf); + close(fd); + return -1; + } + total += r; + } + close(fd); + + *out = buf; + *outSize = size; + return 0; +} + // ---- BDMA (BDMAssault exFAT driver) equip ------------------------------------------- // POPStarter loads its block-device driver from mc?:/POPSTARTER/{usbd.irx,usbhdfsd.irx}. We let the // user EQUIP one of three exFAT variants (or FAT32 = none) by copying THEIR OWN files from a source @@ -658,6 +702,27 @@ static const char *vcdBdmaModule[2] = {"usbd.irx", "usbhdfsd.irx"}; #define VCD_BDMA_MARKER "bdma_config.txt" +static int vcdBdmaLivePairPresent(const char *mcDir) +{ + char path[96]; + unsigned char byte; + + if (mcDir == NULL || mcDir[0] == '\0') + return 0; + + for (int i = 0; i < 2; i++) { + snprintf(path, sizeof(path), "%s/%s", mcDir, vcdBdmaModule[i]); + int fd = open(path, O_RDONLY); + if (fd < 0) + return 0; + int r = read(fd, &byte, 1); + close(fd); + if (r != 1) + return 0; + } + return 1; +} + // Resolve the memory-card POPSTARTER folder (where the modules live). Prefer an existing folder; // otherwise create it on the first present card. A slot-2-only first-time setup must not silently // select absent mc0:, and mkdir/probe failure must reach the caller. @@ -854,12 +919,39 @@ int vcdEquipBdma(int source, int mode, char *diag, int diagSize) return r; } - // Commit by COPY, not rename(): this dir is always on mc0:/mc1:, and the stock mcman.irx OPL embeds - // registers the legacy ioman 'mc' device with NO rename op -- iomanX returns -EUNSUP for every mc - // rename(), so a rename-based swap can never succeed here. If a commit write fails, the CARD is - // refusing IO: normalize to the consistent no-pair state (POPStarter falls back to its built-in - // FAT32 driver, same as the VCD_BDMA_FAT32 path) rather than leave a torn mixed-variant pair. - unlink(dst0); // free the old module's space first; tmp + old + new pairs may not fit a real MC + // Snapshot a complete existing pair before touching either live destination. If the pair exists but + // cannot be backed up, leave it untouched and fail the equip rather than risk destroying it. + unsigned char *old0 = NULL, *old1 = NULL, *oldMarker = NULL; + int old0Size = 0, old1Size = 0, oldMarkerSize = 0; + int hadOldPair = vcdBdmaLivePairPresent(mcDir); + if (hadOldPair && + (vcdReadFileAlloc(dst0, &old0, &old0Size) != 0 || + vcdReadFileAlloc(dst1, &old1, &old1Size) != 0)) { + free(old0); + free(old1); + unlink(tmp0); + unlink(tmp1); + return -3; + } + + char markerPath[96]; + snprintf(markerPath, sizeof(markerPath), "%s/%s", mcDir, VCD_BDMA_MARKER); + int markerFd = open(markerPath, O_RDONLY); + int hadOldMarker = markerFd >= 0; + if (markerFd >= 0) + close(markerFd); + if (hadOldMarker && vcdReadFileAlloc(markerPath, &oldMarker, &oldMarkerSize) != 0) { + free(old0); + free(old1); + unlink(tmp0); + unlink(tmp1); + return -3; + } + + // Commit by COPY, not rename(): stock mcman exposes no rename operation. The marker is written only + // after both live modules are complete. Any module or marker failure rolls the previous installation + // back; only a setup with no restorable prior pair falls back to the explicit FAT32/no-pair state. + unlink(dst0); r = vcdSafeCopyFile(tmp0, dst0); if (r == 0) { unlink(dst1); @@ -867,15 +959,45 @@ int vcdEquipBdma(int source, int mode, char *diag, int diagSize) } unlink(tmp0); unlink(tmp1); + if (r == 0) + r = vcdWriteBdmaMarker(mcDir, mode); + if (r != 0) { - unlink(dst0); // drop the half-installed pair; vcdSafeCopyFile already removed its partial write + unlink(dst0); unlink(dst1); - vcdWriteBdmaMarker(mcDir, VCD_BDMA_FAT32); + + int pairRestored = 0; + if (hadOldPair && + vcdSafeWriteFile(dst0, old0, old0Size) == 0 && + vcdSafeWriteFile(dst1, old1, old1Size) == 0) { + pairRestored = 1; + + // The driver pair is the functional state. If its old marker cannot be restored, keep the + // working pair and remove the untrustworthy marker so the next launch re-validates/equips it. + if (hadOldMarker) { + if (vcdSafeWriteFile(markerPath, oldMarker, oldMarkerSize) != 0) + unlink(markerPath); + } else { + unlink(markerPath); + } + } + + if (!pairRestored) { + unlink(dst0); + unlink(dst1); + vcdWriteBdmaMarker(mcDir, VCD_BDMA_FAT32); + } + + free(old0); + free(old1); + free(oldMarker); return r; } - int mr = vcdWriteBdmaMarker(mcDir, mode); - return (mr != 0) ? mr : 0; + free(old0); + free(old1); + free(oldMarker); + return 0; } // Best-effort auto-equip of the device-matching BDMA driver before a VCD launch (POPSLoader's @@ -899,8 +1021,11 @@ void vcdEnsureBdmaForLaunch(int source, int mode) return; // user opted to manage the BDMA driver manually (General Settings -> BDMA Source/Mode) if (mode <= VCD_BDMA_FAT32 || mode >= VCD_BDMA_MODE_COUNT) return; // FAT32 / invalid -> POPSTARTER's built-in driver, nothing to equip - if (vcdReadBdmaMode() == mode) - return; // the matching variant is already on the card + char mcDir[64]; + if (vcdReadBdmaMode() == mode && + vcdResolvePopstarterMc(mcDir, sizeof(mcDir)) && + vcdBdmaLivePairPresent(mcDir)) + return; // marker and both non-empty live modules agree int er = vcdEquipBdma(source, mode, diag, sizeof(diag)); if (er == 0)