From 836b9a4aec8a2869ea13a314e91ed90e5cd0eb45 Mon Sep 17 00:00:00 2001 From: qiyinxi <52456734+qiyinxi@users.noreply.github.com> Date: Tue, 10 Nov 2026 15:18:54 +0100 Subject: [PATCH 1/2] =?UTF-8?q?v0.1.2=EF=BC=9ARelease=20=E5=8A=A0=E4=B8=8A?= =?UTF-8?q?=20macOS=E3=80=81Linux=20=E7=9A=84=E5=BA=93=EF=BC=8C=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E5=92=8C=E5=8F=91=E7=89=88=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release workflow 多编 macOS arm64 的 libmodavd_extras.dylib 和 Linux x64 的 libmodavd_extras.so, 和 Windows 的两个 DLL 一起按 tag 下的 SHA256SUMS 核对后上传。CI 的 posix job 打印这两个库的哈希, macOS 的最低版本定在 12。README 写明 macOS 实测过、Release 带三个平台的库。 --- .github/workflows/ci.yml | 10 ++++ .github/workflows/release.yml | 98 +++++++++++++++++++++++++++-------- CMakeLists.txt | 4 +- README.md | 5 +- release/0.1.2.md | 48 +++++++++++++++++ 5 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 release/0.1.2.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40635be..9187244 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,16 @@ jobs: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build ctest --test-dir build --output-on-failure + # In the format of release/.SHA256SUMS.txt, and what the library needs from the system. + cd build + if [ "$RUNNER_OS" = macOS ]; then + lib=libmodavd_extras.dylib + otool -l "$lib" | grep -A3 LC_BUILD_VERSION | grep minos + else + lib=libmodavd_extras.so + objdump -T "$lib" | grep -o 'GLIBC_[0-9.]*' | sort -uV | tail -n 1 + fi + cmake -E sha256sum "$lib" privacy: runs-on: ubuntu-24.04 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9cae70e..4da03d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,10 +11,10 @@ concurrency: cancel-in-progress: false jobs: - build: + check: if: github.repository == 'ModAVD/ModAVDExtras' && !github.event.deleted - runs-on: windows-2025 - timeout-minutes: 20 + runs-on: ubuntu-24.04 + timeout-minutes: 10 permissions: contents: read steps: @@ -22,7 +22,7 @@ jobs: with: persist-credentials: false fetch-depth: 0 - - name: verify tag, ancestry and version + - name: verify tag, ancestry, version and the hash list shell: pwsh env: TAG: ${{ github.ref_name }} @@ -37,6 +37,22 @@ jobs: if ($found.Count -ne 1) { throw "expected one project(ModAVDExtras VERSION ...) line in CMakeLists.txt, found $($found.Count)" } $want = $found[0].Matches[0].Groups[1].Value if ($want -cne $version) { throw "CMakeLists.txt version=$want, tag=$version" } + # Exactly one line per release file, sorted by name, as the CI jobs print them. + $names = @('external_renderer_ipc.dll', 'libmodavd_extras.dylib', 'libmodavd_extras.so', 'modavd_extras.dll') + $sums = Get-Content -Raw "release/$version.SHA256SUMS.txt" + $pattern = '\A' + (($names | ForEach-Object { '[0-9a-f]{64} ' + [regex]::Escape($_) + '\n' }) -join '') + '\z' + if ($sums -cnotmatch $pattern) { throw "release/$version.SHA256SUMS.txt must be one ' ' line for each of: $($names -join ', ')" } + + windows: + needs: check + runs-on: windows-2025 + timeout-minutes: 20 + permissions: + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: build, test and verify shell: pwsh env: @@ -50,22 +66,60 @@ jobs: ctest --test-dir build -C Release --output-on-failure if ($LASTEXITCODE -ne 0) { throw 'tests failed' } $version = $env:TAG.Substring(1) - # The list must be exactly these lines, in this order: what ci.yml prints for the same build. - $names = @('external_renderer_ipc.dll', 'modavd_extras.dll') - $lines = foreach ($name in $names) { '{0} {1}' -f (Get-FileHash "build/Release/$name" -Algorithm SHA256).Hash.ToLowerInvariant(), $name } - $lines - if ((Get-Content -Raw "release/$version.SHA256SUMS.txt") -cne (($lines -join "`n") + "`n")) { throw "release/$version.SHA256SUMS.txt must be exactly the lines above" } + $sums = (Get-Content -Raw "release/$version.SHA256SUMS.txt") -split "`n" New-Item -ItemType Directory -Force artifacts | Out-Null - foreach ($name in $names) { Copy-Item "build/Release/$name" artifacts } - Copy-Item "release/$version.SHA256SUMS.txt" artifacts/SHA256SUMS.txt + foreach ($name in 'external_renderer_ipc.dll', 'modavd_extras.dll') { + $line = '{0} {1}' -f (Get-FileHash "build/Release/$name" -Algorithm SHA256).Hash.ToLowerInvariant(), $name + $line + if ($sums -cnotcontains $line) { throw "release/$version.SHA256SUMS.txt does not have this line" } + Copy-Item "build/Release/$name" artifacts + } + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: release-windows + path: artifacts + if-no-files-found: error + + posix: + needs: check + strategy: + matrix: + os: [ubuntu-24.04, macos-15] + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + permissions: + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: build, test and verify + shell: bash + env: + TAG: ${{ github.ref_name }} + run: | + set -euo pipefail + # The same build as ci.yml's posix job. + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build + ctest --test-dir build --output-on-failure + if [ "$RUNNER_OS" = macOS ]; then lib=libmodavd_extras.dylib; else lib=libmodavd_extras.so; fi + line="$(cd build && cmake -E sha256sum "$lib")" + echo "$line" + if ! grep -Fxq -- "$line" "release/${TAG#v}.SHA256SUMS.txt"; then + echo "release/${TAG#v}.SHA256SUMS.txt does not have this line" >&2 + exit 1 + fi + mkdir artifacts + cp "build/$lib" artifacts/ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: - name: release-assets + name: release-${{ matrix.os }} path: artifacts if-no-files-found: error draft: - needs: build + needs: [windows, posix] runs-on: windows-2025 timeout-minutes: 10 permissions: @@ -77,26 +131,27 @@ jobs: fetch-depth: 1 - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: - name: release-assets + pattern: release-* path: artifacts - - name: verify artifact + merge-multiple: true + - name: verify artifacts shell: pwsh env: TAG: ${{ github.ref_name }} run: | - # Checked against the tag's own list, not only the copy that travelled with the artifact. + # Checked against the tag's own list, not only what the build jobs reported. $version = $env:TAG.Substring(1) $sums = Get-Content -Raw "release/$version.SHA256SUMS.txt" - if ((Get-Content -Raw artifacts/SHA256SUMS.txt) -cne $sums) { throw 'artifact SHA256SUMS.txt differs from the tag' } - $names = @('external_renderer_ipc.dll', 'modavd_extras.dll') + $names = @('external_renderer_ipc.dll', 'libmodavd_extras.dylib', 'libmodavd_extras.so', 'modavd_extras.dll') $have = (Get-ChildItem artifacts -File | ForEach-Object Name | Sort-Object) -join ',' - $expect = (@($names + 'SHA256SUMS.txt') | Sort-Object) -join ',' + $expect = ($names | Sort-Object) -join ',' if ($have -cne $expect) { throw "unexpected artifact files: $have" } foreach ($name in $names) { $want = [regex]::Match($sums, "(?m)^([0-9a-f]{64}) $([regex]::Escape($name))\r?$").Groups[1].Value $got = (Get-FileHash "artifacts/$name" -Algorithm SHA256).Hash.ToLowerInvariant() if (-not $want -or $got -ne $want) { throw "downloaded $name hash mismatch" } } + Copy-Item "release/$version.SHA256SUMS.txt" artifacts/SHA256SUMS.txt - name: create draft shell: pwsh env: @@ -109,11 +164,12 @@ jobs: $tags = gh api "repos/$env:GH_REPO/releases?per_page=100" --paginate --jq '.[].tag_name' if ($LASTEXITCODE -ne 0) { throw 'cannot list releases' } if ($tags -contains $env:TAG) { throw "a release for $env:TAG already exists (draft or published)" } - # --verify-tag only checks that the tag exists: make sure it still points at the commit the build job built. + # --verify-tag only checks that the tag exists: make sure it still points at the commit the build jobs built. $head = git rev-parse HEAD if ($LASTEXITCODE -ne 0) { throw 'git rev-parse failed' } $tagCommit = gh api "repos/$env:GH_REPO/commits/tags/$env:TAG" --jq .sha if ($LASTEXITCODE -ne 0) { throw "cannot resolve $env:TAG" } if ($tagCommit -ne $head) { throw "$env:TAG now points at $tagCommit; this run built $head" } - gh release create $env:TAG --draft --verify-tag --notes-file "release/$version.md" artifacts/modavd_extras.dll artifacts/external_renderer_ipc.dll artifacts/SHA256SUMS.txt + $files = @('modavd_extras.dll', 'external_renderer_ipc.dll', 'libmodavd_extras.so', 'libmodavd_extras.dylib', 'SHA256SUMS.txt') | ForEach-Object { "artifacts/$_" } + gh release create $env:TAG --draft --verify-tag --notes-file "release/$version.md" @files if ($LASTEXITCODE -ne 0) { throw 'gh release create failed' } diff --git a/CMakeLists.txt b/CMakeLists.txt index 180313a..80390cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.20) -project(ModAVDExtras VERSION 0.1.1 LANGUAGES C) +# macOS: the oldest release the library loads on. Without it the build machine's SDK version is used. +set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum macOS version") +project(ModAVDExtras VERSION 0.1.2 LANGUAGES C) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index 563512c..02636f8 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,9 @@ - v0.1:只有截图。点击、按键、文字的函数已经声明,现在返回 `MODAVD_E_UNSUPPORTED`。 - Windows:截图这套逻辑在 ModAVD 上已经用了一个多月,形式是下面的兼容外壳。 -- Linux、macOS:能编,单元测试在 CI 上跑;还没有在模拟器上实测。 +- macOS(Apple Silicon):11-09 有贡献者用官方 Emulator 37.2.13、API 35 ARM64 实测过截图。 +- Linux:能编,单元测试在 CI 上跑;还没有在模拟器上实测。 +- [Release](https://github.com/ModAVD/ModAVDExtras/releases) 从 v0.1.2 起带三个平台的库:Windows x64 的 `modavd_extras.dll`、macOS arm64 的 `libmodavd_extras.dylib`、Linux x64 的 `libmodavd_extras.so`,外壳 `external_renderer_ipc.dll` 只有 Windows 版。 ## 接口 @@ -109,5 +111,6 @@ ModAVDExtras is a small C library that reads the screen of a [ModAVD](https://gi - The library finds the console port from an adb address, starts frame sharing through the console when it is off, copies a frame in the format the caller asks for (copying again if a new frame arrived meanwhile), and reports whether capture is usable. It never falls back to adb by itself. - Version 0.1 does screen capture only; the input functions are declared and return `MODAVD_E_UNSUPPORTED`. See [include/modavd_extras.h](include/modavd_extras.h). - `external_renderer_ipc.dll` is a Windows-only compatibility shell. It exports the four capture functions that MaaCore looks up in MuMu's DLL, on top of the same code, so MaaCore versions that do not know ModAVD can still capture from it. AUTO-MAS uses it today. It will be retired once MaaCore can connect to ModAVD directly. +- Status: Windows has used this capture code for over a month through the shell below; on Apple Silicon macOS a contributor tested capture with the official Emulator 37.2.13 and API 35 ARM64; Linux builds and passes the unit tests in CI but has not been tested with an emulator. From v0.1.2 the [releases](https://github.com/ModAVD/ModAVDExtras/releases) carry `modavd_extras.dll` (Windows x64), `libmodavd_extras.dylib` (macOS arm64) and `libmodavd_extras.so` (Linux x64), plus the Windows-only shell. - Build: `build.ps1` on Windows (Visual Studio 2022 Build Tools, CMake, Ninja); CMake on Linux and macOS. The unit tests need no emulator. - License: LGPL-3.0-or-later ([LICENSE](LICENSE), [COPYING](COPYING)). Only code written for this project goes in; code from GPL or AGPL projects such as MaaCore does not. diff --git a/release/0.1.2.md b/release/0.1.2.md new file mode 100644 index 0000000..9c4e3e2 --- /dev/null +++ b/release/0.1.2.md @@ -0,0 +1,48 @@ +# ModAVDExtras v0.1.2 + +- `modavd_extras.dll`:`@WIN_LIB@` +- `external_renderer_ipc.dll`:`@WIN_SHIM@` +- `libmodavd_extras.dylib`:`@MAC_LIB@` +- `libmodavd_extras.so`:`@LINUX_LIB@` + +这一版起 Release 也带 macOS、Linux 的库;另外修了 Linux、macOS 上截图会拿到旧画面的问题。接口版本还是 1,头文件只改了注释,调用方不用重编。 + +## 新增 + +- macOS arm64 的 `libmodavd_extras.dylib`(macOS 12 起能载入)和 Linux x64 的 `libmodavd_extras.so`(要 glibc @GLIBC@ 或更新)。 + - 接口和 Windows 的 `modavd_extras.dll` 一样,见 `include/modavd_extras.h`。 + - macOS 上有贡献者在 Apple Silicon 上用官方 Emulator 37.2.13、API 35 ARM64 实测过截图。Linux 还没有在模拟器上实测。 + +## 修复 + +- Linux、macOS:模拟器退出后共享内存还在,下次冷启动时库直接认了上次的末帧,截到的一直是旧画面(#8)。现在 `modavd_open` 默认先经控制台开流,成功了才打开映射;控制台鉴权或命令失败时返回 `MODAVD_E_IO`,不再被旧映射掩盖。确定映射属于当前实例、而且已经在开流的,可以带 `MODAVD_OPEN_NO_START` 跳过控制台。 +- 所有平台:开了流、第一帧还没到时,`modavd_capture` 返回 `MODAVD_E_NOT_READY`,以前返回成功和一张全黑的图(#8)。稍后再调就行。 +- `external_renderer_ipc.dll`:行为不变。第一帧到之前照旧交出尺寸和黑图、返回成功,和它替换的 DLL 一样,因为 MaaCore 连上时马上要问尺寸,失败就放弃这条路(#9)。 +- `modavd_version_string()` 返回 `"0.1.2"`。 + +## 许可证与源码 + +- LGPL-3.0-or-later。正文是 tag 下的 [LICENSE](https://github.com/ModAVD/ModAVDExtras/blob/v0.1.2/LICENSE)(LGPL-3.0)和 [COPYING](https://github.com/ModAVD/ModAVDExtras/blob/v0.1.2/COPYING)(GPL-3.0);转发这些库时请一起带上。 +- 源码:。 + +## 下载与核对 + +四个文件都由本仓库的 release workflow 在 GitHub 上编出,和 tag 下的 `release/0.1.2.SHA256SUMS.txt` 核对过才上传: + +- Windows:`windows-2025`,`cmake -A x64`,`--config Release`。两个 DLL 都静态链接 C 运行库,只依赖 `KERNEL32`、`WS2_32`。编译带 `/Brepro`:同样的命令、同一版本的 MSVC 和 Windows SDK 能编出相同的字节。MSVC 版本在 workflow 日志里 CMake 配置那一步,Windows SDK 跟着 runner 镜像,镜像版本在「Set up job」那一步。 +- macOS:`macos-15`(Apple Silicon),`cmake -DCMAKE_BUILD_TYPE=Release`。 +- Linux:`ubuntu-24.04`(x64),`cmake -DCMAKE_BUILD_TYPE=Release`。 + +请用附件 `SHA256SUMS.txt` 核对:Windows 上 `Get-FileHash .\modavd_extras.dll -Algorithm SHA256`,macOS 上 `shasum -a 256 libmodavd_extras.dylib`,Linux 上 `sha256sum libmodavd_extras.so`。 + +## English + +From this release the releases also carry the macOS and Linux libraries, and a Linux / macOS issue where capture returned a stale frame is fixed. The API version is still 1 and only comments changed in the header, so callers need not rebuild. + +- New: `libmodavd_extras.dylib` for macOS arm64 (loads on macOS 12 and later) and `libmodavd_extras.so` for Linux x64 (needs glibc @GLIBC@ or later), with the same API as `modavd_extras.dll` (`include/modavd_extras.h`). A contributor tested capture on Apple Silicon with the official Emulator 37.2.13 and API 35 ARM64; Linux has not been tested with an emulator yet. +- Fixed on Linux and macOS: the shared memory outlives the emulator, so on the next cold boot the library took the last frame of the previous run and kept returning it (#8). By default `modavd_open` now starts frame sharing through the console before it opens the mapping; console auth or command failures return `MODAVD_E_IO` instead of being hidden by an old mapping. Callers that know the mapping belongs to the running instance and sharing is on can pass `MODAVD_OPEN_NO_START` to skip the console. +- Fixed on all platforms: after sharing starts and before the first frame arrives, `modavd_capture` returns `MODAVD_E_NOT_READY` instead of success and an all-black frame (#8). Call again a little later. +- `external_renderer_ipc.dll`: unchanged behaviour. Before the first frame it still reports the size and a black frame with success, as the DLL it replaces did, because MaaCore asks for the size right after connecting and gives up on that path if it fails (#9). +- `modavd_version_string()` returns `"0.1.2"`. +- License: LGPL-3.0-or-later; the texts are [LICENSE](https://github.com/ModAVD/ModAVDExtras/blob/v0.1.2/LICENSE) (LGPL-3.0) and [COPYING](https://github.com/ModAVD/ModAVDExtras/blob/v0.1.2/COPYING) (GPL-3.0) at the tag. Ship them with the libraries. Source: . +- All four files are built by this repository's release workflow on GitHub (Windows: `windows-2025`, `cmake -A x64`, `--config Release`, with `/Brepro`, static C runtime, depending only on `KERNEL32` and `WS2_32`; macOS: `macos-15` on Apple Silicon; Linux: `ubuntu-24.04` x64; both `cmake -DCMAKE_BUILD_TYPE=Release`) and checked against `release/0.1.2.SHA256SUMS.txt` at the tag before upload. Check them with the attached `SHA256SUMS.txt`. From c433754b5b4ef1d62895035a040dfadf3ef54431 Mon Sep 17 00:00:00 2001 From: qiyinxi <52456734+qiyinxi@users.noreply.github.com> Date: Tue, 10 Nov 2026 15:23:12 +0100 Subject: [PATCH 2/2] =?UTF-8?q?v0.1.2=EF=BC=9A=E5=A1=AB=E4=B8=8A=20CI=20?= =?UTF-8?q?=E7=BC=96=E5=87=BA=E7=9A=84=E5=93=88=E5=B8=8C=EF=BC=9B=E5=8F=91?= =?UTF-8?q?=E7=89=88=E5=89=8D=E6=9F=A5=E5=8F=91=E7=89=88=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E9=87=8C=E6=B2=A1=E6=9C=89=E7=95=99=E4=B8=8B=E5=8D=A0=E4=BD=8D?= =?UTF-8?q?=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 ++ release/0.1.2.SHA256SUMS.txt | 4 ++++ release/0.1.2.md | 12 ++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 release/0.1.2.SHA256SUMS.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4da03d1..0ec855e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,6 +42,8 @@ jobs: $sums = Get-Content -Raw "release/$version.SHA256SUMS.txt" $pattern = '\A' + (($names | ForEach-Object { '[0-9a-f]{64} ' + [regex]::Escape($_) + '\n' }) -join '') + '\z' if ($sums -cnotmatch $pattern) { throw "release/$version.SHA256SUMS.txt must be one ' ' line for each of: $($names -join ', ')" } + # The notes are written before CI prints the hashes, with @NAME@ where they go. + if ((Get-Content -Raw "release/$version.md") -cmatch '@[A-Z_]+@') { throw "release/$version.md still has a placeholder: $($Matches[0])" } windows: needs: check diff --git a/release/0.1.2.SHA256SUMS.txt b/release/0.1.2.SHA256SUMS.txt new file mode 100644 index 0000000..d1d3700 --- /dev/null +++ b/release/0.1.2.SHA256SUMS.txt @@ -0,0 +1,4 @@ +8a0a82a59745da36e93eba6278dbacfab67616a415fd0780b24a9b03f7bb99ed external_renderer_ipc.dll +84fbbdd76fc3262bae9e058777d4bc20c800426883ce3f47ac29ec7d2ed5cb62 libmodavd_extras.dylib +c18c2b2f1f00346b944c2bd85213b8654b557fbe7dc7bd04670e84e782cbef56 libmodavd_extras.so +a5ef972919d76c7821225ada2d67d322b2f0128e195ba34d69bbf9aa9759daba modavd_extras.dll diff --git a/release/0.1.2.md b/release/0.1.2.md index 9c4e3e2..c037ff5 100644 --- a/release/0.1.2.md +++ b/release/0.1.2.md @@ -1,15 +1,15 @@ # ModAVDExtras v0.1.2 -- `modavd_extras.dll`:`@WIN_LIB@` -- `external_renderer_ipc.dll`:`@WIN_SHIM@` -- `libmodavd_extras.dylib`:`@MAC_LIB@` -- `libmodavd_extras.so`:`@LINUX_LIB@` +- `modavd_extras.dll`:`a5ef972919d76c7821225ada2d67d322b2f0128e195ba34d69bbf9aa9759daba` +- `external_renderer_ipc.dll`:`8a0a82a59745da36e93eba6278dbacfab67616a415fd0780b24a9b03f7bb99ed` +- `libmodavd_extras.dylib`:`84fbbdd76fc3262bae9e058777d4bc20c800426883ce3f47ac29ec7d2ed5cb62` +- `libmodavd_extras.so`:`c18c2b2f1f00346b944c2bd85213b8654b557fbe7dc7bd04670e84e782cbef56` 这一版起 Release 也带 macOS、Linux 的库;另外修了 Linux、macOS 上截图会拿到旧画面的问题。接口版本还是 1,头文件只改了注释,调用方不用重编。 ## 新增 -- macOS arm64 的 `libmodavd_extras.dylib`(macOS 12 起能载入)和 Linux x64 的 `libmodavd_extras.so`(要 glibc @GLIBC@ 或更新)。 +- macOS arm64 的 `libmodavd_extras.dylib`(macOS 12 起能载入)和 Linux x64 的 `libmodavd_extras.so`(要 glibc 2.34 或更新)。 - 接口和 Windows 的 `modavd_extras.dll` 一样,见 `include/modavd_extras.h`。 - macOS 上有贡献者在 Apple Silicon 上用官方 Emulator 37.2.13、API 35 ARM64 实测过截图。Linux 还没有在模拟器上实测。 @@ -39,7 +39,7 @@ From this release the releases also carry the macOS and Linux libraries, and a Linux / macOS issue where capture returned a stale frame is fixed. The API version is still 1 and only comments changed in the header, so callers need not rebuild. -- New: `libmodavd_extras.dylib` for macOS arm64 (loads on macOS 12 and later) and `libmodavd_extras.so` for Linux x64 (needs glibc @GLIBC@ or later), with the same API as `modavd_extras.dll` (`include/modavd_extras.h`). A contributor tested capture on Apple Silicon with the official Emulator 37.2.13 and API 35 ARM64; Linux has not been tested with an emulator yet. +- New: `libmodavd_extras.dylib` for macOS arm64 (loads on macOS 12 and later) and `libmodavd_extras.so` for Linux x64 (needs glibc 2.34 or later), with the same API as `modavd_extras.dll` (`include/modavd_extras.h`). A contributor tested capture on Apple Silicon with the official Emulator 37.2.13 and API 35 ARM64; Linux has not been tested with an emulator yet. - Fixed on Linux and macOS: the shared memory outlives the emulator, so on the next cold boot the library took the last frame of the previous run and kept returning it (#8). By default `modavd_open` now starts frame sharing through the console before it opens the mapping; console auth or command failures return `MODAVD_E_IO` instead of being hidden by an old mapping. Callers that know the mapping belongs to the running instance and sharing is on can pass `MODAVD_OPEN_NO_START` to skip the console. - Fixed on all platforms: after sharing starts and before the first frame arrives, `modavd_capture` returns `MODAVD_E_NOT_READY` instead of success and an all-black frame (#8). Call again a little later. - `external_renderer_ipc.dll`: unchanged behaviour. Before the first frame it still reports the size and a black frame with success, as the DLL it replaces did, because MaaCore asks for the size right after connecting and gives up on that path if it fails (#9).