Compare commits
No commits in common. "master" and "v1.13.0" have entirely different histories.
|
@ -1,13 +0,0 @@
|
|||
;;; Directory Local Variables
|
||||
;;; See Info node `(emacs) Directory Variables' for more information.
|
||||
|
||||
(
|
||||
(c-mode . ((c-basic-offset . 3)
|
||||
(c-file-offsets . ((arglist-intro . ++)
|
||||
(arglist-cont-nonempty . ++)))
|
||||
(eval . (setq-local c-cleanup-list
|
||||
(cl-set-difference c-cleanup-list
|
||||
'(brace-else-brace
|
||||
brace-elseif-brace))))))
|
||||
(objc-mode . ((c-basic-offset . 3)))
|
||||
)
|
|
@ -0,0 +1,35 @@
|
|||
# First and foremost consider this:
|
||||
- Only RetroArch bugs should be filed here. Not core bugs or game bugs
|
||||
- This is not a forum or a help section, this is strictly developer oriented
|
||||
|
||||
## Description
|
||||
|
||||
[Description of the bug]
|
||||
|
||||
### Expected behavior
|
||||
|
||||
[What you expected to happen]
|
||||
|
||||
### Actual behavior
|
||||
|
||||
[What is actually happening]
|
||||
|
||||
### Steps to reproduce the bug
|
||||
|
||||
1. [First step]
|
||||
2. [Second step]
|
||||
3. [and so on...]
|
||||
|
||||
### Bisect Results
|
||||
|
||||
[Try to bisect and tell us when this started happening]
|
||||
|
||||
### Version/Commit
|
||||
You can find this information under Information/System Information
|
||||
|
||||
- RetroArch: [version/commit]
|
||||
|
||||
### Environment information
|
||||
|
||||
- OS: [The operating system you're running]
|
||||
- Compiler: [In case you are running local builds]
|
|
@ -1,100 +0,0 @@
|
|||
name: Bug report
|
||||
description: This is not a forum or a help section, this is strictly developer oriented.
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Only RetroArch bugs should be filed here. Not core bugs or game bugs
|
||||
options:
|
||||
- label: This is a bug in RetroArch frontend
|
||||
required: true
|
||||
- label: I have searched the existing issues
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Description of the actual behavior of the bug
|
||||
placeholder: What is actually happening
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: What you expected to happen
|
||||
|
||||
- type: textarea
|
||||
id: reproduce_steps
|
||||
attributes:
|
||||
label: Steps to reproduce the bug
|
||||
description: List all steps to reproduce the problem
|
||||
placeholder: |
|
||||
1. [First step]
|
||||
2. [Second step]
|
||||
3. [and so on...]
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version/Commit
|
||||
description: You can find this information under Information/System Information
|
||||
placeholder: 1.20.0 (Git ab3b175)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: bisecting
|
||||
attributes:
|
||||
label: Bisect Results
|
||||
description: Did this work with any older RetroArch version? Can you point to a version (or even commit) where it broke?
|
||||
placeholder: 43105ab
|
||||
|
||||
- type: dropdown
|
||||
id: nigthly
|
||||
attributes:
|
||||
label: Present in the nightly version
|
||||
description: Is the issue reproducible with current [nightly builds](https://buildbot.libretro.com/nightly/)?
|
||||
options:
|
||||
- I don't know
|
||||
- Yes, this is reproduced in the nightly build
|
||||
- No, looks like this is already resolved
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform & operating system
|
||||
description: The system you're running RetroArch on
|
||||
placeholder: Linux aarch64, Windows 11 23H2, Android 14, PS Vita
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: cores
|
||||
attributes:
|
||||
label: Affected Cores
|
||||
description: List the affected cores and their versions here, if applicable. If the issue **only occurs with a single core** then the bug may not be with RetroArch; in that case, you should report it in that core's repository instead of here.
|
||||
placeholder: bsnes (115), FCEUmm ((SVN) aebea87), Snes9x (1.63.229933ea)
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment information
|
||||
description: Additional information about hardware and software
|
||||
placeholder: |
|
||||
* Window Manager: dwm/X11
|
||||
* Affected video drivers: sdl2, glcore
|
||||
* Installed through Flatpak
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Paste [RetroArch log](https://docs.libretro.com/guides/generating-retroarch-logs/) and/or [GDB backtrace](https://docs.libretro.com/development/retroarch/debugging/). This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
name: Feature request
|
||||
title: "[Feature Request] <FEATURE NAME>"
|
||||
about: Is there something you'd like to see in RetroArch?
|
||||
labels: feature request
|
||||
---
|
|
@ -1,14 +0,0 @@
|
|||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Libretro Forums
|
||||
url: https://forums.libretro.com
|
||||
about: A place to discuss all things libretro
|
||||
- name: Discord
|
||||
url: https://ra-link.web.app/discord
|
||||
about: Join our Discord server for help
|
||||
- name: RetroArch/libretro subreddit
|
||||
url: https://www.reddit.com/r/RetroArch
|
||||
about: Subreddit dedicated to RetroArch and the libretro API framework
|
||||
- name: Documentation
|
||||
url: https://docs.libretro.com
|
||||
about: Official RetroArch documentation for users and developers
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile Salamander
|
||||
run: |
|
||||
|
@ -30,7 +27,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.ctr -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 clean
|
||||
make -f Makefile.ctr -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.ctr -j$(getconf _NPROCESSORS_ONLN) USE_CTRULIB_2=1 HAVE_STATIC_DUMMY=1
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-3DS-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch_3ds.cia
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
name: CI Android
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types: [run_build]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
cd pkg/android/phoenix
|
||||
./gradlew assembleDebug
|
||||
find . -iname "*.apk" -exec ls -l "{}" \;
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: retroarch-android-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
pkg/android/phoenix/build/outputs/apk/normal/debug/phoenix-normal-debug.apk
|
||||
pkg/android/phoenix/build/outputs/apk/aarch64/debug/phoenix-aarch64-debug.apk
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -25,13 +22,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.dos -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-DOS-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
|
@ -31,3 +28,8 @@ jobs:
|
|||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-Emscripten-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch.js
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,13 +17,18 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.ngc -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-GameCube-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch_ngc.dol
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
name: CI Linux (i686)
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
repository_dispatch:
|
||||
types: [run_build]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: git.libretro.com:5050/libretro-infrastructure/libretro-build-i386-ubuntu:xenial-gcc9
|
||||
options: --user root
|
||||
|
||||
steps:
|
||||
- name: Check Out Repo
|
||||
uses: taiki-e/checkout-action@v1
|
||||
|
||||
- name: Configure Build
|
||||
run: |
|
||||
./configure --disable-qt --enable-xdelta
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
make -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -j$(getconf _NPROCESSORS_ONLN) info all
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
|
@ -1,58 +0,0 @@
|
|||
name: CI Windows (MSVC)
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
repository_dispatch:
|
||||
types: [run_build]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
# These jobs run smoke tests to ensure that MSVC-specific builds work properly.
|
||||
jobs:
|
||||
|
||||
msvc:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
version: [UWP, 2019, 2022]
|
||||
configuration: [Debug, Release]
|
||||
platform: [x64]
|
||||
exclude:
|
||||
- version: UWP
|
||||
configuration: Debug
|
||||
include:
|
||||
- version: UWP
|
||||
configuration: ReleaseAngle
|
||||
platform: x64
|
||||
# Qt and Cg builds are excluded for now
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Compile RA
|
||||
working-directory: "${{github.workspace}}/pkg/msvc${{ matrix.version == 'UWP' && '-uwp' || ''}}"
|
||||
run: |
|
||||
msbuild -p:"Configuration=${{matrix.configuration}}" -p:"Platform=${{matrix.platform}}" .\RetroArch-msvc${{matrix.version}}.sln
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
shell: powershell
|
||||
run: echo "sha8=$('${{github.sha}}'.Substring(0,8))" >> $env:GITHUB_OUTPUT
|
||||
# https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: retroarch-${{matrix.version}}-${{matrix.configuration}}-${{matrix.platform}}-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
${{ matrix.version != 'UWP' }}:
|
||||
pkg/msvc/${{matrix.platform}}/${{matrix.configuration}}/RetroArch-msvc${{matrix.version}}.exe
|
||||
${{ matrix.version == 'UWP' }}:
|
||||
pkg/msvc-uwp/AppPackages/RetroArch-msvcUWP
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
name: CI Windows (MSYS2)
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
repository_dispatch:
|
||||
types: [run_build]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
msys2-build-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sys: [MINGW64, UCRT64,CLANG64]
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
update: true
|
||||
install: base-devel git
|
||||
pacboy: >-
|
||||
gettext:p
|
||||
gobject-introspection:p
|
||||
graphite2:p
|
||||
p11-kit:p
|
||||
qt6:p
|
||||
qt6-3d:p
|
||||
qt6-charts:p
|
||||
qt6-datavis3d:p
|
||||
qt6-imageformats:p
|
||||
qt6-location:p
|
||||
qt6-lottie:p
|
||||
qt6-networkauth:p
|
||||
qt6-quick3dphysics:p
|
||||
qt6-quicktimeline:p
|
||||
qt6-remoteobjects:p
|
||||
qt6-scxml:p
|
||||
qt6-sensors:p
|
||||
qt6-serialbus:p
|
||||
qt6-speech:p
|
||||
qt6-tools:p
|
||||
qt6-translations:p
|
||||
qt6-virtualkeyboard:p
|
||||
qt6-webchannel:p
|
||||
qt6-websockets:p
|
||||
x264:p
|
||||
cc:p
|
||||
|
||||
- name: Configure and build RetroArch
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
echo "Building RetroArch in ${{ matrix.sys }} environment"
|
||||
./configure
|
||||
make -j$(nproc) info all
|
||||
|
||||
- name: Collect DLLs and binaries
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
echo "Collecting DLLs and binaries"
|
||||
mkdir -p dist
|
||||
cp retroarch.exe dist/
|
||||
ldd retroarch.exe|grep $MINGW_PREFIX |awk '{print $3}'|xargs -I {} cp {} dist/
|
||||
|
||||
- name: Archive build artifacts
|
||||
if: success()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: retroarch-${{ matrix.sys }}
|
||||
path: dist/
|
|
@ -1,33 +0,0 @@
|
|||
name: CI macOS
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
set -o pipefail
|
||||
xcodebuild -workspace pkg/apple/RetroArch.xcworkspace -scheme RetroArch -config Release -xcconfig pkg/apple/GitHubCI.xcconfig -derivedDataPath build | xcpretty --color
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RetroArch-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
build/Build/Products/Release
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -25,13 +22,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.miyoo clean
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.miyoo info all
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.miyoo
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: retroarch_miyoo_arm32${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -30,13 +27,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.ps2 -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.ps2 -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info release
|
||||
make -f Makefile.ps2 -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 release
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-PS2-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
name: CI PS3/PSL1GHT
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
repository_dispatch:
|
||||
types: [run_build]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: git.libretro.com:5050/libretro-infrastructure/libretro-build-psl1ght:latest
|
||||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile Salamander
|
||||
run: |
|
||||
make -f Makefile.psl1ght.salamander -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.psl1ght.salamander -j$(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.psl1ght -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.psl1ght -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RA-psl1ght-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch_psl1ght_salamander.elf
|
||||
retroarch_psl1ght.elf
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -31,13 +28,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
export PATH=~/cli:$PATH # .net cli
|
||||
make -f Makefile.orbis -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.orbis -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bin-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -42,7 +39,7 @@ jobs:
|
|||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-PSP-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -30,12 +27,12 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 HAVE_VITAGLES=1 info all
|
||||
make -f Makefile.vita -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 HAVE_VITAGLES=1
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-PSVita-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -25,13 +22,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.rs90 clean
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.rs90 info all
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.rs90
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: retroarch_rs90_mips32${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -25,13 +22,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.retrofw clean
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.retrofw info all
|
||||
make -j$(getconf _NPROCESSORS_ONLN) -f Makefile.retrofw
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: retroarch_retrofw_mips32${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
name: CI Generate Source Only Tarball
|
||||
|
||||
# Trigger whenever a release and/or is created
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
push:
|
||||
tags:
|
||||
- "v*.*"
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: archive
|
||||
id: archive
|
||||
run: |
|
||||
VERSION=${GITHUB_REF##*/}
|
||||
test -z "$VERSION" && VERSION=${{ github.event.release.tag_name }}
|
||||
VERSION=$(printf "%s\n" "$VERSION" | sed 's/^v//')
|
||||
PKGNAME="retroarch-sourceonly-$VERSION"
|
||||
mkdir -p /tmp/$PKGNAME
|
||||
mv * /tmp/$PKGNAME
|
||||
mv /tmp/$PKGNAME .
|
||||
rm -rf $PKGNAME/pkg || true
|
||||
rm -rf $PKGNAME/wii/libogc || true
|
||||
rm -rf $PKGNAME/deps/glslang/glslang/Test || true
|
||||
rm -rf $PKGNAME/deps/SPIRV-Cross/reference || true
|
||||
rm -rf $PKGNAME/gfx/include/userland || true
|
||||
find $PKGNAME/ -type f -name '*.a' -delete || true
|
||||
find $PKGNAME/ -type f -name '*.lib' -delete || true
|
||||
find $PKGNAME/ -type f -name '*.dylib' -delete || true
|
||||
find $PKGNAME/ -type f -name '*.so.*' -delete || true
|
||||
find $PKGNAME/ -type f -name '*.dll' -delete || true
|
||||
TARBALL=$PKGNAME.tar.xz
|
||||
tar cJf $TARBALL $PKGNAME
|
||||
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: upload tarball
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ steps.archive.outputs.tarball }}
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -30,7 +27,7 @@ jobs:
|
|||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-libnx-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile Salamander
|
||||
run: |
|
||||
|
@ -30,8 +27,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.wii -j$(getconf _NPROCESSORS_ONLN) EXTERNAL_LIBOGC=1 GX_PTHREAD_LEGACY=0 HAVE_STATIC_DUMMY=1
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-Wii-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch_wii.dol
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile Salamander
|
||||
run: |
|
||||
|
@ -30,7 +27,13 @@ jobs:
|
|||
- name: Compile RA
|
||||
run: |
|
||||
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) clean
|
||||
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1 info all
|
||||
make -f Makefile.wiiu -j$(getconf _NPROCESSORS_ONLN) HAVE_STATIC_DUMMY=1
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RA-WiiU-dummy-${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch.rpx
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
|
@ -32,3 +29,9 @@ jobs:
|
|||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: retroarch${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch.exe
|
||||
|
|
|
@ -9,9 +9,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -20,7 +17,7 @@ jobs:
|
|||
options: --user root
|
||||
|
||||
steps:
|
||||
- uses: taiki-e/checkout-action@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile RA
|
||||
run: |
|
||||
|
@ -32,3 +29,9 @@ jobs:
|
|||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: retroarch${{ steps.slug.outputs.sha8 }}
|
||||
path: |
|
||||
retroarch.exe
|
||||
|
|
|
@ -16,12 +16,12 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Checkout
|
||||
|
|
|
@ -18,12 +18,12 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Checkout
|
||||
|
|
|
@ -13,9 +13,6 @@ on:
|
|||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
linux-c89: # Smoketest build using most restrictive compiler and default options
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -33,4 +30,4 @@ jobs:
|
|||
- name: Build Debug
|
||||
run: |
|
||||
make clean # making sure we don't have leftovers from previous build
|
||||
make DEBUG=1 GL_DEBUG=1 C89_BUILD=1 info all
|
||||
make DEBUG=1 GL_DEBUG=1 C89_BUILD=1
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
name: CI webOS
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '*'
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
release:
|
||||
types: [ published ]
|
||||
repository_dispatch:
|
||||
types: [ run_build ]
|
||||
|
||||
env:
|
||||
PACKAGE_NAME: com.retroarch.webos
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check Out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download ares-cli-rs
|
||||
uses: robinraju/release-downloader@v1.11
|
||||
with:
|
||||
repository: "webosbrew/ares-cli-rs"
|
||||
latest: true
|
||||
fileName: "ares-package_*.deb"
|
||||
out-file-path: "temp"
|
||||
|
||||
- name: Download Manifest Generator
|
||||
uses: robinraju/release-downloader@v1.9
|
||||
with:
|
||||
repository: "webosbrew/dev-toolbox-cli"
|
||||
latest: true
|
||||
fileName: "webosbrew-toolbox-gen-manifest_*.deb"
|
||||
out-file-path: "temp"
|
||||
|
||||
- name: Update packages
|
||||
run: sudo apt-get -yq update
|
||||
|
||||
- name: Install webOS CLI
|
||||
run: sudo apt-get -yq install ./temp/*.deb
|
||||
|
||||
- name: Download webOS NDK
|
||||
uses: robinraju/release-downloader@v1.11
|
||||
with:
|
||||
repository: "openlgtv/buildroot-nc4"
|
||||
latest: true
|
||||
fileName: "arm-webos-linux-gnueabi_sdk-buildroot-x86_64.tar.gz"
|
||||
out-file-path: "/tmp"
|
||||
|
||||
- name: Extract webOS NDK
|
||||
shell: bash
|
||||
working-directory: /tmp
|
||||
run: |
|
||||
tar xzf arm-webos-linux-gnueabi_sdk-buildroot-x86_64.tar.gz
|
||||
./arm-webos-linux-gnueabi_sdk-buildroot/relocate-sdk.sh
|
||||
|
||||
- name: Compile RA
|
||||
shell: bash
|
||||
run: |
|
||||
. /tmp/arm-webos-linux-gnueabi_sdk-buildroot/environment-setup
|
||||
make -f Makefile.webos ipk PACKAGE_NAME=${PACKAGE_NAME} ADD_SDL2_LIB=1 -j$(getconf _NPROCESSORS_ONLN)
|
||||
env:
|
||||
DEBUG: ${{ github.event_name == 'release' && '0' || '1' }}
|
||||
|
||||
- name: Get short SHA
|
||||
id: slug
|
||||
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: com.retroarch.webos_${{ steps.slug.outputs.sha8 }}_arm.ipk
|
||||
path: |
|
||||
webos/*.ipk
|
||||
|
||||
- name: Generate Manifest
|
||||
shell: bash
|
||||
run: |
|
||||
. version.all
|
||||
webosbrew-gen-manifest -o webos/${PACKAGE_NAME}.manifest.json \
|
||||
-p webos/${PACKAGE_NAME}_${RARCH_VERSION}_arm.ipk \
|
||||
-i https://github.com/webosbrew/RetroArch/raw/webos/webos/icon160.png \
|
||||
-l https://github.com/webosbrew/RetroArch
|
||||
|
||||
- name: Release
|
||||
if: github.event_name == 'release'
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
allowUpdates: true
|
||||
omitNameDuringUpdate: true
|
||||
omitBody: true
|
||||
omitPrereleaseDuringUpdate: true
|
||||
artifacts: webos/*.ipk,webos/*.manifest.json
|
|
@ -1,11 +1,7 @@
|
|||
*.o
|
||||
*.obj
|
||||
*.pdb
|
||||
*.exe
|
||||
*.bmpobj
|
||||
*.binobj
|
||||
*.so
|
||||
*.so.*
|
||||
*.dll
|
||||
*.a
|
||||
*.elf
|
||||
|
@ -14,14 +10,13 @@
|
|||
*.swp
|
||||
*.cache
|
||||
*.gcda
|
||||
*.lcbk
|
||||
*.gcno
|
||||
.tmp
|
||||
.tmp.c
|
||||
.tmp.cxx
|
||||
.moc.h
|
||||
.moc.cpp
|
||||
*.log
|
||||
config.log
|
||||
/.project
|
||||
/.externalToolBuilders/
|
||||
/retroarch
|
||||
|
@ -30,6 +25,8 @@
|
|||
/retroarch_debug.exe
|
||||
/config.h
|
||||
/config.mk
|
||||
/tools/retroarch-joyconfig
|
||||
/tools/retroarch-joyconfig.exe
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
|
@ -97,10 +94,6 @@ database
|
|||
overlays
|
||||
playlists
|
||||
states
|
||||
cheats
|
||||
thumbnails
|
||||
docs/html
|
||||
system
|
||||
shaders/shaders_cg
|
||||
shaders/shaders_glsl
|
||||
shaders/shaders_slang
|
||||
|
@ -139,7 +132,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
|||
|
||||
# CLion
|
||||
/cmake-build-debug/
|
||||
.run
|
||||
|
||||
# Android
|
||||
/pkg/android/phoenix/obj/
|
||||
|
@ -148,6 +140,7 @@ wiiu/wut/elf2rpl/elf2rpl
|
|||
/pkg/android/phoenix/bin/
|
||||
/pkg/android/phoenix/gen/
|
||||
/pkg/android/phoenix/local.properties
|
||||
/pkg/android/phoenix/gradle.properties
|
||||
/pkg/android/phoenix/.gradle
|
||||
/pkg/android/phoenix/.externalNativeBuild
|
||||
/pkg/android/phoenix/build
|
||||
|
@ -159,7 +152,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
|||
/media/shaders_cg/
|
||||
/media/libretrodb/
|
||||
|
||||
compile_commands.json
|
||||
pkg/apple/iOS/build/
|
||||
pkg/apple/build/
|
||||
ui/drivers/qt/moc_*
|
||||
|
@ -168,26 +160,23 @@ ui/drivers/moc_*
|
|||
obj-unix/
|
||||
.vagrant/
|
||||
|
||||
# Visual Studio
|
||||
/pkg/msvc/Release Cg/*.exe
|
||||
/pkg/msvc/Release Cg/*.iobj
|
||||
/pkg/msvc/Release Cg/*.ipdb
|
||||
/pkg/msvc/Release Cg/*.pdb
|
||||
/pkg/msvc/Release Cg/*.lpl
|
||||
/pkg/msvc/Release Cg/*.cfg
|
||||
/pkg/msvc/*.db
|
||||
/pkg/msvc/.vs
|
||||
/pkg/msvc/*/.vs
|
||||
*.tlog
|
||||
*.lastbuildstate
|
||||
*.FileListAbsolute.txt
|
||||
*.res
|
||||
/pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.tlog
|
||||
/pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.lastbuildstate
|
||||
/pkg/msvc/msvc-2010/Release Cg/*.log
|
||||
/pkg/msvc/msvc-2010/Release Cg/*.obj
|
||||
/pkg/msvc/msvc-2010/Release Cg/*.res
|
||||
/pkg/msvc/msvc-2010/Release Cg/*.pdb
|
||||
retroarch.cfg
|
||||
Makefile.local
|
||||
pkg/msvc/**/ARM
|
||||
pkg/msvc/**/ARM64
|
||||
pkg/msvc/**/* Cg
|
||||
pkg/msvc/**/* QT
|
||||
pkg/msvc/**/* QT+CG
|
||||
pkg/msvc/**/x64
|
||||
|
||||
# Emscripten artifacts
|
||||
|
||||
|
@ -195,8 +184,6 @@ retroarch.js
|
|||
retroarch.js.mem
|
||||
*.bc
|
||||
*.wasm
|
||||
*.wasm.map
|
||||
obj-emscripten/
|
||||
|
||||
# only ignore .js files in the repo root
|
||||
/*.js
|
||||
|
@ -214,10 +201,6 @@ retroarch_switch.nso
|
|||
*_irx.c
|
||||
|
||||
# Wayland
|
||||
gfx/common/wayland/fractional-scale-v1.c
|
||||
gfx/common/wayland/fractional-scale-v1.h
|
||||
gfx/common/wayland/viewporter.c
|
||||
gfx/common/wayland/viewporter.h
|
||||
gfx/common/wayland/idle-inhibit-unstable-v1.c
|
||||
gfx/common/wayland/idle-inhibit-unstable-v1.h
|
||||
gfx/common/wayland/xdg-shell-unstable-v6.c
|
||||
|
@ -226,22 +209,6 @@ gfx/common/wayland/xdg-decoration-unstable-v1.h
|
|||
gfx/common/wayland/xdg-decoration-unstable-v1.c
|
||||
gfx/common/wayland/xdg-shell.c
|
||||
gfx/common/wayland/xdg-shell.h
|
||||
gfx/common/wayland/pointer-constraints-unstable-v1.c
|
||||
gfx/common/wayland/pointer-constraints-unstable-v1.h
|
||||
gfx/common/wayland/relative-pointer-unstable-v1.c
|
||||
gfx/common/wayland/relative-pointer-unstable-v1.h
|
||||
gfx/common/wayland/viewporter.c
|
||||
gfx/common/wayland/viewporter.h
|
||||
gfx/common/wayland/cursor-shape-v1.h
|
||||
gfx/common/wayland/cursor-shape-v1.c
|
||||
gfx/common/wayland/tablet-unstable-v2.h
|
||||
gfx/common/wayland/tablet-unstable-v2.c
|
||||
gfx/common/wayland/content-type-v1.h
|
||||
gfx/common/wayland/content-type-v1.c
|
||||
gfx/common/wayland/single-pixel-buffer-v1.h
|
||||
gfx/common/wayland/single-pixel-buffer-v1.c
|
||||
gfx/common/wayland/xdg-toplevel-icon-v1.h
|
||||
gfx/common/wayland/xdg-toplevel-icon-v1.c
|
||||
|
||||
# libretro-common samples
|
||||
libretro-common/samples/streams/rzip/rzip
|
||||
|
@ -260,21 +227,3 @@ param.sfo
|
|||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# Clazy
|
||||
*.clazy.yaml
|
||||
|
||||
# PSL1GHT
|
||||
*.SELF
|
||||
EBOOT.BIN
|
||||
pkg/psl1ght/*.pkg
|
||||
modern_alpha_blend_fpo.h
|
||||
modern_alpha_blend_vpo.h
|
||||
modern_opaque_fpo.h
|
||||
modern_opaque_vpo.h
|
||||
gfx/drivers/rsx_shaders/modern_alpha_blend.fpo
|
||||
gfx/drivers/rsx_shaders/modern_alpha_blend.vpo
|
||||
gfx/drivers/rsx_shaders/modern_opaque.fpo
|
||||
gfx/drivers/rsx_shaders/modern_opaque.vpo
|
||||
pkg/psl1ght/pkg/USRDIR/shaders_cg/
|
||||
!pkg/psl1ght/pkg/USRDIR/system/
|
||||
|
|
|
@ -331,7 +331,7 @@ build-retroarch-linux-i686:
|
|||
.build-retroarch-macos-xcode:
|
||||
# Metal/Universal x86_64 arm64 is default
|
||||
tags:
|
||||
- mac-apple-silicon
|
||||
- macosx-packaging
|
||||
stage: build
|
||||
variables:
|
||||
XCARCHIVE_PATH: pkg/apple/build/RetroArchUniversal
|
||||
|
@ -345,11 +345,12 @@ build-retroarch-linux-i686:
|
|||
dependencies: []
|
||||
script:
|
||||
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme RetroArch -archivePath ${XCARCHIVE_PATH} -xcconfig pkg/apple/${XCCONFIG} archive
|
||||
- xcodebuild -exportArchive -archivePath ${XCARCHIVE_PATH}.xcarchive -exportPath . -exportOptionsPlist pkg/apple/OSX/ExportOptions.plist
|
||||
- ditto -c -k --sequesterRsrc --keepParent RetroArch.app ${XCPROJECT_NAME}.zip
|
||||
- pushd ${XCARCHIVE_PATH}.xcarchive/Products/Users/gitlab/Applications/
|
||||
- ditto -c -k --sequesterRsrc --keepParent RetroArch.app RetroArch.zip
|
||||
- popd
|
||||
- mv ${XCARCHIVE_PATH}.xcarchive/Products/Users/gitlab/Applications/RetroArch.zip ${XCPROJECT_NAME}.zip
|
||||
- mkdir .retroarch-repo
|
||||
- "cp -R ./* .retroarch-repo"
|
||||
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
|
||||
- "cp -r ./* .retroarch-repo"
|
||||
- "mv .retroarch-repo/ retroarch-repo/"
|
||||
|
||||
# Mac OS Universal, Metal
|
||||
|
@ -358,8 +359,6 @@ build-retroarch-osx-universal-metal:
|
|||
|
||||
build-retroarch-osx-opengl-x64:
|
||||
extends: .build-retroarch-macos-xcode
|
||||
tags:
|
||||
- macosx-packaging
|
||||
variables:
|
||||
XCARCHIVE_PATH: pkg/apple/build/RetroArchOpenGL
|
||||
XCPROJECT_NAME: RetroArch
|
||||
|
@ -391,25 +390,21 @@ build-retroarch-osx-opengl-x64:
|
|||
build-retroarch-ios-arm64:
|
||||
extends: .build-retroarch-macos-xcode
|
||||
variables:
|
||||
XCPROJECT_NAME: RetroArch_iOS13
|
||||
XCPROJECT_NAME: RetroArch_iOS11_Metal
|
||||
XCCONFIG: GitLabCI.xcconfig
|
||||
XCSCHEME: "RetroArch iOS Release"
|
||||
XCDESTINATION: "generic/platform=iOS"
|
||||
artifacts:
|
||||
paths:
|
||||
- retroarch-repo/
|
||||
expire_in: 10 min
|
||||
script:
|
||||
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -destination ${XCDESTINATION} -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/${XCCONFIG} build
|
||||
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/GitLabCI.xcconfig build
|
||||
- mkdir .retroarch-repo
|
||||
- "cp -r ./* .retroarch-repo"
|
||||
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
|
||||
- "mv .retroarch-repo/ retroarch-repo/"
|
||||
|
||||
build-retroarch-ios9:
|
||||
extends: .build-retroarch-macos-xcode
|
||||
tags:
|
||||
- macosx-packaging
|
||||
variables:
|
||||
XCPROJECT_NAME: RetroArch_iOS9
|
||||
XCCONFIG: GitLabCI.xcconfig
|
||||
|
@ -422,14 +417,12 @@ build-retroarch-ios9:
|
|||
- xcodebuild -project pkg/apple/${XCPROJECT_NAME}.xcodeproj -config Release -scheme "${XCSCHEME}" -xcconfig pkg/apple/iOS/GitLabCI.xcconfig build
|
||||
- mkdir .retroarch-repo
|
||||
- "cp -r ./* .retroarch-repo"
|
||||
- echo '#define GIT_VERSION ' $(git rev-parse --short HEAD) > .retroarch-repo/.git_version.h
|
||||
- "mv .retroarch-repo/ retroarch-repo/"
|
||||
|
||||
build-retroarch-tvos-arm64:
|
||||
extends: build-retroarch-ios-arm64
|
||||
variables:
|
||||
XCSCHEME: "RetroArch tvOS Release"
|
||||
XCDESTINATION: "generic/platform=tvOS"
|
||||
|
||||
build-retroarch-dingux-mips32:
|
||||
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-dingux:latest
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"macFrameworkPath": [
|
||||
"/System/Library/Frameworks",
|
||||
"/Library/Frameworks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw32",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw64",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Switch",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
|
||||
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include",
|
||||
"/opt/devkitpro/libnx/include",
|
||||
"/opt/devkitpro/portlibs/switch/include",
|
||||
"/opt/devkitpro/portlibs/switch/include/freetype2",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"__aarch64__",
|
||||
"__SWITCH__",
|
||||
"HAVE_LIBNX"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.17763.0",
|
||||
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
},
|
||||
{
|
||||
"name": "WiiU",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitPPC/powerpc-eabi/include",
|
||||
"/opt/devkitpro/devkitPPC/lib/gcc/powerpc-eabi/6.3.0/include",
|
||||
"/opt/devkitpro/portlibs/ppc/include",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"WIIU",
|
||||
"WIIU_HID"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.17763.0",
|
||||
"compilerPath": "/opt/devkitpro/devkitPPC/bin/powerpc-eabi-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
},
|
||||
{
|
||||
"name": "ps2sdk-ee",
|
||||
"includePath": [
|
||||
"${env:PS2DEV}/ps2sdk/common/include",
|
||||
"${env:PS2DEV}/ps2sdk/ee/include",
|
||||
"${env:PS2DEV}/gsKit/include",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"PS2",
|
||||
"_EE"
|
||||
],
|
||||
"compilerPath": "${env:PS2DEV}/ee/bin/mips64r5900el-ps2-elf-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/retroarch.exe",
|
||||
"args": ["-v"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) Attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "${workspaceFolder}/retroarch.exe",
|
||||
"processId": "${command:pickProcess}",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PSP-GDB Debugger",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/retroarchpsp.elf",
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "symbol-file ${workspaceFolder}/retroarchpsp.elf",
|
||||
"description": "read symbols for elf file",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Enable all-exceptions",
|
||||
"text": "-exec \"catch throw\"",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"showDisplayString": true,
|
||||
"targetArchitecture": "mips",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/local/pspdev/bin/psp-gdb",
|
||||
"miDebuggerServerAddress": "127.0.0.1:10001",
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
/*"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"terminal.integrated.env.windows": {
|
||||
"PATH": "/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:$PATH",
|
||||
"MSYSTEM": "MINGW64",
|
||||
},*/
|
||||
"terminal.integrated.cursorBlinking": true,
|
||||
"editor.tabSize": 3,
|
||||
"editor.detectIndentation": false,
|
||||
"editor.renderWhitespace": "all",
|
||||
"editor.insertSpaces": true,
|
||||
"editor.formatOnSave": false,
|
||||
"editor.ruler": [80],
|
||||
"files.associations": {
|
||||
"*.h": "c",
|
||||
"*.in": "c",
|
||||
"*.rh": "c",
|
||||
"array": "c",
|
||||
"iosfwd": "c",
|
||||
"xlocbuf": "c",
|
||||
"xmemory0": "c",
|
||||
"ios": "c",
|
||||
"list": "c",
|
||||
"unordered_map": "c",
|
||||
"unordered_set": "c",
|
||||
"sstream": "cpp",
|
||||
"hash_map": "c",
|
||||
"hash_set": "c",
|
||||
"initializer_list": "c",
|
||||
"string_view": "c",
|
||||
"utility": "c",
|
||||
"thread": "c",
|
||||
"xlocale": "c",
|
||||
"deque": "c",
|
||||
"vector": "c",
|
||||
"xhash": "c",
|
||||
"xiosbase": "c",
|
||||
"xstring": "c",
|
||||
"xtree": "c",
|
||||
"xutility": "c"
|
||||
},
|
||||
"C_Cpp.dimInactiveRegions": false,
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "linux clean build",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "make clean && ./configure && make -j12"
|
||||
},
|
||||
{
|
||||
"label": "linux clean",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "make clean"
|
||||
},
|
||||
{
|
||||
"label": "linux build with debug symbols",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "DEBUG=1 make -j12"
|
||||
},
|
||||
{
|
||||
"label": "linux build",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "make -j12"
|
||||
},
|
||||
{
|
||||
"label": "linux build and run",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "make -j12 && ./retroarch -v"
|
||||
},
|
||||
{
|
||||
"label": "linux build and run with debug symbols",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "DEBUG=1 make -j12 && ./retroarch -v"
|
||||
},
|
||||
{
|
||||
"label": "msys2-mingw64 build",
|
||||
"type": "shell",
|
||||
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
|
||||
"command": "./configure; make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "msys2-mingw64 build with debug symbols",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "./configure; DEBUG=1 make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "msys2-mingw64 rebuild",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "msys2-mingw64 clean",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make clean",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "msys2-mingw64 run",
|
||||
"type": "shell",
|
||||
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true },
|
||||
|
||||
"command": "./retroarch -v",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -231,7 +231,6 @@ Jean-Sébastien Guay (Skylark13)
|
|||
Jeff (jeffbdavenport)
|
||||
Jeff Sousa (LordeIlluminati)
|
||||
jess (winneon)
|
||||
Jesse Talavera-Greenberg (JesseTG)
|
||||
Joan Coll Cerdán (johanbcn)
|
||||
Job Adrian Salinas Gonzalez (efylan)
|
||||
Joe Osborn (JoeOsborn)
|
||||
|
@ -315,12 +314,12 @@ Mike Swanson (chungy)
|
|||
mikeOSX
|
||||
minucce
|
||||
misson20000
|
||||
esoptron
|
||||
Monroe88
|
||||
Morgane (MorganeAD)
|
||||
mprobinson
|
||||
MrHuu
|
||||
MrJs (mrjschulte)
|
||||
mudlord
|
||||
Muhamed Hobi (mmhobi7)
|
||||
muzuiget
|
||||
N/A (inactive123)
|
||||
|
@ -333,6 +332,7 @@ nayslayer
|
|||
negativeExponent
|
||||
Neil Barkhina (nbarkhina)
|
||||
neil4
|
||||
Nephilim (Nephil1m)
|
||||
netux79
|
||||
nfnty
|
||||
nfp0
|
||||
|
@ -481,7 +481,6 @@ vaguerant
|
|||
Val Packett (valpackett)
|
||||
Valerio Proietti (kamicane)
|
||||
vgmoose
|
||||
Viachaslau Khalikin (viachaslavic)
|
||||
Vicki Pfau (endrift)
|
||||
Vicky C Lau (vickychenglau)
|
||||
vin (suseme)
|
||||
|
|
1042
CHANGES.md
1042
CHANGES.md
File diff suppressed because it is too large
Load Diff
|
@ -44,7 +44,7 @@ For POD-types, try to order structs as follows (first to last):
|
|||
bool fuzzy_archive_match;
|
||||
bool autofix_paths;
|
||||
char path[PATH_MAX_LENGTH];
|
||||
char base_content_directory[DIR_MAX_LENGTH];
|
||||
char base_content_directory[PATH_MAX_LENGTH];
|
||||
} playlist_config_t;
|
||||
|
||||
size_t has the biggest alignment here, so 'struct playlist_config_t'
|
||||
|
|
|
@ -14,39 +14,25 @@ If there are any issues, we are willing to have discussions about it.
|
|||
|
||||
## Submitting Bug Reports
|
||||
|
||||
Bug reports for _RetroArch_ may fall into a few categories:
|
||||
Bug reports in _RetroArch_ may fall into one of two categories:
|
||||
|
||||
* _RetroArch_ itself, the user interface and API around all of the various cores.
|
||||
* Individual _Core_, that interacts with _RetroArch_.
|
||||
* Supplementary data provided within _RetroArch_, such as controller autoconfigs, databases,
|
||||
thumbnails...
|
||||
* The [documentation set](https://docs.libretro.com/)
|
||||
* Individual _Core_, of which interact with _RetroArch_.
|
||||
|
||||
When submitting a bug report, ensure that the report is submitted to the correct repository.
|
||||
* For _RetroArch_ itself, submit an issue to the [RetroArch](https://github.com/libretro/RetroArch)
|
||||
repository. Please read and fill the issue template.
|
||||
* For other cores, please use the search function within the [libretro Organization](https://github.com/libretro)
|
||||
on GitHub. Issues that are specific to a core and not _RetroArch_ are likely to be closed
|
||||
very quickly. If an issue is suspected with _RetroArch_, please make sure to test with
|
||||
multiple cores to be sure that is is not isolated.
|
||||
* For database content, submit an issue to
|
||||
[libretro-database repo](https://github.com/libretro/libretro-database) or ask in the
|
||||
_database_ channel on Discord.
|
||||
* For controller autoconfigs, submit an issue to
|
||||
[retroarch-joypad-autoconfig repo](https://github.com/libretro/retroarch-joypad-autoconfig)
|
||||
* For actual thumbnail images, submit an issue to
|
||||
[libretro-thumbnails](https://github.com/libretro-thumbnails/libretro-thumbnails) repo
|
||||
or ask in the _database_ channel on Discord.
|
||||
* For documentation, submit an issue to [libretro-docs](https://github.com/libretro/libretro-docs)
|
||||
repo or ask in the _documentation_ channel.
|
||||
* For translations, please see [here](https://docs.libretro.com/development/retroarch/new-translations-crowdin/).
|
||||
For _RetroArch_ itself, it is done by reporting a bug within the
|
||||
[RetroArch](https://github.com/libretro/RetroArch) repository. For other cores, please use
|
||||
the search function within the [libretro Organization](https://github.com/libretro) on
|
||||
GitHub. Issues that are specific to a core and not _RetroArch_ are likely to be closed very
|
||||
quickly. If an issue is suspected with _RetroArch_, please make sure to test with multiple
|
||||
cores to be sure that is is not isolated.
|
||||
|
||||
If the issue occurs during runtime, please paste the verbose log output:
|
||||
|
||||
* If using the _Pheonix_ interface, the log will be in _File_ -> _Show Log_.
|
||||
* If using the main interface, enable verbose logging with _Settings_ -> _Logging_ ->
|
||||
_Logging Verbosity_. Ensure both _Log to File_ and _Timestamp log Files_ is enabled.
|
||||
Set frontend log level to _0 (Debug)_.
|
||||
* Or run _RetroArch_ with the verbose (`-v`) flag and get the log from the console.
|
||||
* Otherwise, run _RetroArch_ with the verbose (`-v`) flag.
|
||||
|
||||
If the error happens during compilation and/or building, paste the output of `./configure`
|
||||
and `make` accordingly. If using an IDE, please paste any of the errors and log output.
|
||||
|
|
469
Doxyfile
469
Doxyfile
|
@ -1,4 +1,4 @@
|
|||
# Doxyfile 1.9.1
|
||||
# Doxyfile 1.8.14
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
|
@ -17,10 +17,10 @@
|
|||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# This tag specifies the encoding used for all characters in the configuration
|
||||
# file that follow. The default is UTF-8 which is also the encoding used for all
|
||||
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||
# iconv built into libc) for the transcoding. See
|
||||
# This tag specifies the encoding used for all characters in the config file
|
||||
# that follow. The default is UTF-8 which is also the encoding used for all text
|
||||
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
|
||||
# built into libc) for the transcoding. See
|
||||
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
|
@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
|
|||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = RetroArch
|
||||
PROJECT_NAME = "RetroArch"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
|
@ -58,7 +58,7 @@ PROJECT_LOGO =
|
|||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = docs
|
||||
OUTPUT_DIRECTORY =
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
|
@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO
|
|||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all generated output in the proper direction.
|
||||
# Possible values are: None, LTR, RTL and Context.
|
||||
# The default value is: None.
|
||||
|
||||
OUTPUT_TEXT_DIRECTION = None
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
|
||||
# descriptions after the members that are listed in the file and class
|
||||
# documentation (similar to Javadoc). Set to NO to disable this.
|
||||
|
@ -195,17 +187,7 @@ SHORT_NAMES = YES
|
|||
# description.)
|
||||
# The default value is: NO.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
|
||||
# such as
|
||||
# /***************
|
||||
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
|
||||
# Javadoc-style will behave just like regular comments and it will not be
|
||||
# interpreted by doxygen.
|
||||
# The default value is: NO.
|
||||
|
||||
JAVADOC_BANNER = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
|
||||
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
||||
# line (until the first dot) of a Qt-style comment as the brief description. If
|
||||
|
@ -227,14 +209,6 @@ QT_AUTOBRIEF = NO
|
|||
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
|
||||
# By default Python docstrings are displayed as preformatted text and doxygen's
|
||||
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
|
||||
# doxygen's special commands can be used and the contents of the docstring
|
||||
# documentation blocks is shown as doxygen documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
PYTHON_DOCSTRING = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||
# documentation from any documented member that it re-implements.
|
||||
# The default value is: YES.
|
||||
|
@ -264,12 +238,14 @@ TAB_SIZE = 4
|
|||
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
||||
# newlines (in the resulting output). You can put ^^ in the value part of an
|
||||
# alias to insert a newline as if a physical newline was in the original file.
|
||||
# When you need a literal { or } or , in the value part of an alias you have to
|
||||
# escape them by means of a backslash (\), this can lead to conflicts with the
|
||||
# commands \{ and \} for these it is advised to use the version @{ and @} or use
|
||||
# a double escape (\\{ and \\})
|
||||
|
||||
ALIASES = "setby{1}=@par Set by^^The \1."
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
|
@ -277,7 +253,7 @@ ALIASES = "setby{1}=@par Set by^^The \1."
|
|||
# members will be omitted, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||
# Python sources only. Doxygen will then generate output that is more tailored
|
||||
|
@ -299,40 +275,28 @@ OPTIMIZE_FOR_FORTRAN = NO
|
|||
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
|
||||
# sources only. Doxygen will then generate output that is more tailored for that
|
||||
# language. For instance, namespaces will be presented as modules, types will be
|
||||
# separated into more groups, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_SLICE = NO
|
||||
|
||||
# Doxygen selects the parser to use depending on the extension of the files it
|
||||
# parses. With this tag you can assign which parser to use for a given
|
||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
|
||||
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||
# default for Fortran type files). For instance to make doxygen treat .inc files
|
||||
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||
# use: inc=Fortran f=C.
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
|
||||
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
|
||||
# Fortran. In the later case the parser tries to guess whether the code is fixed
|
||||
# or free formatted code, this is the default for Fortran type files), VHDL. For
|
||||
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
|
||||
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
|
||||
#
|
||||
# Note: For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||
# the files are not read by doxygen. When specifying no_extension you should add
|
||||
# * to the FILE_PATTERNS.
|
||||
#
|
||||
# Note see also the list of default file extension mappings.
|
||||
# the files are not read by doxygen.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
|
||||
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
||||
# according to the Markdown format, which allows for more readable
|
||||
# documentation. See https://daringfireball.net/projects/markdown/ for details.
|
||||
# documentation. See http://daringfireball.net/projects/markdown/ for details.
|
||||
# The output of markdown processing is further processed by doxygen, so you can
|
||||
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
||||
# case of backward compatibilities issues.
|
||||
|
@ -344,7 +308,7 @@ MARKDOWN_SUPPORT = YES
|
|||
# to that level are automatically included in the table of contents, even if
|
||||
# they do not have an id attribute.
|
||||
# Note: This feature currently applies only to Markdown headings.
|
||||
# Minimum value: 0, maximum value: 99, default value: 5.
|
||||
# Minimum value: 0, maximum value: 99, default value: 0.
|
||||
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||
|
||||
TOC_INCLUDE_HEADINGS = 0
|
||||
|
@ -434,7 +398,7 @@ INLINE_GROUPED_CLASSES = NO
|
|||
# Man pages) or section (for LaTeX and RTF).
|
||||
# The default value is: NO.
|
||||
|
||||
INLINE_SIMPLE_STRUCTS = YES
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
|
||||
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
|
||||
# enum is documented as struct, union, or enum with the name of the typedef. So
|
||||
|
@ -460,19 +424,6 @@ TYPEDEF_HIDES_STRUCT = NO
|
|||
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
|
||||
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
|
||||
# during processing. When set to 0 doxygen will based this on the number of
|
||||
# cores available in the system. You can set it explicitly to a value larger
|
||||
# than 0 to get more control over the balance between CPU load and processing
|
||||
# speed. At this moment only the input processing can be done using multiple
|
||||
# threads. Since this is still an experimental feature the default is set to 1,
|
||||
# which efficively disables parallel processing. Please report any issues you
|
||||
# encounter. Generating dot graphs in parallel is controlled by the
|
||||
# DOT_NUM_THREADS setting.
|
||||
# Minimum value: 0, maximum value: 32, default value: 1.
|
||||
|
||||
NUM_PROC_THREADS = 16
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -491,13 +442,7 @@ EXTRACT_ALL = YES
|
|||
# be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PRIVATE = NO
|
||||
|
||||
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
|
||||
# methods of a class will be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PRIV_VIRTUAL = NO
|
||||
EXTRACT_PRIVATE = YES
|
||||
|
||||
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
||||
# scope will be included in the documentation.
|
||||
|
@ -536,13 +481,6 @@ EXTRACT_LOCAL_METHODS = YES
|
|||
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
# If this flag is set to YES, the name of an unnamed parameter in a declaration
|
||||
# will be determined by the corresponding definition. By default unnamed
|
||||
# parameters remain unnamed in the output.
|
||||
# The default value is: YES.
|
||||
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
|
||||
# undocumented members inside documented classes or files. If set to NO these
|
||||
# members will be included in the various overviews, but no documentation
|
||||
|
@ -560,8 +498,8 @@ HIDE_UNDOC_MEMBERS = NO
|
|||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
||||
# declarations. If set to NO, these declarations will be included in the
|
||||
# documentation.
|
||||
# (class|struct|union) declarations. If set to NO, these declarations will be
|
||||
# included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
|
@ -580,18 +518,11 @@ HIDE_IN_BODY_DOCS = NO
|
|||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
|
||||
# able to match the capabilities of the underlying filesystem. In case the
|
||||
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||
# whose names only differ in casing), the option must be set to YES to properly
|
||||
# deal with such files in case they appear in the input. For filesystems that
|
||||
# are not case sensitive the option should be be set to NO to properly deal with
|
||||
# output files written for symbols that only differ in casing, such as for two
|
||||
# classes, one named CLASS and the other named Class, and to also support
|
||||
# references to files without having to specify the exact matching casing. On
|
||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||
# YES.
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# and Mac users are advised to set this option to NO.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
@ -601,7 +532,7 @@ CASE_SENSE_NAMES = YES
|
|||
# scope will be hidden.
|
||||
# The default value is: NO.
|
||||
|
||||
HIDE_SCOPE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
|
||||
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
|
||||
# append additional text to a page's title, such as Class Reference. If set to
|
||||
|
@ -640,7 +571,7 @@ INLINE_INFO = YES
|
|||
# name. If set to NO, the members will appear in declaration order.
|
||||
# The default value is: YES.
|
||||
|
||||
SORT_MEMBER_DOCS = NO
|
||||
SORT_MEMBER_DOCS = YES
|
||||
|
||||
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
|
||||
# descriptions of file, namespace and class members alphabetically by member
|
||||
|
@ -823,17 +754,13 @@ WARN_IF_DOC_ERROR = YES
|
|||
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
||||
# are documented, but have no documentation for their parameters or return
|
||||
# value. If set to NO, doxygen will only warn about wrong or incomplete
|
||||
# parameter documentation, but not about the absence of documentation. If
|
||||
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
|
||||
# parameter documentation, but not about the absence of documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_NO_PARAMDOC = NO
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||
# at the end of the doxygen process doxygen will return with a non-zero status.
|
||||
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
|
||||
# a warning is encountered.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
||||
|
@ -864,13 +791,13 @@ WARN_LOGFILE =
|
|||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = libretro-common
|
||||
INPUT =
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||
# documentation (see:
|
||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
|
||||
# possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
|
@ -883,17 +810,56 @@ INPUT_ENCODING = UTF-8
|
|||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# read by doxygen.
|
||||
#
|
||||
# Note the list of default checked file patterns might differ from the list of
|
||||
# default file extension mappings.
|
||||
#
|
||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
||||
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
|
||||
# *.ucf, *.qsf and *.ice.
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
||||
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
|
||||
|
||||
FILE_PATTERNS = *.h
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.idl \
|
||||
*.ddl \
|
||||
*.odl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.cs \
|
||||
*.d \
|
||||
*.php \
|
||||
*.php4 \
|
||||
*.php5 \
|
||||
*.phtml \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.markdown \
|
||||
*.md \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.pyw \
|
||||
*.f90 \
|
||||
*.f95 \
|
||||
*.f03 \
|
||||
*.f08 \
|
||||
*.f \
|
||||
*.for \
|
||||
*.tcl \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.ucf \
|
||||
*.qsf
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
|
@ -924,11 +890,7 @@ EXCLUDE_SYMLINKS = NO
|
|||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS = */libretro-common/rthreads/* \
|
||||
*/libretro-common/formats/* \
|
||||
*/libretro-common/crt/* \
|
||||
*/libretro-common/samples/* \
|
||||
*/libretro-common/include/glsym/*
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
|
@ -939,9 +901,7 @@ EXCLUDE_PATTERNS = */libretro-common/rthreads/* \
|
|||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories use the pattern */test/*
|
||||
|
||||
EXCLUDE_SYMBOLS = bool \
|
||||
void \
|
||||
const
|
||||
EXCLUDE_SYMBOLS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||
# that contain example code fragments that are included (see the \include
|
||||
|
@ -1052,7 +1012,7 @@ INLINE_SOURCES = NO
|
|||
STRIP_CODE_COMMENTS = YES
|
||||
|
||||
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
||||
# entity all documented functions referencing it will be listed.
|
||||
# function all documented functions referencing it will be listed.
|
||||
# The default value is: NO.
|
||||
|
||||
REFERENCED_BY_RELATION = NO
|
||||
|
@ -1089,7 +1049,7 @@ SOURCE_TOOLTIPS = YES
|
|||
#
|
||||
# To use it do the following:
|
||||
# - Install the latest version of global
|
||||
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
|
||||
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
|
||||
# - Make sure the INPUT points to the root of the source tree
|
||||
# - Run doxygen as normal
|
||||
#
|
||||
|
@ -1111,44 +1071,6 @@ USE_HTAGS = NO
|
|||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
|
||||
# clang parser (see:
|
||||
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
|
||||
# performance. This can be particularly helpful with template rich C++ code for
|
||||
# which doxygen's built-in parser lacks the necessary type information.
|
||||
# Note: The availability of this option depends on whether or not doxygen was
|
||||
# generated with the -Duse_libclang=ON option for CMake.
|
||||
# The default value is: NO.
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
|
||||
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
|
||||
# YES then doxygen will add the directory of each input to the include path.
|
||||
# The default value is: YES.
|
||||
|
||||
CLANG_ADD_INC_PATHS = YES
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||
# line options that you would normally use when invoking the compiler. Note that
|
||||
# the include paths will already be set by doxygen for the files and directories
|
||||
# specified with INPUT and INCLUDE_PATH.
|
||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||
|
||||
CLANG_OPTIONS =
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the clang parser with the
|
||||
# path to the directory containing a file called compile_commands.json. This
|
||||
# file is the compilation database (see:
|
||||
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
|
||||
# options used when the source files were built. This is equivalent to
|
||||
# specifying the -p option to a clang tool, such as clang-check. These options
|
||||
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
|
||||
# will be added as well.
|
||||
# Note: The availability of this option depends on whether or not doxygen was
|
||||
# generated with the -Duse_libclang=ON option for CMake.
|
||||
|
||||
CLANG_DATABASE_PATH =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1160,14 +1082,20 @@ CLANG_DATABASE_PATH =
|
|||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
# while generating the index headers.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
IGNORE_PREFIX = retro_ \
|
||||
RETRO_
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
|
@ -1299,9 +1227,9 @@ HTML_TIMESTAMP = NO
|
|||
|
||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||
# documentation will contain a main index with vertical navigation menus that
|
||||
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||
# are dynamically created via Javascript. If disabled, the navigation index will
|
||||
# consists of multiple levels of tabs that are statically embedded in every HTML
|
||||
# page. Disable this option to support browsers that do not have JavaScript,
|
||||
# page. Disable this option to support browsers that do not have Javascript,
|
||||
# like the Qt help browser.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
@ -1331,14 +1259,13 @@ HTML_INDEX_NUM_ENTRIES = 100
|
|||
|
||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||
# environment (see:
|
||||
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
|
||||
# create a documentation set, doxygen will generate a Makefile in the HTML
|
||||
# output directory. Running make will produce the docset in that directory and
|
||||
# running make install will install the docset in
|
||||
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
|
||||
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||
# that directory and running make install will install the docset in
|
||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||
# genXcode/_index.html for more information.
|
||||
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
|
||||
# for more information.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
|
@ -1377,8 +1304,8 @@ DOCSET_PUBLISHER_NAME = Publisher
|
|||
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||
# (see:
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
|
||||
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||
# Windows.
|
||||
#
|
||||
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||
|
@ -1408,7 +1335,7 @@ CHM_FILE =
|
|||
HHC_LOCATION =
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the main .chm file (NO).
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
|
@ -1453,8 +1380,7 @@ QCH_FILE =
|
|||
|
||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||
# Project output. For more information please see Qt Help Project / Namespace
|
||||
# (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
|
||||
# The default value is: org.doxygen.Project.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
|
@ -1462,8 +1388,7 @@ QHP_NAMESPACE = org.doxygen.Project
|
|||
|
||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||
# Folders (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
|
||||
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
|
||||
# The default value is: doc.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
|
@ -1471,30 +1396,28 @@ QHP_VIRTUAL_FOLDER = doc
|
|||
|
||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||
# filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_NAME =
|
||||
|
||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
|
||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
|
||||
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
|
||||
# The QHG_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
|
||||
# run qhelpgenerator on the generated .qhp file.
|
||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||
# generated .qhp file.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHG_LOCATION =
|
||||
|
@ -1545,7 +1468,7 @@ DISABLE_INDEX = NO
|
|||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
GENERATE_TREEVIEW = YES
|
||||
GENERATE_TREEVIEW = NO
|
||||
|
||||
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
|
||||
# doxygen will group on one line in the generated HTML documentation.
|
||||
|
@ -1571,17 +1494,6 @@ TREEVIEW_WIDTH = 250
|
|||
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
|
||||
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||
# Possible values are: png (the default) and svg (looks nicer but requires the
|
||||
# pdf2svg or inkscape tool).
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FORMULA_FORMAT = png
|
||||
|
||||
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||
# the HTML documentation. When you change the font size after a successful
|
||||
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||
|
@ -1602,14 +1514,8 @@ FORMULA_FONTSIZE = 10
|
|||
|
||||
FORMULA_TRANSPARENT = YES
|
||||
|
||||
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||
# the section "Including formulas" for details.
|
||||
|
||||
FORMULA_MACROFILE =
|
||||
|
||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||
# https://www.mathjax.org) which uses client side JavaScript for the rendering
|
||||
# https://www.mathjax.org) which uses client side Javascript for the rendering
|
||||
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
||||
# installed or if you want to formulas look prettier in the HTML output. When
|
||||
# enabled you may also need to install MathJax separately and configure the path
|
||||
|
@ -1621,7 +1527,7 @@ USE_MATHJAX = NO
|
|||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
|
||||
# http://docs.mathjax.org/en/latest/output.html) for more details.
|
||||
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||
# compatibility), NativeMML (i.e. MathML) and SVG.
|
||||
# The default value is: HTML-CSS.
|
||||
|
@ -1637,7 +1543,7 @@ MATHJAX_FORMAT = HTML-CSS
|
|||
# Content Delivery Network so you can quickly see the result without installing
|
||||
# MathJax. However, it is strongly recommended to install a local copy of
|
||||
# MathJax from https://www.mathjax.org before deployment.
|
||||
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
|
||||
|
@ -1651,8 +1557,7 @@ MATHJAX_EXTENSIONS =
|
|||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
# (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
|
||||
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
|
||||
# example see the documentation.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
|
@ -1680,7 +1585,7 @@ MATHJAX_CODEFILE =
|
|||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a web server instead of a web client using JavaScript. There
|
||||
# implemented using a web server instead of a web client using Javascript. There
|
||||
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||
|
@ -1699,8 +1604,7 @@ SERVER_BASED_SEARCH = NO
|
|||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see:
|
||||
# https://xapian.org/).
|
||||
# Xapian (see: https://xapian.org/).
|
||||
#
|
||||
# See the section "External Indexing and Searching" for details.
|
||||
# The default value is: NO.
|
||||
|
@ -1713,9 +1617,8 @@ EXTERNAL_SEARCH = NO
|
|||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see:
|
||||
# https://xapian.org/). See the section "External Indexing and Searching" for
|
||||
# details.
|
||||
# Xapian (see: https://xapian.org/). See the section "External Indexing and
|
||||
# Searching" for details.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
SEARCHENGINE_URL =
|
||||
|
@ -1766,35 +1669,21 @@ LATEX_OUTPUT = latex
|
|||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||
# invoked.
|
||||
#
|
||||
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
|
||||
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
|
||||
# chosen this is overwritten by pdflatex. For specific output languages the
|
||||
# default can have been set differently, this depends on the implementation of
|
||||
# the output language.
|
||||
# Note that when enabling USE_PDFLATEX this option is only used for generating
|
||||
# bitmaps for formulas in the HTML output, but not in the Makefile that is
|
||||
# written to the output directory.
|
||||
# The default file is: latex.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_CMD_NAME = latex
|
||||
|
||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
||||
# index for LaTeX.
|
||||
# Note: This tag is used in the Makefile / make.bat.
|
||||
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
|
||||
# (.tex).
|
||||
# The default file is: makeindex.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
|
||||
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
|
||||
# generate index for LaTeX. In case there is no backslash (\) as first character
|
||||
# it will be automatically added in the LaTeX code.
|
||||
# Note: This tag is used in the generated output file (.tex).
|
||||
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
|
||||
# The default value is: makeindex.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_MAKEINDEX_CMD = makeindex
|
||||
|
||||
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
|
||||
# documents. This may be useful for small projects and may help to save some
|
||||
# trees in general.
|
||||
|
@ -1879,11 +1768,9 @@ LATEX_EXTRA_FILES =
|
|||
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
|
||||
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
|
||||
# files. Set this option to YES, to get a higher quality PDF documentation.
|
||||
#
|
||||
# See also section LATEX_CMD_NAME for selecting the engine.
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
|
||||
# higher quality PDF documentation.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
|
@ -1931,14 +1818,6 @@ LATEX_BIB_STYLE = plain
|
|||
|
||||
LATEX_TIMESTAMP = NO
|
||||
|
||||
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# path from which the emoji images will be read. If a relative path is entered,
|
||||
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||
# LATEX_OUTPUT directory will be used.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_EMOJI_DIRECTORY =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1978,9 +1857,9 @@ COMPACT_RTF = NO
|
|||
|
||||
RTF_HYPERLINKS = NO
|
||||
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||
# configuration file, i.e. a series of assignments. You only have to provide
|
||||
# replacements, missing definitions are set to their default value.
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
|
||||
# file, i.e. a series of assignments. You only have to provide replacements,
|
||||
# missing definitions are set to their default value.
|
||||
#
|
||||
# See also section "Doxygen usage" for information on how to generate the
|
||||
# default style sheet that doxygen normally uses.
|
||||
|
@ -1989,8 +1868,8 @@ RTF_HYPERLINKS = NO
|
|||
RTF_STYLESHEET_FILE =
|
||||
|
||||
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||
# similar to doxygen's configuration file. A template extensions file can be
|
||||
# generated using doxygen -e rtf extensionFile.
|
||||
# similar to doxygen's config file. A template extensions file can be generated
|
||||
# using doxygen -e rtf extensionFile.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
@ -2076,13 +1955,6 @@ XML_OUTPUT = xml
|
|||
|
||||
XML_PROGRAMLISTING = YES
|
||||
|
||||
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
|
||||
# namespace members in file scope as well, matching the HTML output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_NS_MEMB_FILE_SCOPE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the DOCBOOK output
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -2122,10 +1994,6 @@ DOCBOOK_PROGRAMLISTING = NO
|
|||
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to Sqlite3 output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -2221,7 +2089,7 @@ INCLUDE_FILE_PATTERNS =
|
|||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = DOXYGEN
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
|
@ -2288,6 +2156,12 @@ EXTERNAL_GROUPS = YES
|
|||
|
||||
EXTERNAL_PAGES = YES
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
# The default file (with absolute path) is: /usr/bin/perl.
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -2299,7 +2173,16 @@ EXTERNAL_PAGES = YES
|
|||
# powerful graphs.
|
||||
# The default value is: YES.
|
||||
|
||||
CLASS_DIAGRAMS = NO
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
|
@ -2319,9 +2202,9 @@ HIDE_UNDOC_RELATIONS = YES
|
|||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||
# Bell Labs. The other options in this section have no effect if this option is
|
||||
# set to NO
|
||||
# The default value is: YES.
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = NO
|
||||
HAVE_DOT = YES
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
|
@ -2398,31 +2281,9 @@ UML_LOOK = NO
|
|||
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||
# 10.
|
||||
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
||||
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
|
||||
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
|
||||
# tag is set to YES, doxygen will add type and arguments for attributes and
|
||||
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
|
||||
# will not generate fields with class member information in the UML graphs. The
|
||||
# class diagrams will look similar to the default class diagrams but using UML
|
||||
# notation for the relationships.
|
||||
# Possible values are: NO, YES and NONE.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
DOT_UML_DETAILS = NO
|
||||
|
||||
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
|
||||
# to display on a single line. If the actual line length exceeds this threshold
|
||||
# significantly it will wrapped across multiple lines. Some heuristics are apply
|
||||
# to avoid ugly line breaks.
|
||||
# Minimum value: 0, maximum value: 1000, default value: 17.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
||||
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||
# collaboration graphs will show the relations between templates and their
|
||||
|
@ -2497,9 +2358,7 @@ DIRECTORY_GRAPH = YES
|
|||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||
# requirement).
|
||||
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
|
||||
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
|
||||
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
|
||||
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
|
||||
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
||||
# png:gdiplus:gdiplus.
|
||||
# The default value is: png.
|
||||
|
@ -2615,11 +2474,9 @@ DOT_MULTI_TARGETS = YES
|
|||
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
|
||||
# files that are used to generate the various graphs.
|
||||
#
|
||||
# Note: This setting is not only used for dot files but also for msc and
|
||||
# plantuml temporary files.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
|
64
Makefile
64
Makefile
|
@ -26,9 +26,6 @@ DEF_FLAGS := -I.
|
|||
ASFLAGS :=
|
||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
|
||||
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
||||
DEFINES += -DASSETS_DIR='"$(DESTDIR)$(ASSETS_DIR)"'
|
||||
DEFINES += -DFILTERS_DIR='"$(DESTDIR)$(FILTERS_DIR)"'
|
||||
DEFINES += -DCORE_INFO_DIR='"$(DESTDIR)$(CORE_INFO_DIR)"'
|
||||
|
||||
OBJDIR_BASE := obj-unix
|
||||
|
||||
|
@ -45,9 +42,10 @@ else
|
|||
OBJDIR := $(OBJDIR_BASE)/release
|
||||
CFLAGS ?= -O3
|
||||
CXXFLAGS ?= -O3
|
||||
DEF_FLAGS += -ffast-math
|
||||
endif
|
||||
|
||||
DEF_FLAGS += -Wall -Wsign-compare
|
||||
DEF_FLAGS += -Wall
|
||||
|
||||
ifneq ($(findstring BSD,$(OS)),)
|
||||
DEF_FLAGS += -DBSD
|
||||
|
@ -66,7 +64,7 @@ ifneq ($(findstring FPGA,$(OS)),)
|
|||
endif
|
||||
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
LDFLAGS += -static-libgcc -lwinmm -limm32
|
||||
LDFLAGS += -static-libgcc -lwinmm
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
@ -112,7 +110,7 @@ endif
|
|||
|
||||
ifneq ($(CXX_BUILD), 1)
|
||||
ifneq ($(C89_BUILD),)
|
||||
CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long -Werror=declaration-after-statement -Wno-variadic-macros
|
||||
CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long -Werror=declaration-after-statement
|
||||
else ifeq ($(HAVE_C99), 1)
|
||||
CFLAGS += $(C99_CFLAGS)
|
||||
endif
|
||||
|
@ -172,33 +170,6 @@ endif
|
|||
|
||||
all: $(TARGET) config.mk
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CPPFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBRARY_DIRS: $(LIBRARY_DIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
MD: $(MD)
|
||||
MOC: $(MOC)
|
||||
MOC_TMP: $(MOC_TMP)
|
||||
OBJCFLAGS: $(OBJCFLAGS)
|
||||
QT_VERSION: $(QT_VERSION)
|
||||
RARCH_OBJ: $(RARCH_OBJ)
|
||||
WINDRES: $(WINDRES)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
$(MOC_SRC):
|
||||
@$(if $(Q), $(shell echo echo MOC $<),)
|
||||
$(eval MOC_TMP := $(patsubst %.h,%_moc.cpp,$@))
|
||||
|
@ -252,7 +223,7 @@ $(OBJDIR)/%.o: %.S config.h config.mk $(HEADERS)
|
|||
$(OBJDIR)/%.o: %.rc $(HEADERS)
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo WINDRES $<),)
|
||||
$(Q)$(WINDRES) $(DEFINES) -o $@ $<
|
||||
$(Q)$(WINDRES) -o $@ $<
|
||||
|
||||
install: $(TARGET)
|
||||
mkdir -p $(DESTDIR)$(BIN_DIR) 2>/dev/null || /bin/true
|
||||
|
@ -265,21 +236,21 @@ install: $(TARGET)
|
|||
cp $(TARGET) $(DESTDIR)$(BIN_DIR)
|
||||
cp tools/cg2glsl.py $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
cp retroarch.cfg $(DESTDIR)$(GLOBAL_CONFIG_DIR)
|
||||
cp com.libretro.RetroArch.metainfo.xml $(DESTDIR)$(DATA_DIR)/metainfo
|
||||
cp com.libretro.RetroArch.desktop $(DESTDIR)$(DATA_DIR)/applications
|
||||
cp com.libretro.RetroArch.appdata.xml $(DESTDIR)$(DATA_DIR)/metainfo
|
||||
cp retroarch.desktop $(DESTDIR)$(DATA_DIR)/applications
|
||||
cp docs/retroarch.6 $(DESTDIR)$(MAN_DIR)/man6
|
||||
cp docs/retroarch-cg2glsl.6 $(DESTDIR)$(MAN_DIR)/man6
|
||||
cp media/com.libretro.RetroArch.svg $(DESTDIR)$(DATA_DIR)/pixmaps
|
||||
cp media/retroarch.svg $(DESTDIR)$(DATA_DIR)/pixmaps
|
||||
cp COPYING $(DESTDIR)$(DOC_DIR)
|
||||
cp README.md $(DESTDIR)$(DOC_DIR)
|
||||
chmod 755 $(DESTDIR)$(BIN_DIR)/$(TARGET)
|
||||
chmod 755 $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
chmod 644 $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/applications/com.libretro.RetroArch.desktop
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/metainfo/com.libretro.RetroArch.metainfo.xml
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/applications/retroarch.desktop
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/metainfo/com.libretro.RetroArch.appdata.xml
|
||||
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch.6
|
||||
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch-cg2glsl.6
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/pixmaps/com.libretro.RetroArch.svg
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/pixmaps/retroarch.svg
|
||||
@if test -d media/assets && test $(HAVE_ASSETS); then \
|
||||
echo "Installing media assets..."; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
|
@ -300,9 +271,9 @@ uninstall:
|
|||
rm -f $(DESTDIR)$(BIN_DIR)/$(TARGET)
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
rm -f $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/applications/com.libretro.RetroArch.desktop
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/metainfo/com.libretro.RetroArch.metainfo.xml
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/pixmaps/com.libretro.RetroArch.svg
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/applications/retroarch.desktop
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/metainfo/com.libretro.RetroArch.appdata.xml
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/pixmaps/retroarch.svg
|
||||
rm -f $(DESTDIR)$(DOC_DIR)/COPYING
|
||||
rm -f $(DESTDIR)$(DOC_DIR)/COPYING.assets
|
||||
rm -f $(DESTDIR)$(DOC_DIR)/README.md
|
||||
|
@ -311,10 +282,9 @@ uninstall:
|
|||
rm -rf $(DESTDIR)$(ASSETS_DIR)
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -rf $(OBJDIR_BASE)
|
||||
$(Q)rm -f $(TARGET)
|
||||
$(Q)rm -f *.d
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
|
||||
.PHONY: all install uninstall clean
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ clean:
|
|||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f $(BINDIR)/retroarch
|
||||
rm -f $(BINDIR)/retroarch-joyconfig
|
||||
rm -f $(PNDDIR)/readme.html
|
||||
rm -f retroarch
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ clean:
|
|||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f $(BINDIR)/retroarch
|
||||
rm -f $(BINDIR)/retroarch-joyconfig
|
||||
rm -f $(PNDDIR)/readme.html
|
||||
rm -f retroarch
|
||||
|
||||
|
|
554
Makefile.common
554
Makefile.common
|
@ -15,9 +15,7 @@ ifeq ($(HAVE_NOUNUSED_VARIABLE), 1)
|
|||
DEF_FLAGS += $(NOUNUSED_VARIABLE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_QT6), 1)
|
||||
CXXFLAGS += $(CXX17_CFLAGS)
|
||||
else ifeq ($(HAVE_CXX11), 1)
|
||||
ifeq ($(HAVE_CXX11), 1)
|
||||
CXXFLAGS += $(CXX11_CFLAGS)
|
||||
endif
|
||||
|
||||
|
@ -25,6 +23,8 @@ ifeq ($(HAVE_SAPI), 1)
|
|||
LIBS += sapi.dll
|
||||
endif
|
||||
|
||||
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT),)
|
||||
HAVE_GL_CONTEXT = 0
|
||||
HAVE_GL_MODERN = 0
|
||||
|
@ -239,12 +239,14 @@ endif
|
|||
OBJ += frontend/frontend_driver.o \
|
||||
retroarch.o \
|
||||
runloop.o \
|
||||
driver.o \
|
||||
ui/ui_companion_driver.o \
|
||||
camera/camera_driver.o \
|
||||
record/record_driver.o \
|
||||
record/drivers/record_wav.o \
|
||||
command.o \
|
||||
msg_hash.o \
|
||||
midi_driver.o \
|
||||
location_driver.o \
|
||||
intl/msg_hash_us.o \
|
||||
$(LIBRETRO_COMM_DIR)/queues/task_queue.o \
|
||||
tasks/task_content.o
|
||||
|
@ -252,29 +254,10 @@ OBJ += frontend/frontend_driver.o \
|
|||
ifeq ($(HAVE_PATCH), 1)
|
||||
DEFINES += -DHAVE_PATCH
|
||||
OBJ += tasks/task_patch.o
|
||||
ifeq ($(HAVE_XDELTA), 1)
|
||||
DEFINES += -DHAVE_XDELTA -DSECONDARY_DJW -DSECONDARY_LZMA -DSECONDARY_FGK
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/xdelta3 -I$(LIBRETRO_COMM_DIR)
|
||||
LIBS += -llzma
|
||||
OBJ += $(DEPS_DIR)/xdelta3/xdelta3.o
|
||||
HEADERS += xdelta3.h \
|
||||
xdelta3-cfgs.h \
|
||||
xdelta3-fgk.h \
|
||||
xdelta3-hash.h \
|
||||
xdelta3-internal.h \
|
||||
xdelta3-list.h \
|
||||
xdelta3-lzma.h \
|
||||
xdelta3-second.h
|
||||
# These headers are added to the makefile because xdelta3 does weird things
|
||||
# with its #includes, which affects dependency tracking and project analysis
|
||||
# (e.g. for IDEs).
|
||||
endif
|
||||
endif
|
||||
|
||||
OBJ += \
|
||||
save.o \
|
||||
tasks/task_save.o \
|
||||
tasks/task_movie.o \
|
||||
tasks/task_file_transfer.o \
|
||||
tasks/task_image.o \
|
||||
tasks/task_playlist_manager.o \
|
||||
|
@ -338,21 +321,14 @@ OBJ += \
|
|||
gfx/video_driver.o \
|
||||
gfx/gfx_display.o \
|
||||
gfx/gfx_animation.o \
|
||||
gfx/gfx_thumbnail_path.o \
|
||||
gfx/gfx_thumbnail.o \
|
||||
gfx/video_coord_array.o \
|
||||
configuration.o \
|
||||
$(LIBRETRO_COMM_DIR)/dynamic/dylib.o \
|
||||
cores/dynamic_dummy.o \
|
||||
$(LIBRETRO_COMM_DIR)/queues/message_queue.o
|
||||
|
||||
ifeq ($(HAVE_MENU), 1)
|
||||
OBJ += \
|
||||
gfx/gfx_thumbnail_path.o \
|
||||
gfx/gfx_thumbnail.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_MICROPHONE), 1)
|
||||
DEFINES += -DHAVE_MICROPHONE
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_REWIND), 1)
|
||||
DEFINES += -DHAVE_REWIND
|
||||
OBJ += state_manager.o
|
||||
|
@ -455,7 +431,6 @@ endif
|
|||
|
||||
ifeq ($(HAVE_RUNAHEAD), 1)
|
||||
DEFINES += -DHAVE_RUNAHEAD
|
||||
OBJ += runahead.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CC_RESAMPLER), 1)
|
||||
|
@ -470,6 +445,38 @@ endif
|
|||
ifeq ($(HAVE_LANGEXTRA), 1)
|
||||
DEFINES += -DHAVE_LANGEXTRA
|
||||
DEF_FLAGS += -finput-charset=UTF-8
|
||||
|
||||
OBJ += intl/msg_hash_de.o \
|
||||
intl/msg_hash_eo.o \
|
||||
intl/msg_hash_es.o \
|
||||
intl/msg_hash_fr.o \
|
||||
intl/msg_hash_it.o \
|
||||
intl/msg_hash_ja.o \
|
||||
intl/msg_hash_ko.o \
|
||||
intl/msg_hash_nl.o \
|
||||
intl/msg_hash_pl.o \
|
||||
intl/msg_hash_pt_br.o \
|
||||
intl/msg_hash_pt_pt.o \
|
||||
intl/msg_hash_ru.o \
|
||||
intl/msg_hash_vn.o \
|
||||
intl/msg_hash_chs.o \
|
||||
intl/msg_hash_cht.o \
|
||||
intl/msg_hash_ar.o \
|
||||
intl/msg_hash_el.o \
|
||||
intl/msg_hash_tr.o \
|
||||
intl/msg_hash_sk.o \
|
||||
intl/msg_hash_fa.o \
|
||||
intl/msg_hash_he.o \
|
||||
intl/msg_hash_ast.o \
|
||||
intl/msg_hash_fi.o \
|
||||
intl/msg_hash_id.o \
|
||||
intl/msg_hash_sv.o \
|
||||
intl/msg_hash_uk.o \
|
||||
intl/msg_hash_cs.o \
|
||||
intl/msg_hash_val.o \
|
||||
intl/msg_hash_ca.o \
|
||||
intl/msg_hash_en.o \
|
||||
intl/msg_hash_hu.o
|
||||
endif
|
||||
|
||||
ifneq ($(HAVE_GETOPT_LONG), 1)
|
||||
|
@ -536,18 +543,10 @@ ifeq ($(HAVE_QT), 1)
|
|||
endif
|
||||
|
||||
DEFINES += -DHAVE_MAIN
|
||||
ifeq ($(HAVE_QT6), 1)
|
||||
CXXFLAGS += -DQT_DISABLE_DEPRECATED_BEFORE=0x060000 $(QT6CORE_CFLAGS) $(QT6GUI_CFLAGS) $(QT6WIDGETS_CFLAGS) $(QT6CONCURRENT_CFLAGS) $(QT6NETWORK_CFLAGS)
|
||||
#DEF_FLAGS += $(QT6WEBENGINE_CFLAGS)
|
||||
LIBS += $(QT6CORE_LIBS) $(QT6GUI_LIBS) $(QT6WIDGETS_LIBS) $(QT6CONCURRENT_LIBS) $(QT6NETWORK_LIBS)
|
||||
#LIBS += $(QT6WEBENGINE_LIBS)
|
||||
else
|
||||
DEF_FLAGS += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) $(QT5NETWORK_CFLAGS)
|
||||
#DEF_FLAGS += $(QT5WEBENGINE_CFLAGS)
|
||||
LIBS += $(QT5CORE_LIBS) $(QT5GUI_LIBS) $(QT5WIDGETS_LIBS) $(QT5CONCURRENT_LIBS) $(QT5NETWORK_LIBS)
|
||||
#LIBS += $(QT5WEBENGINE_LIBS)
|
||||
endif
|
||||
|
||||
NEED_CXX_LINKER = 1
|
||||
|
||||
ifneq ($(findstring Linux,$(OS)),)
|
||||
|
@ -767,8 +766,7 @@ else ifeq ($(HAVE_BUILTINMBEDTLS), 1)
|
|||
OBJ += $(OBJS_TLS_CRYPTO) $(OBJS_TLS_X509) $(OBJS_TLS)
|
||||
else ifeq ($(HAVE_SSL), 1)
|
||||
DEFINES += -DHAVE_SSL
|
||||
LIBS += $(SYSTEMMBEDTLS_LIBS) $(SYSTEMMBEDX509_LIBS) $(SYSTEMMBEDCRYPTO_LIBS)
|
||||
DEF_FLAGS += $(SYSTEMMBEDTLS_CFLAGS) $(SYSTEMMBEDX509_CFLAGS) $(SYSTEMMBEDCRYPTO_CFLAGS)
|
||||
LIBS += $(SYSTEMMBEDTLS_LIBS)
|
||||
endif
|
||||
|
||||
# Miscellaneous
|
||||
|
@ -785,13 +783,8 @@ ifeq ($(HAVE_EMSCRIPTEN), 1)
|
|||
OBJ += frontend/drivers/platform_emscripten.o \
|
||||
input/drivers/rwebinput_input.o \
|
||||
input/drivers_joypad/rwebpad_joypad.o \
|
||||
audio/drivers/rwebaudio.o \
|
||||
camera/drivers/rwebcam.o
|
||||
ifeq ($(HAVE_RWEBAUDIO), 1)
|
||||
OBJ += audio/drivers/rwebaudio.o
|
||||
endif
|
||||
ifeq ($(HAVE_AUDIOWORKLET), 1)
|
||||
OBJ += audio/drivers/audioworklet.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_BLUETOOTH), 1)
|
||||
|
@ -838,6 +831,18 @@ ifeq ($(HAVE_CORETEXT), 1)
|
|||
OBJ += gfx/drivers_font_renderer/coretext.o
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET), retroarch_3ds)
|
||||
OBJ += gfx/drivers_font/ctr_font.o
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET), retroarch_ps2)
|
||||
OBJ += gfx/drivers_font/ps2_font.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LIBNX), 1)
|
||||
OBJ += gfx/drivers_font/switch_font.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AUDIOIO), 1)
|
||||
OBJ += audio/drivers/audioio.o
|
||||
endif
|
||||
|
@ -857,8 +862,7 @@ endif
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_ALSA), 1)
|
||||
OBJ += audio/drivers/alsa.o \
|
||||
audio/common/alsa.o
|
||||
OBJ += audio/drivers/alsa.o
|
||||
|
||||
ifneq ($(HAVE_HAKCHI), 1)
|
||||
ifneq ($(HAVE_SEGAM), 1)
|
||||
|
@ -914,18 +918,6 @@ ifeq ($(HAVE_PULSE), 1)
|
|||
DEF_FLAGS += $(PULSE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_PIPEWIRE), 1)
|
||||
OBJ += audio/drivers/pipewire.o \
|
||||
audio/common/pipewire.o
|
||||
|
||||
ifeq ($(HAVE_PIPEWIRE_STABLE), 1)
|
||||
OBJ += camera/drivers/pipewire.o
|
||||
endif
|
||||
|
||||
LIBS += $(PIPEWIRE_LIBS)
|
||||
DEF_FLAGS += $(PIPEWIRE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OSS_LIB), 1)
|
||||
LIBS += -lossaudio
|
||||
endif
|
||||
|
@ -966,12 +958,6 @@ ifeq ($(HAVE_WINMM), 1)
|
|||
LIBS += -lwinmm
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREMIDI), 1)
|
||||
OBJ += midi/drivers/coremidi.o
|
||||
DEFINES += -DHAVE_COREMIDI
|
||||
LIBS += -framework CoreMIDI
|
||||
endif
|
||||
|
||||
# Audio Resamplers
|
||||
|
||||
ifeq ($(HAVE_NEON),1)
|
||||
|
@ -984,9 +970,7 @@ ifeq ($(HAVE_NEON),1)
|
|||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/conversion/mono_to_stereo_float.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/conversion/stereo_to_mono_float.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.o
|
||||
|
||||
ifeq ($(HAVE_RWAV), 1)
|
||||
DEFINES += -DHAVE_RWAV
|
||||
|
@ -1078,22 +1062,16 @@ endif
|
|||
|
||||
ifeq ($(HAVE_LAKKA), 1)
|
||||
DEFINES += -DHAVE_LAKKA
|
||||
ifneq ($(HAVE_LAKKA_PROJECT),)
|
||||
DEFINES += -DHAVE_LAKKA_PROJECT=\"${HAVE_LAKKA_PROJECT}\"
|
||||
else
|
||||
$(error You asked for Lakka, but you did not specify a target device name in HAVE_LAKKA_PROJECT)
|
||||
endif
|
||||
ifneq ($(HAVE_LAKKA_SERVER),)
|
||||
DEFINES += -DHAVE_LAKKA_SERVER=\"${HAVE_LAKKA_SERVER}\"
|
||||
else
|
||||
$(error You asked for Lakka, but you did not specify update server in HAVE_LAKKA_SERVER)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LAKKA_SWITCH), 1)
|
||||
DEFINES += -DHAVE_LAKKA_SWITCH
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LAKKA_NIGHTLY), 1)
|
||||
DEFINES += -DHAVE_LAKKA_NIGHTLY
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
OBJ += menu/menu_setting.o \
|
||||
menu/menu_driver.o \
|
||||
|
@ -1139,6 +1117,18 @@ ifeq ($(HAVE_OVERLAY), 1)
|
|||
led/drivers/led_overlay.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEO_LAYOUT), 1)
|
||||
DEFINES += -DHAVE_VIDEO_LAYOUT
|
||||
OBJ += \
|
||||
gfx/video_layout.o \
|
||||
gfx/video_layout/view.o \
|
||||
gfx/video_layout/element.o \
|
||||
gfx/video_layout/component.o \
|
||||
gfx/video_layout/internal.o \
|
||||
gfx/video_layout/scope.o \
|
||||
gfx/video_layout/load.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_STB_FONT), 1)
|
||||
OBJ += gfx/drivers_font_renderer/stb.o
|
||||
OBJ += gfx/drivers_font_renderer/stb_unicode.o
|
||||
|
@ -1184,13 +1174,17 @@ ifeq ($(HAVE_VITA2D), 1)
|
|||
$(DEPS_DIR)/libvita2d/shader/texture_tint_v_gxp.o \
|
||||
$(DEPS_DIR)/libvita2d/shader/texture_tint_f_gxp.o
|
||||
|
||||
OBJ += gfx/drivers/vita2d_gfx.o
|
||||
OBJ += gfx/drivers_display/gfx_display_vita2d.o
|
||||
|
||||
OBJ += gfx/drivers/vita2d_gfx.o \
|
||||
gfx/drivers_font/vita2d_font.o
|
||||
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/libvita2d/include
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET), retroarch_3ds)
|
||||
OBJ += gfx/drivers/ctr_gfx.o \
|
||||
gfx/drivers_display/gfx_display_ctr.o \
|
||||
input/drivers/ctr_input.o \
|
||||
input/drivers_joypad/ctr_joypad.o
|
||||
endif
|
||||
|
@ -1217,6 +1211,8 @@ endif
|
|||
|
||||
ifeq ($(TARGET), retroarch_wiiu)
|
||||
OBJ += gfx/drivers/gx2_gfx.o \
|
||||
gfx/drivers_font/wiiu_font.o \
|
||||
gfx/drivers_display/gfx_display_wiiu.o \
|
||||
input/drivers/wiiu_input.o \
|
||||
input/drivers_joypad/wiiu_joypad.o \
|
||||
input/drivers_joypad/wiiu/wpad_driver.o \
|
||||
|
@ -1235,12 +1231,15 @@ endif
|
|||
|
||||
ifeq ($(TARGET), retroarch_switch)
|
||||
ifeq ($(HAVE_LIBNX), 1)
|
||||
OBJ += gfx/drivers/switch_nx_gfx.o \
|
||||
OBJ += gfx/drivers_display/gfx_display_switch.o \
|
||||
gfx/drivers/switch_nx_gfx.o \
|
||||
audio/drivers/switch_libnx_audren_audio.o \
|
||||
audio/drivers/switch_libnx_audren_thread_audio.o
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/drivers_context/switch_ctx.o
|
||||
endif
|
||||
else
|
||||
OBJ += gfx/drivers/switch_gfx.o
|
||||
endif
|
||||
OBJ += audio/drivers/switch_audio.o \
|
||||
audio/drivers/switch_thread_audio.o \
|
||||
|
@ -1263,18 +1262,9 @@ ifeq ($(HAVE_WAYLAND), 1)
|
|||
input/common/wayland_common.o \
|
||||
input/drivers/wayland_input.o \
|
||||
gfx/common/wayland_common.o \
|
||||
gfx/common/wayland/fractional-scale-v1.o \
|
||||
gfx/common/wayland/viewporter.o \
|
||||
gfx/common/wayland/xdg-toplevel-icon-v1.o \
|
||||
gfx/common/wayland/xdg-shell.o \
|
||||
gfx/common/wayland/idle-inhibit-unstable-v1.o \
|
||||
gfx/common/wayland/xdg-decoration-unstable-v1.o \
|
||||
gfx/common/wayland/pointer-constraints-unstable-v1.o \
|
||||
gfx/common/wayland/relative-pointer-unstable-v1.o \
|
||||
gfx/common/wayland/cursor-shape-v1.o \
|
||||
gfx/common/wayland/tablet-unstable-v2.o \
|
||||
gfx/common/wayland/content-type-v1.o \
|
||||
gfx/common/wayland/single-pixel-buffer-v1.o
|
||||
gfx/common/wayland/xdg-decoration-unstable-v1.o
|
||||
|
||||
ifeq ($(HAVE_VULKAN), 1)
|
||||
OBJ += gfx/drivers_context/wayland_vk_ctx.o
|
||||
|
@ -1332,13 +1322,6 @@ ifeq ($(HAVE_X11), 1)
|
|||
ifeq ($(HAVE_XCB),1)
|
||||
LIBS += -lX11-xcb
|
||||
endif
|
||||
ifeq ($(HAVE_XI2),1)
|
||||
LIBS += -lXi
|
||||
DEFINES += -DHAVE_XI2
|
||||
endif
|
||||
ifeq ($(HAVE_XSCRNSAVER),1)
|
||||
LIBS += -lXss
|
||||
endif
|
||||
ifneq ($(HAVE_OPENGLES), 1)
|
||||
OBJ += gfx/drivers_context/x_ctx.o
|
||||
endif
|
||||
|
@ -1379,11 +1362,12 @@ ifeq ($(HAVE_LIBUSB), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_IOHIDMANAGER), 1)
|
||||
HAVE_HID=1
|
||||
ifeq ($(HAVE_HID), 1)
|
||||
DEFINES += -DHAVE_IOHIDMANAGER
|
||||
OBJ += input/drivers_hid/iohidmanager_hid.o
|
||||
LIBS += -framework IOKit
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_HID), 1)
|
||||
DEFINES += -DHAVE_HID
|
||||
|
@ -1445,8 +1429,7 @@ OBJ += gfx/drivers_context/gfx_null_ctx.o
|
|||
|
||||
ifeq ($(HAVE_KMS), 1)
|
||||
HAVE_AND_WILL_USE_DRM = 1
|
||||
OBJ += gfx/drivers_context/drm_ctx.o \
|
||||
gfx/display_servers/dispserv_kms.o
|
||||
OBJ += gfx/drivers_context/drm_ctx.o
|
||||
|
||||
ifeq ($(HAVE_ODROIDGO2), 1)
|
||||
OBJ += gfx/drivers_context/drm_go2_ctx.o
|
||||
|
@ -1457,7 +1440,7 @@ endif
|
|||
|
||||
ifeq ($(HAVE_CACA), 1)
|
||||
DEFINES += -DHAVE_CACA
|
||||
OBJ += gfx/drivers/caca_gfx.o
|
||||
OBJ += gfx/drivers/caca_gfx.o gfx/drivers_font/caca_font.o
|
||||
LIBS += $(CACA_LIBS)
|
||||
DEF_FLAGS += $(CACA_CFLAGS)
|
||||
endif
|
||||
|
@ -1465,7 +1448,8 @@ endif
|
|||
ifeq ($(HAVE_SIXEL), 1)
|
||||
DEFINES += -DHAVE_SIXEL
|
||||
INCLUDE_DIRS += -I/usr/include/sixel
|
||||
OBJ += gfx/drivers/sixel_gfx.o
|
||||
OBJ += gfx/drivers/sixel_gfx.o \
|
||||
gfx/drivers_font/sixel_font.o
|
||||
LIBS += $(SIXEL_LIBS)
|
||||
DEF_FLAGS += $(SIXEL_CFLAGS)
|
||||
endif
|
||||
|
@ -1493,13 +1477,14 @@ ifeq ($(HAVE_PLAIN_DRM), 1)
|
|||
INCLUDE_DIRS += -I/usr/include/libdrm
|
||||
endif
|
||||
LIBS += -ldrm
|
||||
HAVE_AND_WILL_USE_DRM = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VITAGL), 1)
|
||||
DEFINES += -DHAVE_OPENGL1 -DHAVE_VITAGL
|
||||
OBJ += gfx/drivers/gl1.o \
|
||||
gfx/drivers_context/vita_ctx.o
|
||||
gfx/drivers_font/gl1_raster_font.o \
|
||||
gfx/drivers_context/vita_ctx.o \
|
||||
gfx/drivers_display/gfx_display_gl1.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VITAGLES), 1)
|
||||
|
@ -1511,14 +1496,18 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
|||
ifeq ($(HAVE_GL_MODERN), 1)
|
||||
DEFINES += -DHAVE_OPENGL
|
||||
OBJ += gfx/drivers/gl2.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o \
|
||||
gfx/drivers_font/gl2_raster_font.o \
|
||||
gfx/drivers_display/gfx_display_gl2.o
|
||||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/rglgen.o
|
||||
|
||||
ifeq ($(HAVE_OPENGL1), 1)
|
||||
DEFINES += -DHAVE_OPENGL1
|
||||
OBJ += gfx/drivers/gl1.o
|
||||
OBJ += gfx/drivers/gl1.o \
|
||||
gfx/drivers_font/gl1_raster_font.o \
|
||||
gfx/drivers_display/gfx_display_gl1.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEOCORE), 1)
|
||||
|
@ -1526,11 +1515,8 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_EMSCRIPTEN), 1)
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
OBJ += gfx/drivers_context/emscriptenegl_ctx.o
|
||||
endif
|
||||
OBJ += gfx/drivers_context/emscriptenwebgl_ctx.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_MALI_FBDEV), 1)
|
||||
OBJ += gfx/drivers_context/mali_fbdev_ctx.o
|
||||
|
@ -1573,11 +1559,10 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
|||
DEF_FLAGS += $(OPENGLES_CFLAGS)
|
||||
ifeq ($(HAVE_OPENGLES3), 1)
|
||||
DEFINES += -DHAVE_OPENGLES3
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.o
|
||||
else
|
||||
DEFINES += -DHAVE_OPENGLES2
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/glsym_es2.o
|
||||
endif
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/glsym_es2.o
|
||||
else
|
||||
DEFINES += -DHAVE_GL_SYNC
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/glsym_gl.o
|
||||
|
@ -1600,7 +1585,10 @@ ifeq ($(HAVE_METAL), 1)
|
|||
DEF_FLAGS += -fobjc-arc
|
||||
OBJ += \
|
||||
gfx/common/metal/metal_renderer.o \
|
||||
gfx/drivers/metal.o
|
||||
gfx/common/metal_common.o \
|
||||
gfx/drivers/metal.o \
|
||||
gfx/drivers_font/metal_raster_font.o \
|
||||
gfx/drivers_display/gfx_display_metal.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
|
@ -1672,7 +1660,9 @@ ifeq ($(HAVE_VULKAN), 1)
|
|||
|
||||
OBJ += gfx/drivers/vulkan.o \
|
||||
gfx/common/vulkan_common.o \
|
||||
$(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o
|
||||
$(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o \
|
||||
gfx/drivers_font/vulkan_raster_font.o \
|
||||
gfx/drivers_display/gfx_display_vulkan.o
|
||||
|
||||
ifeq ($(HAVE_SLANG), 1)
|
||||
OBJ += gfx/drivers_shader/shader_vulkan.o
|
||||
|
@ -1687,16 +1677,14 @@ ifeq ($(HAVE_VULKAN), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL_CORE), 1)
|
||||
OBJ += gfx/drivers/gl3.o
|
||||
OBJ += gfx/drivers/gl3.o \
|
||||
gfx/drivers_font/gl3_raster_font.o \
|
||||
gfx/drivers_shader/shader_gl3.o \
|
||||
gfx/drivers_display/gfx_display_gl3.o
|
||||
|
||||
DEFINES += -DHAVE_OPENGL_CORE
|
||||
|
||||
ifeq ($(HAVE_SLANG), 1)
|
||||
OBJ += gfx/drivers_shader/shader_gl3.o
|
||||
|
||||
NEED_CXX_LINKER = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OMAP), 1)
|
||||
OBJ += gfx/drivers/omap_gfx.o
|
||||
|
@ -1748,28 +1736,38 @@ ifeq ($(HAVE_D3D9), 1)
|
|||
endif
|
||||
endif
|
||||
HAVE_DX_COMMON = 1
|
||||
OBJ += gfx/drivers_font/d3d9x_w32_font.o
|
||||
OBJ += gfx/drivers_font/d3d_w32_font.o
|
||||
ifeq ($(HAVE_CG), 1)
|
||||
LIBS += -lcgD3D9
|
||||
OBJ += gfx/drivers/d3d9cg.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d9cg.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D10), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d10.o
|
||||
OBJ += gfx/drivers/d3d10.o \
|
||||
gfx/common/d3d10_common.o \
|
||||
gfx/drivers_font/d3d10_font.o \
|
||||
gfx/drivers_display/gfx_display_d3d10.o
|
||||
DEFINES += -DHAVE_D3D10
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D11), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d11.o
|
||||
OBJ += gfx/drivers/d3d11.o \
|
||||
gfx/common/d3d11_common.o \
|
||||
gfx/drivers_font/d3d11_font.o \
|
||||
gfx/drivers_display/gfx_display_d3d11.o
|
||||
DEFINES += -DHAVE_D3D11
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D12), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d12.o
|
||||
OBJ += gfx/drivers/d3d12.o \
|
||||
gfx/common/d3d12_common.o \
|
||||
gfx/drivers_font/d3d12_font.o \
|
||||
gfx/drivers_display/gfx_display_d3d12.o
|
||||
DEFINES += -DHAVE_D3D12
|
||||
endif
|
||||
|
||||
|
@ -1806,6 +1804,8 @@ endif
|
|||
ifeq ($(HAVE_D3D8), 1)
|
||||
DEFINES += -DHAVE_D3D8
|
||||
OBJ += gfx/drivers/d3d8.o
|
||||
OBJ += gfx/common/d3d8_common.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d8.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D9), 1)
|
||||
|
@ -1832,6 +1832,7 @@ endif
|
|||
ifeq ($(HAVE_HLSL),1)
|
||||
DEFINES += -DHAVE_HLSL
|
||||
OBJ += gfx/drivers/d3d9hlsl.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d9hlsl.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SLANG),1)
|
||||
|
@ -1876,6 +1877,10 @@ ifeq ($(HAVE_BUILTINGLSLANG), 1)
|
|||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \
|
||||
$(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/ossource.cpp
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
DEFINES += -DENABLE_HLSL
|
||||
GLSLANG_SOURCES += $(wildcard $(DEPS_DIR)/glslang/glslang/hlsl/*.cpp)
|
||||
endif
|
||||
else ifeq ($(HAVE_GLSLANG),1)
|
||||
HAVE_GLSLANG_COMMON = 1
|
||||
GLSLANG_SOURCES := gfx/drivers_shader/glslang.cpp
|
||||
|
@ -1886,6 +1891,7 @@ else ifeq ($(HAVE_GLSLANG),1)
|
|||
$(GLSLANG_GENERICCODEGEN_LIBS) \
|
||||
$(GLSLANG_OSDEPENDENT_LIBS) \
|
||||
$(GLSLANG_OGLCOMPILER_LIBS) \
|
||||
$(GLSLANG_HLSL_LIBS) \
|
||||
$(GLSLANG_SPIRV_LIBS) \
|
||||
$(GLSLANG_SPIRV_TOOLS_OPT_LIBS) \
|
||||
$(GLSLANG_SPIRV_TOOLS_LIBS)
|
||||
|
@ -1949,34 +1955,6 @@ ifeq ($(HAVE_7ZIP),1)
|
|||
$(7ZOBJ)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZSTD),1)
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/zstd/lib
|
||||
DEFINES += -DHAVE_ZSTD -DZSTD_DISABLE_ASM
|
||||
ZSOBJ = $(DEPS_DIR)/zstd/lib/common/entropy_common.o \
|
||||
$(DEPS_DIR)/zstd/lib/common/error_private.o \
|
||||
$(DEPS_DIR)/zstd/lib/common/fse_decompress.o \
|
||||
$(DEPS_DIR)/zstd/lib/common/zstd_common.o \
|
||||
$(DEPS_DIR)/zstd/lib/common/xxhash.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/fse_compress.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/hist.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/huf_compress.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_compress.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_compress_literals.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_compress_sequences.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_compress_superblock.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_double_fast.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_fast.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_lazy.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_ldm.o \
|
||||
$(DEPS_DIR)/zstd/lib/compress/zstd_opt.o \
|
||||
$(DEPS_DIR)/zstd/lib/decompress/huf_decompress.o \
|
||||
$(DEPS_DIR)/zstd/lib/decompress/zstd_ddict.o \
|
||||
$(DEPS_DIR)/zstd/lib/decompress/zstd_decompress.o \
|
||||
$(DEPS_DIR)/zstd/lib/decompress/zstd_decompress_block.o
|
||||
|
||||
OBJ += $(ZSOBJ)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_IBXM), 1)
|
||||
DEFINES += -DHAVE_IBXM
|
||||
OBJ += $(DEPS_DIR)/ibxm/ibxm.o
|
||||
|
@ -2018,7 +1996,6 @@ ifeq ($(HAVE_BUILTINZLIB), 1)
|
|||
HAVE_ZLIB_COMMON = 1
|
||||
OBJ += $(DEPS_DIR)/libz/adler32.o \
|
||||
$(DEPS_DIR)/libz/libz-crc32.o \
|
||||
$(DEPS_DIR)/libz/compress.o \
|
||||
$(DEPS_DIR)/libz/deflate.o \
|
||||
$(DEPS_DIR)/libz/gzclose.o \
|
||||
$(DEPS_DIR)/libz/gzlib.o \
|
||||
|
@ -2028,7 +2005,6 @@ ifeq ($(HAVE_BUILTINZLIB), 1)
|
|||
$(DEPS_DIR)/libz/inflate.o \
|
||||
$(DEPS_DIR)/libz/inftrees.o \
|
||||
$(DEPS_DIR)/libz/trees.o \
|
||||
$(DEPS_DIR)/libz/uncompr.o \
|
||||
$(DEPS_DIR)/libz/zutil.o
|
||||
INCLUDE_DIRS += -I$(LIBRETRO_COMM_DIR)/include/compat/zlib
|
||||
else ifeq ($(HAVE_ZLIB),1)
|
||||
|
@ -2046,97 +2022,6 @@ ifeq ($(HAVE_ZLIB_COMMON), 1)
|
|||
ifeq ($(HAVE_CHD), 1)
|
||||
INCLUDE_DIRS += -I$(LIBRETRO_COMM_DIR)/formats/libchdr
|
||||
DEFINES += -DHAVE_CHD -DWANT_SUBCODE -DWANT_RAW_DATA_SECTOR
|
||||
ifeq ($(HAVE_STATIC_CORES), 1)
|
||||
DEFINES += -Dbitstream_overflow=retroarch_internal_bitstream_overflow
|
||||
DEFINES += -Dcreate_bitstream=retroarch_internal_create_bitstream
|
||||
DEFINES += -Dbitstream_peek=retroarch_internal_bitstream_peek
|
||||
DEFINES += -Dbitstream_remove=retroarch_internal_bitstream_remove
|
||||
DEFINES += -Dbitstream_read=retroarch_internal_bitstream_read
|
||||
DEFINES += -Dbitstream_read_offset=retroarch_internal_bitstream_read_offset
|
||||
DEFINES += -Dbitstream_flush=retroarch_internal_bitstream_flush
|
||||
|
||||
DEFINES += -Decc_compute_bytes=retroarch_internal_ecc_compute_bytes
|
||||
DEFINES += -Decc_verify=retroarch_internal_ecc_verify
|
||||
DEFINES += -Decc_generate=retroarch_internal_ecc_generate
|
||||
DEFINES += -Decc_clear=retroarch_internal_ecc_clear
|
||||
|
||||
DEFINES += -Ds_cd_sync_header=retroarch_internal_s_cd_sync_header
|
||||
DEFINES += -Dchd_open_file=retroarch_internal_chd_open_file
|
||||
DEFINES += -Dchd_precache=retroarch_internal_chd_precache
|
||||
DEFINES += -Dchd_open=retroarch_internal_chd_open
|
||||
DEFINES += -Dchd_close=retroarch_internal_chd_close
|
||||
DEFINES += -Dchd_core_file=retroarch_internal_chd_core_file
|
||||
DEFINES += -Dchd_error_string=retroarch_internal_chd_error_string
|
||||
DEFINES += -Dchd_get_header=retroarch_internal_chd_get_header
|
||||
DEFINES += -Dchd_read=retroarch_internal_chd_read
|
||||
DEFINES += -Dchd_get_metadata=retroarch_internal_chd_get_metadata
|
||||
DEFINES += -Dchd_codec_config=retroarch_internal_chd_codec_config
|
||||
DEFINES += -Dchd_get_codec_name=retroarch_internal_chd_get_codec_name
|
||||
|
||||
DEFINES += -Dcreate_huffman_decoder=retroarch_internal_create_huffman_decoder
|
||||
DEFINES += -Ddelete_huffman_decoder=retroarch_internal_delete_huffman_decoder
|
||||
DEFINES += -Dhuffman_decode_one=retroarch_internal_huffman_decode_one
|
||||
DEFINES += -Dhuffman_import_tree_rle=retroarch_internal_huffman_import_tree_rle
|
||||
DEFINES += -Dhuffman_import_tree_huffman=retroarch_internal_huffman_import_tree_huffman
|
||||
DEFINES += -Dhuffman_compute_tree_from_histo=retroarch_internal_huffman_compute_tree_from_histo
|
||||
DEFINES += -Dhuffman_build_tree=retroarch_internal_huffman_build_tree
|
||||
DEFINES += -Dhuffman_assign_canonical_codes=retroarch_internal_huffman_assign_canonical_codes
|
||||
DEFINES += -Dhuffman_build_lookup_table=retroarch_internal_huffman_build_lookup_table
|
||||
|
||||
DEFINES += -Dcdzl_codec_init=retroarch_internal_cdzl_codec_init
|
||||
DEFINES += -Dcdzl_codec_free=retroarch_internal_cdzl_codec_free
|
||||
DEFINES += -Dcdzl_codec_decompress=retroarch_internal_cdzl_codec_decompress
|
||||
DEFINES += -Dzlib_codec_init=retroarch_internal_zlib_codec_init
|
||||
DEFINES += -Dzlib_codec_free=retroarch_internal_zlib_codec_free
|
||||
DEFINES += -Dzlib_codec_decompress=retroarch_internal_zlib_codec_decompress
|
||||
DEFINES += -Dzlib_fast_alloc=retroarch_internal_zlib_fast_alloc
|
||||
DEFINES += -Dzlib_fast_free=retroarch_internal_zlib_fast_free
|
||||
|
||||
DEFINES += -Dchdstream_open=retroarch_internal_chdstream_open
|
||||
DEFINES += -Dchdstream_close=retroarch_internal_chdstream_close
|
||||
DEFINES += -Dchdstream_read=retroarch_internal_chdstream_read
|
||||
DEFINES += -Dchdstream_getc=retroarch_internal_chdstream_getc
|
||||
DEFINES += -Dchdstream_gets=retroarch_internal_chdstream_gets
|
||||
DEFINES += -Dchdstream_tell=retroarch_internal_chdstream_tell
|
||||
DEFINES += -Dchdstream_rewind=retroarch_internal_chdstream_rewind
|
||||
DEFINES += -Dchdstream_seek=retroarch_internal_chdstream_seek
|
||||
DEFINES += -Dchdstream_get_size=retroarch_internal_chdstream_get_size
|
||||
DEFINES += -Dchdstream_get_track_start=retroarch_internal_chdstream_get_track_start
|
||||
DEFINES += -Dchdstream_get_frame_size=retroarch_internal_chdstream_get_frame_size
|
||||
DEFINES += -Dchdstream_get_first_track_sector=retroarch_internal_chdstream_get_first_track_sector
|
||||
|
||||
DEFINES += -Dflac_decoder_init=retroarch_internal_flac_decoder_init
|
||||
DEFINES += -Dflac_decoder_free=retroarch_internal_flac_decoder_free
|
||||
DEFINES += -Dflac_decoder_reset=retroarch_internal_flac_decoder_reset
|
||||
DEFINES += -Dflac_decoder_decode_interleaved=retroarch_internal_flac_decoder_decode_interleaved
|
||||
DEFINES += -Dflac_decoder_finish=retroarch_internal_flac_decoder_finish
|
||||
DEFINES += -Dflac_decoder_read_callback_static=retroarch_internal_flac_decoder_read_callback_static
|
||||
DEFINES += -Dflac_decoder_read_callback=retroarch_internal_flac_decoder_read_callback
|
||||
DEFINES += -Dflac_decoder_metadata_callback_static=retroarch_internal_flac_decoder_metadata_callback_static
|
||||
DEFINES += -Dflac_decoder_tell_callback_static=retroarch_internal_flac_decoder_tell_callback_static
|
||||
DEFINES += -Dflac_decoder_write_callback_static=retroarch_internal_flac_decoder_write_callback_static
|
||||
DEFINES += -Dflac_decoder_write_callback=retroarch_internal_flac_decoder_write_callback
|
||||
DEFINES += -Dflac_decoder_error_callback_static=retroarch_internal_flac_decoder_error_callback_static
|
||||
DEFINES += -Dcdfl_codec_init=retroarch_internal_cdfl_codec_init
|
||||
DEFINES += -Dcdfl_codec_free=retroarch_internal_cdfl_codec_free
|
||||
DEFINES += -Dcdfl_codec_decompress=retroarch_internal_cdfl_codec_decompress
|
||||
|
||||
DEFINES += -Dlzma_allocator_init=retroarch_internal_lzma_allocator_init
|
||||
DEFINES += -Dlzma_allocator_free=retroarch_internal_lzma_allocator_free
|
||||
DEFINES += -Dlzma_codec_init=retroarch_internal_lzma_codec_init
|
||||
DEFINES += -Dlzma_codec_free=retroarch_internal_lzma_codec_free
|
||||
DEFINES += -Dlzma_codec_decompress=retroarch_internal_lzma_codec_decompress
|
||||
DEFINES += -Dcdlz_codec_init=retroarch_internal_cdlz_codec_init
|
||||
DEFINES += -Dcdlz_codec_free=retroarch_internal_cdlz_codec_free
|
||||
DEFINES += -Dcdlz_codec_decompress=retroarch_internal_cdlz_codec_decompress
|
||||
|
||||
DEFINES += -Dzstd_codec_init=retroarch_internal_zstd_codec_init
|
||||
DEFINES += -Dzstd_codec_free=retroarch_internal_zstd_codec_free
|
||||
DEFINES += -Dzstd_codec_decompress=retroarch_internal_zstd_codec_decompress
|
||||
DEFINES += -Dcdzs_codec_init=retroarch_internal_cdzs_codec_init
|
||||
DEFINES += -Dcdzs_codec_free=retroarch_internal_cdzs_codec_free
|
||||
DEFINES += -Dcdzs_codec_decompress=retroarch_internal_cdzs_codec_decompress
|
||||
endif
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_bitstream.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_cdrom.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_chd.o \
|
||||
|
@ -2152,10 +2037,6 @@ ifeq ($(HAVE_ZLIB_COMMON), 1)
|
|||
ifeq ($(HAVE_7ZIP), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_lzma.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZSTD), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zstd.o
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -2209,65 +2090,6 @@ ifeq ($(HAVE_V4L2),1)
|
|||
LIBS += $(V4L2_LIBS)
|
||||
endif
|
||||
|
||||
# FFmpeg
|
||||
|
||||
ifeq ($(HAVE_FFMPEG), 1)
|
||||
DEFINES += -DHAVE_FFMPEG
|
||||
INCLUDE_DIRS += -Iffmpeg
|
||||
DEF_FLAGS += $(FFMPEG_CFLAGS) -Wno-deprecated-declarations
|
||||
LIBS += $(FFMPEG_LIBS)
|
||||
|
||||
ifeq ($(HAVE_AVCODEC), 1)
|
||||
DEFINES += -DHAVE_AVCODEC
|
||||
DEF_FLAGS += $(AVCODEC_CFLAGS)
|
||||
LIBS += $(AVCODEC_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AVDEVICE), 1)
|
||||
DEFINES += -DHAVE_AVDEVICE
|
||||
DEF_FLAGS += $(AVDEVICE_CFLAGS)
|
||||
LIBS += $(AVDEVICE_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AVFORMAT), 1)
|
||||
DEFINES += -DHAVE_AVFORMAT
|
||||
DEF_FLAGS += $(AVFORMAT_CFLAGS)
|
||||
LIBS += $(AVFORMAT_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AVUTIL), 1)
|
||||
DEFINES += -DHAVE_AVUTIL
|
||||
DEF_FLAGS += $(AVUTIL_CFLAGS)
|
||||
LIBS += $(AVUTIL_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SWSCALE), 1)
|
||||
DEFINES += -DHAVE_SWSCALE
|
||||
DEF_FLAGS += $(SWSCALE_CFLAGS)
|
||||
LIBS += $(SWSCALE_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SWRESAMPLE), 1)
|
||||
DEFINES += -DHAVE_SWRESAMPLE
|
||||
DEF_FLAGS += $(SWRESAMPLE_CFLAGS)
|
||||
LIBS += $(SWRESAMPLE_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FFMPEG), 1)
|
||||
ifeq ($(HAVE_AVFORMAT), 1)
|
||||
ifeq ($(HAVE_AVDEVICE), 1)
|
||||
ifeq ($(HAVE_AVCODEC), 1)
|
||||
ifeq ($(HAVE_AVUTIL), 1)
|
||||
ifeq ($(HAVE_SWSCALE), 1)
|
||||
OBJ += camera/drivers/ffmpeg.o
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Accessibility
|
||||
ifeq ($(HAVE_ACCESSIBILITY), 1)
|
||||
DEFINES += -DHAVE_ACCESSIBILITY
|
||||
|
@ -2292,39 +2114,17 @@ ifeq ($(HAVE_NETWORKING), 1)
|
|||
$(LIBRETRO_COMM_DIR)/net/net_socket.o \
|
||||
core_updater_list.o \
|
||||
network/natt.o \
|
||||
network/net_http_special.o \
|
||||
tasks/task_http.o \
|
||||
tasks/task_netplay_lan_scan.o \
|
||||
tasks/task_netplay_nat_traversal.o \
|
||||
tasks/task_pl_thumbnail_download.o \
|
||||
tasks/task_netplay_find_content.o
|
||||
|
||||
ifeq ($(HAVE_EMSCRIPTEN), 1)
|
||||
OBJ += tasks/task_http_emscripten.o
|
||||
else
|
||||
OBJ += tasks/task_http.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_MENU), 1)
|
||||
OBJ += tasks/task_pl_thumbnail_download.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
OBJ += tasks/task_core_updater.o
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Linux,$(OS)),)
|
||||
HAVE_CLOUDSYNC = 1
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Win,$(OS)),)
|
||||
HAVE_CLOUDSYNC = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CLOUDSYNC), 1)
|
||||
DEFINES += -DHAVE_CLOUDSYNC
|
||||
OBJ += tasks/task_cloudsync.o \
|
||||
network/cloud_sync/webdav.o \
|
||||
network/cloud_sync_driver.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_BUILTINBEARSSL), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/net/net_socket_ssl_bear.o
|
||||
else ifeq ($(HAVE_SSL), 1)
|
||||
|
@ -2353,27 +2153,15 @@ ifeq ($(HAVE_NETWORKING), 1)
|
|||
|
||||
# RetroAchievements
|
||||
ifeq ($(HAVE_CHEEVOS), 1)
|
||||
DEFINES += -DHAVE_CHEEVOS -DRC_CLIENT_SUPPORTS_HASH
|
||||
DEFINES += -DHAVE_CHEEVOS
|
||||
INCLUDE_DIRS += -Ideps/rcheevos/include
|
||||
|
||||
ifneq ($(HAVE_THREADS), 1)
|
||||
DEFINES += -DRC_NO_THREADS
|
||||
else ifneq (,$(filter GEKKO,$(CFLAGS)))
|
||||
# Gekko (Wii) and 3DS use custom pthread wrappers (see rthreads.c)
|
||||
DEFINES += -DRC_NO_THREADS
|
||||
else ifneq (,$(filter _3DS,$(CFLAGS)))
|
||||
DEFINES += -DRC_NO_THREADS
|
||||
endif
|
||||
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/cheevos_client.o \
|
||||
cheevos/cheevos_menu.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/cdfs/cdfs.o \
|
||||
deps/rcheevos/src/rc_client.o \
|
||||
deps/rcheevos/src/rc_compat.o \
|
||||
deps/rcheevos/src/rc_libretro.o \
|
||||
deps/rcheevos/src/rc_util.o \
|
||||
deps/rcheevos/src/rcheevos/alloc.o \
|
||||
deps/rcheevos/src/rcheevos/compat.o \
|
||||
deps/rcheevos/src/rcheevos/condition.o \
|
||||
deps/rcheevos/src/rcheevos/condset.o \
|
||||
deps/rcheevos/src/rcheevos/consoleinfo.o \
|
||||
|
@ -2381,20 +2169,15 @@ ifeq ($(HAVE_NETWORKING), 1)
|
|||
deps/rcheevos/src/rcheevos/lboard.o \
|
||||
deps/rcheevos/src/rcheevos/memref.o \
|
||||
deps/rcheevos/src/rcheevos/operand.o \
|
||||
deps/rcheevos/src/rcheevos/rc_libretro.o \
|
||||
deps/rcheevos/src/rcheevos/richpresence.o \
|
||||
deps/rcheevos/src/rcheevos/runtime.o \
|
||||
deps/rcheevos/src/rcheevos/runtime_progress.o \
|
||||
deps/rcheevos/src/rcheevos/trigger.o \
|
||||
deps/rcheevos/src/rcheevos/value.o \
|
||||
deps/rcheevos/src/rhash/aes.o \
|
||||
deps/rcheevos/src/rhash/cdreader.o \
|
||||
deps/rcheevos/src/rhash/hash.o \
|
||||
deps/rcheevos/src/rhash/hash_disc.o \
|
||||
deps/rcheevos/src/rhash/hash_encrypted.o \
|
||||
deps/rcheevos/src/rhash/hash_rom.o \
|
||||
deps/rcheevos/src/rhash/hash_zip.o \
|
||||
deps/rcheevos/src/rapi/rc_api_common.o \
|
||||
deps/rcheevos/src/rapi/rc_api_info.o \
|
||||
deps/rcheevos/src/rapi/rc_api_runtime.o \
|
||||
deps/rcheevos/src/rapi/rc_api_user.o \
|
||||
|
||||
|
@ -2492,7 +2275,9 @@ ifneq ($(findstring Win32,$(OS)),)
|
|||
gfx/display_servers/dispserv_win32.o
|
||||
|
||||
ifeq ($(HAVE_GDI), 1)
|
||||
OBJ += gfx/drivers/gdi_gfx.o
|
||||
OBJ += gfx/drivers/gdi_gfx.o \
|
||||
gfx/drivers_font/gdi_font.o \
|
||||
gfx/drivers_display/gfx_display_gdi.o
|
||||
LIBS += -lmsimg32
|
||||
endif
|
||||
LIBS += -lhid -lsetupapi
|
||||
|
@ -2512,7 +2297,7 @@ ifeq ($(HAVE_FFMPEG), 1)
|
|||
cores/libretro-ffmpeg/video_buffer.o \
|
||||
$(LIBRETRO_COMM_DIR)/rthreads/tpool.o
|
||||
|
||||
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(SWRESAMPLE_LIBS) $(FFMPEG_LIBS) $(AVDEVICE_LIBS)
|
||||
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(SWRESAMPLE_LIBS) $(FFMPEG_LIBS)
|
||||
DEFINES += -DHAVE_FFMPEG
|
||||
DEF_FLAGS += $(AVCODEC_CFLAGS) $(AVFORMAT_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS) $(SWRESAMPLE_CFLAGS) \
|
||||
-Wno-deprecated-declarations
|
||||
|
@ -2581,6 +2366,7 @@ endif
|
|||
|
||||
ifneq ($(findstring DOS,$(OS)),)
|
||||
OBJ += gfx/drivers/vga_gfx.o \
|
||||
gfx/drivers_font/vga_font.o \
|
||||
input/drivers/dos_input.o \
|
||||
input/drivers_joypad/dos_joypad.o \
|
||||
frontend/drivers/platform_dos.o
|
||||
|
@ -2609,7 +2395,6 @@ ifeq ($(HAVE_STATIC_VIDEO_FILTERS), 1)
|
|||
gfx/video_filters/dot_matrix_3x.o \
|
||||
gfx/video_filters/dot_matrix_4x.o \
|
||||
gfx/video_filters/upscale_1_5x.o \
|
||||
gfx/video_filters/upscale_1_66x_fast.o \
|
||||
gfx/video_filters/upscale_256x_320x240.o \
|
||||
gfx/video_filters/picoscale_256x_320x240.o \
|
||||
gfx/video_filters/upscale_240x160_320x240.o \
|
||||
|
@ -2640,22 +2425,18 @@ ifeq ($(WANT_LIBFAT), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_STATIC_AUDIO_FILTERS), 1)
|
||||
OBJ += libretro-common/audio/dsp_filters/chorus.o \
|
||||
libretro-common/audio/dsp_filters/crystalizer.o \
|
||||
libretro-common/audio/dsp_filters/echo.o \
|
||||
OBJ += libretro-common/audio/dsp_filters/echo.o \
|
||||
libretro-common/audio/dsp_filters/eq.o \
|
||||
libretro-common/audio/dsp_filters/chorus.o \
|
||||
libretro-common/audio/dsp_filters/iir.o \
|
||||
libretro-common/audio/dsp_filters/panning.o \
|
||||
libretro-common/audio/dsp_filters/phaser.o \
|
||||
libretro-common/audio/dsp_filters/reverb.o \
|
||||
libretro-common/audio/dsp_filters/tremolo.o \
|
||||
libretro-common/audio/dsp_filters/vibrato.o \
|
||||
libretro-common/audio/dsp_filters/wahwah.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RPILED), 1)
|
||||
OBJ += led/drivers/led_rpi.o \
|
||||
led/drivers/led_sys_linux.o
|
||||
OBJ += led/drivers/led_rpi.o
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
|
@ -2677,13 +2458,6 @@ ifeq ($(HAVE_WEBOS), 1)
|
|||
DEFINES += -DWEBOS
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_TEST_DRIVERS), 1)
|
||||
DEFINES += -DHAVE_TEST_DRIVERS
|
||||
OBJ += input/drivers_joypad/test_joypad.o
|
||||
OBJ += input/drivers/test_input.o
|
||||
endif
|
||||
|
||||
|
||||
#####################################
|
||||
### Android Play Feature Delivery ###
|
||||
### (Play Store build core ###
|
||||
|
@ -2757,36 +2531,4 @@ ifeq ($(HAVE_ODROIDGO2), 1)
|
|||
gfx/drivers/oga_gfx.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_GAME_AI),1)
|
||||
DEFINES += -DHAVE_GAME_AI
|
||||
OBJ += ai/game_ai.o
|
||||
endif
|
||||
|
||||
# Detect the operating system
|
||||
UNAME := $(shell uname -s)
|
||||
|
||||
# Check if the system is MSYS2 (MINGW64 or MINGW32)
|
||||
ifneq ($(findstring MINGW,$(UNAME)),)
|
||||
$(info Detected MSYS2 environment)
|
||||
|
||||
NT_VERSION := $(shell \
|
||||
echo '#include <windows.h>' > temp.c; \
|
||||
echo '#ifdef _WIN32_WINNT' >> temp.c; \
|
||||
echo '#define GET_MACRO_VALUE(x) #x' >> temp.c; \
|
||||
echo '#define EXPAND_MACRO_VALUE(x) GET_MACRO_VALUE(x)' >> temp.c; \
|
||||
echo '#pragma message("_WIN32_WINNT=" EXPAND_MACRO_VALUE(_WIN32_WINNT))' >> temp.c; \
|
||||
echo '#endif' >> temp.c; \
|
||||
$(CC) -c temp.c 2>&1 | sed -n 's/^.*_WIN32_WINNT=\(0x[0-9A-Fa-f]\+\).*/\1/p'; \
|
||||
rm -f temp.c temp.o)
|
||||
|
||||
ifneq ($(NT_VERSION),)
|
||||
ifeq ($(shell [ $$(( $(NT_VERSION) )) -gt $$(( 0x602 )) ] && echo true),true)
|
||||
LIBS += -lxaudio2_9
|
||||
endif
|
||||
else
|
||||
$(warning Windows NT version macro (_WIN32_WINNT) is not defined.)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
##################################
|
||||
|
|
123
Makefile.ctr
123
Makefile.ctr
|
@ -3,7 +3,7 @@ LIBRETRO =
|
|||
|
||||
DEBUG = 0
|
||||
CONSOLE_LOG = 0
|
||||
GRIFFIN_BUILD = 0
|
||||
GRIFFIN_BUILD = 1
|
||||
HAVE_STATIC_DUMMY ?= 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
BUILD_3DSX = 1
|
||||
|
@ -56,7 +56,6 @@ ifeq ($(GRIFFIN_BUILD), 1)
|
|||
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_XMB -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER
|
||||
DEFINES += -DHAVE_ZLIB -DHAVE_7ZIP -D_7ZIP_ST -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA
|
||||
DEFINES += -DHAVE_NETWORKING -DHAVE_IFINFO -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_CORES
|
||||
DEFINES += -DHAVE_UPDATE_CORE_INFO
|
||||
#DEFINES += -DHAVE_UPDATE_ASSETS
|
||||
DEFINES += -DHAVE_PATCH -DHAVE_RWAV
|
||||
DEFINES += -DHAVE_SCREENSHOTS
|
||||
|
@ -89,22 +88,21 @@ else
|
|||
HAVE_REWIND = 1
|
||||
HAVE_AUDIOMIXER = 1
|
||||
HAVE_RWAV = 1
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_DSP_FILTER = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_GFX_WIDGETS = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_IFINFO = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
#HAVE_NETWORKING = 1
|
||||
#HAVE_IFINFO = 1
|
||||
#HAVE_CHEEVOS = 1
|
||||
#HAVE_SOCKET_LEGACY = 1
|
||||
HAVE_THREADS = 1
|
||||
HAVE_BUILTINMBEDTLS = 1
|
||||
#HAVE_SSL = 1
|
||||
#HAVE_BUILTINMBEDTLS = 1
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
HAVE_CLOUDSYNC = 1
|
||||
|
||||
include Makefile.common
|
||||
CFLAGS += $(DEF_FLAGS)
|
||||
BLACKLIST :=
|
||||
BLACKLIST += input/input_overlay.o
|
||||
BLACKLIST += tasks/task_overlay.o
|
||||
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
|
@ -154,7 +152,12 @@ LIBDIRS := -L. -L$(CTRULIB)/lib
|
|||
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
|
||||
|
||||
CFLAGS += -mword-relocations $(ARCH)
|
||||
CFLAGS += -mword-relocations \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
-Werror=implicit-function-declaration \
|
||||
$(ARCH)
|
||||
|
||||
#CFLAGS += -Wall
|
||||
CFLAGS += -DARM11 -D_3DS
|
||||
|
||||
ifeq ($(strip $(USE_CTRULIB_2)),1)
|
||||
|
@ -164,7 +167,7 @@ endif
|
|||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
CFLAGS += -fomit-frame-pointer -O3
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifeq ($(CONSOLE_LOG), 1)
|
||||
|
@ -184,21 +187,21 @@ CFLAGS += -I. \
|
|||
-Ideps \
|
||||
-Ideps/7zip \
|
||||
-Ideps/stb \
|
||||
-Ideps/mbedtls \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ilibretro-common/include \
|
||||
-Ilibretro-common/include/compat/zlib
|
||||
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
|
||||
CFLAGS += -DHAVE_DSP_FILTER
|
||||
CFLAGS += -DHAVE_VIDEO_FILTER
|
||||
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
|
||||
CFLAGS += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_CORES -DHAVE_UPDATE_CORE_INFO
|
||||
CFLAGS += -DHAVE_CHEATS
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
CFLAGS += -Werror=implicit-function-declaration
|
||||
|
||||
ASFLAGS := -g $(ARCH) -O3
|
||||
LDFLAGS += -specs=ctr/3dsx_custom.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -std=gnu99 -ffast-math
|
||||
|
||||
LIB_CORE :=
|
||||
LIB_CORE_FULL :=
|
||||
|
@ -218,10 +221,6 @@ else
|
|||
LIBS += -lctru
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_3DSX), 1)
|
||||
TARGET_3DSX := $(TARGET).3dsx $(TARGET).smdh
|
||||
endif
|
||||
|
@ -234,7 +233,16 @@ ifeq ($(BUILD_CIA), 1)
|
|||
TARGET_CIA := $(TARGET).cia
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(TARGET_3DSX) $(TARGET_3DS) $(TARGET_CIA)
|
||||
$(TARGET).3dsx: $(TARGET).elf
|
||||
$(TARGET).elf: $(OBJ) $(LIB_CORE_FULL)
|
||||
|
||||
PREFIX := $(DEVKITARM)/bin/arm-none-eabi-
|
||||
|
||||
CC := $(PREFIX)gcc
|
||||
CXX := $(PREFIX)g++
|
||||
AS := $(PREFIX)as
|
||||
|
@ -268,36 +276,6 @@ else
|
|||
MAKEROM = $(CTRMAKEROM)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
define INFO
|
||||
AR: $(AR)
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
INCDIRS: $(INCDIRS)
|
||||
LD: $(LD)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
OBJ: $(OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
|
||||
$(TARGET): $(TARGET_3DSX) $(TARGET_3DS) $(TARGET_CIA)
|
||||
$(TARGET).3dsx: $(TARGET).elf
|
||||
$(TARGET).elf: $(OBJ) $(LIB_CORE_FULL)
|
||||
|
||||
%.o: %.vsh %.gsh
|
||||
$(DEVKITTOOLS)/bin/picasso $^ -o $*.shbin
|
||||
$(DEVKITTOOLS)/bin/bin2s $*.shbin | $(PREFIX)as -o $@
|
||||
|
@ -309,24 +287,19 @@ $(TARGET).elf: $(OBJ) $(LIB_CORE_FULL)
|
|||
rm $*.shbin
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
|
||||
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
|
||||
|
||||
%.o: %.s
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(ASFLAGS)
|
||||
$(CC) -c -o $@ $< $(ASFLAGS)
|
||||
|
||||
%.o: %.S
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(ASFLAGS)
|
||||
$(CC) -c -o $@ $< $(ASFLAGS)
|
||||
|
||||
%.a:
|
||||
@$(if $(Q), $(shell echo echo AR $<),)
|
||||
$(Q)$(AR) -rc $@ $^
|
||||
$(AR) -rc $@ $^
|
||||
|
||||
%.vsh:
|
||||
|
||||
|
@ -342,8 +315,7 @@ endif
|
|||
$(DEVKITTOOLS)/bin/3dsxtool $< $@ $(_3DSXFLAGS)
|
||||
|
||||
$(TARGET).elf: ctr/3dsx_custom_crt0.o
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) $(LDFLAGS) $(OBJ) $(LIBDIRS) $(LIBS) -o $@
|
||||
$(LD) $(LDFLAGS) $(OBJ) $(LIBDIRS) $(LIBS) -o $@
|
||||
$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(TARGET).bnr: $(TARGET).elf $(APP_BANNER) $(APP_AUDIO)
|
||||
|
@ -359,16 +331,15 @@ $(TARGET).cia: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
|
|||
$(MAKEROM) -f cia -o $@ $(MAKEROM_ARGS_COMMON) -DAPP_ENCRYPTED=false
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -f $(OBJ)
|
||||
$(Q)rm -f $(TARGET).3dsx
|
||||
$(Q)rm -f $(TARGET).elf
|
||||
$(Q)rm -f $(TARGET).3ds
|
||||
$(Q)rm -f $(TARGET).cia
|
||||
$(Q)rm -f $(TARGET).smdh
|
||||
$(Q)rm -f $(TARGET).bnr
|
||||
$(Q)rm -f $(TARGET).icn
|
||||
$(Q)rm -f ctr/ctr_config_*.o
|
||||
$(Q)rm -f ctr/3dsx_custom_crt0.o
|
||||
rm -f $(OBJ)
|
||||
rm -f $(TARGET).3dsx
|
||||
rm -f $(TARGET).elf
|
||||
rm -f $(TARGET).3ds
|
||||
rm -f $(TARGET).cia
|
||||
rm -f $(TARGET).smdh
|
||||
rm -f $(TARGET).bnr
|
||||
rm -f $(TARGET).icn
|
||||
rm -f ctr/ctr_config_*.o
|
||||
rm -f ctr/3dsx_custom_crt0.o
|
||||
|
||||
.PHONY: clean
|
||||
|
|
|
@ -83,7 +83,12 @@ LIBDIRS := -L. -L$(CTRULIB)/lib
|
|||
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
|
||||
|
||||
CFLAGS += -mword-relocations -fomit-frame-pointer $(ARCH)
|
||||
CFLAGS += -mword-relocations \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
-Werror=implicit-function-declaration \
|
||||
$(ARCH)
|
||||
|
||||
#CFLAGS += -Wall
|
||||
CFLAGS += -DARM11 -D_3DS
|
||||
|
||||
ifeq ($(strip $(USE_CTRULIB_2)),1)
|
||||
|
@ -106,12 +111,11 @@ CFLAGS += -I. -Ideps/7zip -Ideps/stb -Ilibretro-common/include -Ilibretro-common
|
|||
CFLAGS += -DRARCH_CONSOLE -DIS_SALAMANDER
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
CFLAGS += -Werror=implicit-function-declaration
|
||||
|
||||
ASFLAGS := -g $(ARCH) -O3
|
||||
LDFLAGS += -specs=ctr/3dsx_custom.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -std=gnu99 -ffast-math
|
||||
|
||||
LIBS := -lctru -lm
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ HAVE_STRCASESTR = 1
|
|||
HAVE_THREADS = 1
|
||||
HAVE_TRANSLATE = 1
|
||||
HAVE_UDEV = 1
|
||||
HAVE_VIDEO_LAYOUT = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
|
@ -107,7 +108,7 @@ OPK_NAME = retroarch.opk
|
|||
|
||||
OBJ :=
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS := -march=mips32 -mtune=mips32r2 -mhard-float -fomit-frame-pointer
|
||||
DEF_FLAGS := -march=mips32 -mtune=mips32r2 -mhard-float -ffast-math -fomit-frame-pointer
|
||||
DEF_FLAGS += -mplt -mno-shared
|
||||
DEF_FLAGS += -ffunction-sections -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DDINGUX=1 -MMD
|
||||
|
|
47
Makefile.dos
47
Makefile.dos
|
@ -47,7 +47,6 @@ HAVE_DSP_FILTER = 1
|
|||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
HAVE_STATIC_CORES = 1
|
||||
HAVE_FILTERS_BUILTIN = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
|
@ -63,11 +62,10 @@ HAVE_COMMAND := 1
|
|||
HAVE_STDIN_CMD := 1
|
||||
HAVE_CMD := 1
|
||||
HAVE_CHEEVOS = 0
|
||||
HAVE_CHD = 1
|
||||
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
||||
HAVE_STB_VORBIS = 1
|
||||
HAVE_IBXM = 1
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
HAVE_XDELTA = 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 0
|
||||
|
@ -77,9 +75,8 @@ HAVE_OZONE = 0
|
|||
|
||||
OBJ := \
|
||||
frontend/drivers/platform_dos.o \
|
||||
gfx/drivers/vga_gfx.o \
|
||||
input/drivers/dos_input.o \
|
||||
input/drivers_joypad/dos_joypad.o
|
||||
gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o \
|
||||
input/drivers/dos_input.o input/drivers_joypad/dos_joypad.o
|
||||
|
||||
include Makefile.common
|
||||
|
||||
|
@ -120,7 +117,7 @@ APP_ICON := pkg/libnx/retroarch.jpg
|
|||
#---------------------------------------------------------------------------------
|
||||
ARCH :=
|
||||
|
||||
CFLAGS := -g -Wall -O3 -fcommon -ffunction-sections \
|
||||
CFLAGS := -g -Wall -O3 -fcommon -ffast-math -ffunction-sections \
|
||||
$(ARCH) $(DEFINES) $(INCLUDE_DIRS)
|
||||
|
||||
CFLAGS += $(INCLUDE)
|
||||
|
@ -195,10 +192,6 @@ else
|
|||
LIB_CORE += -lretro_dos
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
DEPENDS_TMP := $(OFILES:.o=.d)
|
||||
DEPENDS := $(filter-out libretro_libnx.a,$(DEPENDS_TMP))
|
||||
|
||||
|
@ -209,41 +202,17 @@ DEPENDS := $(filter-out libretro_libnx.a,$(DEPENDS_TMP))
|
|||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT)
|
||||
|
||||
define INFO
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
DEPENDS: $(DEPENDS)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
LIB_CORE: $(LIB_CORE)
|
||||
OBJ: $(OBJ)
|
||||
OUTPUT: $(OUTPUT)
|
||||
PLATEXTRA: $(PLATEXTRA)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
$(OUTPUT): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(PLATEXTRA) -L. $(LIB_CORE) $(LIBS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(PLATEXTRA) -L. $(LIB_CORE) $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $(CFLAGS) $<
|
||||
$(CC) -c -o $@ $(CFLAGS) $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) -c -o $@ $(CFLAGS) $<
|
||||
$(CXX) -c -o $@ $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), $(shell echo echo RM),)
|
||||
$(Q)rm -f $(DEPENDS) $(OBJ) $(OUTPUT)
|
||||
rm -f $(DEPENDS) $(OBJ) $(OUTPUT)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
|
|
|
@ -2,38 +2,35 @@ HAVE_STATIC_DUMMY ?= 0
|
|||
ifeq ($(TARGET),)
|
||||
ifeq ($(LIBRETRO),)
|
||||
TARGET := retroarch.js
|
||||
LIBRETRO = dummy
|
||||
else
|
||||
TARGET := $(LIBRETRO)_libretro.js
|
||||
endif
|
||||
endif
|
||||
TARGET_BASE := $(subst .js,,$(TARGET))
|
||||
|
||||
EOPT = USE_ZLIB=1 # Emscripten specific options
|
||||
EOPTS = $(addprefix -s $(EMPTY), $(EOPT)) # Add '-s ' to each option
|
||||
|
||||
PTHREAD = 0
|
||||
OS = Emscripten
|
||||
OBJ :=
|
||||
DEFINES := -DRARCH_INTERNAL -DHAVE_MAIN -DEMSCRIPTEN
|
||||
DEFINES += -DHAVE_FILTERS_BUILTIN -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORE_INFO
|
||||
DEFINES := -DRARCH_INTERNAL -DHAVE_MAIN -s USE_PTHREADS=$(PTHREAD)
|
||||
DEFINES += -DHAVE_FILTERS_BUILTIN
|
||||
|
||||
HAVE_PATCH = 1
|
||||
HAVE_DSP_FILTER = 1
|
||||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_NETWORKING ?= 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_COMPRESSION = 1
|
||||
HAVE_UPDATE_ASSETS = 1
|
||||
HAVE_ONLINE_UPDATER = 1
|
||||
HAVE_GLSL = 1
|
||||
HAVE_SCREENSHOTS = 1
|
||||
HAVE_REWIND = 1
|
||||
HAVE_AUDIOMIXER = 1
|
||||
HAVE_CC_RESAMPLER ?= 1
|
||||
HAVE_EGL ?= 0
|
||||
HAVE_VIDEO_LAYOUT = 0
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
HAVE_EGL = 1
|
||||
HAVE_OPENGLES = 1
|
||||
HAVE_RJPEG = 0
|
||||
HAVE_RPNG = 1
|
||||
HAVE_EMSCRIPTEN = 1
|
||||
HAVE_MENU ?= 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_GFX_WIDGETS = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_SDL = 0
|
||||
|
@ -44,115 +41,41 @@ HAVE_STATIC_VIDEO_FILTERS = 1
|
|||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_COMMAND = 1
|
||||
HAVE_STDIN_CMD ?= 1
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_IBXM = 1
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BSV_MOVIE = 1
|
||||
HAVE_CHD ?= 0
|
||||
HAVE_NETPLAYDISCOVERY ?= 0
|
||||
|
||||
# enables pthreads, requires special headers on the web server:
|
||||
# see https://web.dev/articles/coop-coep
|
||||
HAVE_THREADS ?= 0
|
||||
|
||||
# requires HAVE_THREADS
|
||||
HAVE_AUDIOWORKLET ?= 0
|
||||
|
||||
# doesn't work on PROXY_TO_PTHREAD
|
||||
HAVE_RWEBAUDIO ?= 1
|
||||
|
||||
# requires ASYNC or PROXY_TO_PTHREAD
|
||||
HAVE_AL ?= 0
|
||||
|
||||
# whether the browser thread is allowed to block to wait for audio to play, not CPU usage-friendly!
|
||||
# currently this variable is only used by rwebaudio and audioworklet; openal will never busywait.
|
||||
ALLOW_AUDIO_BUSYWAIT ?= 0
|
||||
|
||||
# minimal asyncify; better performance than full asyncify,
|
||||
# but sleeping on the main thread is only possible in some places.
|
||||
MIN_ASYNC ?= 0
|
||||
|
||||
# runs RetroArch on a pthread instead of the browser thread; requires HAVE_THREADS
|
||||
PROXY_TO_PTHREAD ?= 0
|
||||
|
||||
# recommended FS when using HAVE_THREADS
|
||||
HAVE_WASMFS ?= 0
|
||||
|
||||
# enables OPFS (origin private file system) and FETCHFS, requires PROXY_TO_PTHREAD
|
||||
HAVE_EXTRA_WASMFS ?= 0
|
||||
|
||||
# enable javascript filesystem tracking, incompatible with HAVE_WASMFS
|
||||
FS_DEBUG ?= 0
|
||||
|
||||
# help diagnose GL problems (can cause issues in normal operation)
|
||||
GL_DEBUG ?= 0
|
||||
|
||||
# does nothing on its own, but automatically selected by some other options
|
||||
WASM_WORKERS = 0
|
||||
|
||||
HAVE_OPENGLES ?= 1
|
||||
HAVE_OPENGLES3 ?= 0
|
||||
|
||||
ASYNC ?= 0
|
||||
ifeq ($(LIBRETRO), mupen64plus)
|
||||
ASYNC = 1
|
||||
endif
|
||||
|
||||
LTO ?= 0
|
||||
PTHREAD_POOL_SIZE ?= 4
|
||||
ifeq ($(LIBRETRO), tyrquake)
|
||||
LTO = 0
|
||||
endif
|
||||
|
||||
ASYNCIFY_ADD ?= dynCall_*,emscripten_mainloop
|
||||
ASYNCIFY_REMOVE ?= threaded_worker
|
||||
MEMORY ?= 134217728
|
||||
|
||||
STACK_SIZE ?= 4194304
|
||||
INITIAL_HEAP ?= 134217728
|
||||
|
||||
# 4194304 ----- 4 MiB (Stack: recommended)
|
||||
# 8388608 ----- 8 MiB
|
||||
# 16777216 ---- 16 MiB
|
||||
# 33554432 ---- 32 MiB
|
||||
# 67108864 ---- 64 MiB
|
||||
# 134217728 --- 128 MiB (Heap: recommended) (Stack: recommended for some cores [mupen64plus_next])
|
||||
# 268435456 --- 256 MiB (Heap: recommended for some cores [mupen64plus_next])
|
||||
# 536870912 --- 512 MiB (Heap: needed for some cores [mednafen_psx(_hw)])
|
||||
# 1073741824 -- 1 GiB
|
||||
# 1610612736 -- 1.5 GiB
|
||||
# 2147483648 -- 2 GiB
|
||||
PRECISE_F32 = 1
|
||||
|
||||
OBJDIR := obj-emscripten
|
||||
|
||||
EXPORTED_FUNCTIONS = _main,_malloc,_free,_cmd_savefiles,_cmd_save_state,_cmd_load_state,_cmd_undo_save_state,_cmd_undo_load_state,_cmd_toggle_fullscreen,_cmd_take_screenshot,\
|
||||
_cmd_toggle_menu,_cmd_reload_config,_cmd_toggle_grab_mouse,_cmd_toggle_game_focus,_cmd_reset,_cmd_toggle_pause,_cmd_pause,_cmd_unpause,\
|
||||
_cmd_set_volume,_cmd_set_shader,_cmd_cheat_set_code,_cmd_cheat_get_code,_cmd_cheat_toggle_index,_cmd_cheat_get_code_state,_cmd_cheat_realloc,\
|
||||
_cmd_cheat_get_size,_cmd_cheat_apply_cheats,EmscriptenSendCommand,EmscriptenReceiveCommandReply
|
||||
|
||||
EXPORTS := callMain,FS,PATH,ERRNO_CODES,ENV,stringToNewUTF8,UTF8ToString,Browser,EmscriptenSendCommand,EmscriptenReceiveCommandReply
|
||||
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
|
||||
|
||||
LIBS := -s USE_ZLIB=1
|
||||
CFLAGS := -s USE_ZLIB=1
|
||||
|
||||
ifeq ($(HAVE_EXTRA_WASMFS), 1)
|
||||
LIBS += -lfetchfs.js -lopfs.js
|
||||
DEFINES += -DHAVE_EXTRA_WASMFS
|
||||
override HAVE_WASMFS = 1
|
||||
ifeq ($(PROXY_TO_PTHREAD), 0)
|
||||
$(error ERROR: HAVE_EXTRA_WASMFS requires PROXY_TO_PTHREAD)
|
||||
endif
|
||||
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
||||
--js-library emscripten/library_rwebaudio.js \
|
||||
--js-library emscripten/library_rwebcam.js \
|
||||
--js-library emscripten/library_errno_codes.js
|
||||
ifneq ($(PTHREAD), 0)
|
||||
LDFLAGS += -s USE_PTHREADS=$(PTHREAD) -s PTHREAD_POOL_SIZE=2
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_WASMFS), 1)
|
||||
LIBS += -s WASMFS -s FORCE_FILESYSTEM=1
|
||||
endif
|
||||
|
||||
# note: real PROXY_TO_PTHREAD is not used here; we do the pthread management ourselves
|
||||
ifeq ($(PROXY_TO_PTHREAD), 1)
|
||||
LIBS += -s OFFSCREENCANVAS_SUPPORT
|
||||
DEFINES += -DPROXY_TO_PTHREAD -DEMSCRIPTEN_STACK_SIZE=$(STACK_SIZE)
|
||||
override HAVE_THREADS = 1
|
||||
override WASM_WORKERS = 1
|
||||
# use the default stack size for the browser thread; the RetroArch thread will be created with the specified stack size
|
||||
override STACK_SIZE = 4194304
|
||||
else ifeq ($(HAVE_AL), 1)
|
||||
override ASYNC = 1
|
||||
ifeq ($(ASYNC), 1)
|
||||
LDFLAGS += -s ASYNCIFY=$(ASYNC)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
|
@ -160,119 +83,16 @@ ifeq ($(HAVE_SDL2), 1)
|
|||
DEFINES += -DHAVE_SDL2
|
||||
endif
|
||||
|
||||
LDFLAGS := -L. --no-heap-copy -s STACK_SIZE=$(STACK_SIZE) -s INITIAL_MEMORY=$(INITIAL_HEAP) \
|
||||
-s EXPORTED_RUNTIME_METHODS=$(EXPORTS) \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="$(EXPORTED_FUNCTIONS)" \
|
||||
-s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME="libretro_$(subst -,_,$(LIBRETRO))" \
|
||||
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 \
|
||||
-s ENVIRONMENT=web,worker -s WASM_BIGINT=1 \
|
||||
--extern-pre-js emscripten/pre.js \
|
||||
--js-library emscripten/library_rwebcam.js \
|
||||
--js-library emscripten/library_platform_emscripten.js
|
||||
|
||||
ifeq ($(HAVE_OPENGLES), 1)
|
||||
ifeq ($(HAVE_OPENGLES3), 1)
|
||||
LDFLAGS += -s FULL_ES3=1 -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2
|
||||
else
|
||||
LDFLAGS += -s FULL_ES2=1 -s MIN_WEBGL_VERSION=1 -s MAX_WEBGL_VERSION=2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(GL_DEBUG), 1)
|
||||
LDFLAGS += -s GL_ASSERTIONS=1 -s GL_DEBUG=1
|
||||
DEFINES += -DHAVE_GL_DEBUG_ES=1
|
||||
endif
|
||||
|
||||
ifeq ($(FS_DEBUG), 1)
|
||||
LDFLAGS += -s FS_DEBUG=1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RWEBAUDIO), 1)
|
||||
LDFLAGS += --js-library emscripten/library_rwebaudio.js
|
||||
DEFINES += -DHAVE_RWEBAUDIO
|
||||
ifeq ($(PROXY_TO_PTHREAD), 1)
|
||||
$(error ERROR: RWEBAUDIO is incompatible with PROXY_TO_PTHREAD)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AUDIOWORKLET), 1)
|
||||
LDFLAGS += -s AUDIO_WORKLET=1
|
||||
DEFINES += -DHAVE_AUDIOWORKLET
|
||||
override WASM_WORKERS = 1
|
||||
ifeq ($(HAVE_THREADS), 0)
|
||||
$(error ERROR: AUDIOWORKLET requires HAVE_THREADS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AL), 1)
|
||||
LDFLAGS += -lopenal
|
||||
DEFINES += -DHAVE_AL
|
||||
endif
|
||||
|
||||
ifeq ($(PROXY_TO_PTHREAD), 1)
|
||||
else ifeq ($(ASYNC), 1)
|
||||
else
|
||||
DEFINES += -DEMSCRIPTEN_AUDIO_EXTERNAL_BLOCK
|
||||
ifeq ($(MIN_ASYNC), 1)
|
||||
DEFINES += -DEMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
||||
else
|
||||
DEFINES += -DEMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||
endif
|
||||
ifneq ($(ALLOW_AUDIO_BUSYWAIT), 1)
|
||||
DEFINES += -DEMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ALLOW_AUDIO_BUSYWAIT), 1)
|
||||
DEFINES += -DEMSCRIPTEN_AUDIO_BUSYWAIT
|
||||
endif
|
||||
|
||||
# explanation of some of these defines:
|
||||
# EMSCRIPTEN_AUDIO_EXTERNAL_BLOCK: audio blocking occurs in the main loop instead of in the audio driver functions.
|
||||
# EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK: along with above, enables external blocking in the write function.
|
||||
# EMSCRIPTEN_AUDIO_BUSYWAIT: write function will busywait. init function may still use an external block.
|
||||
# EMSCRIPTEN_AUDIO_ASYNC_BLOCK: external block uses emscripten_sleep (requires MIN_ASYNC).
|
||||
# EMSCRIPTEN_AUDIO_FAKE_BLOCK: external block uses main loop timing (doesn't require asyncify).
|
||||
# when building with either PROXY_TO_PTHREAD or ASYNC (full asyncify), none of the above are required.
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
LDFLAGS += -pthread -s PTHREAD_POOL_SIZE=$(PTHREAD_POOL_SIZE)
|
||||
CFLAGS += -pthread -s SHARED_MEMORY
|
||||
endif
|
||||
|
||||
ifeq ($(WASM_WORKERS), 1)
|
||||
LDFLAGS += -s WASM_WORKERS=1
|
||||
endif
|
||||
|
||||
ifeq ($(ASYNC), 1)
|
||||
DEFINES += -DEMSCRIPTEN_ASYNCIFY -DEMSCRIPTEN_FULL_ASYNCIFY
|
||||
LDFLAGS += -s ASYNCIFY=1 -s ASYNCIFY_STACK_SIZE=8192
|
||||
ifeq ($(DEBUG), 1)
|
||||
#LDFLAGS += -s ASYNCIFY_DEBUG=1 # broken?
|
||||
endif
|
||||
else ifeq ($(MIN_ASYNC), 1)
|
||||
DEFINES += -DEMSCRIPTEN_ASYNCIFY -DEMSCRIPTEN_MIN_ASYNCIFY
|
||||
LDFLAGS += -s ASYNCIFY=1 -s ASYNCIFY_STACK_SIZE=8192 -s ASYNCIFY_IGNORE_INDIRECT=1 -s ASYNCIFY_ADD='$(ASYNCIFY_ADD)' -s ASYNCIFY_REMOVE='$(ASYNCIFY_REMOVE)'
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -s ASYNCIFY_ADVISE #-s ASYNCIFY_DEBUG=1
|
||||
endif
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
||||
DEF_FLAGS += $(INCLUDE_DIRS) -Ideps -Ideps/stb
|
||||
CFLAGS += $(DEF_FLAGS) -Ideps -Ideps/stb
|
||||
|
||||
CFLAGS += $(DEF_FLAGS)
|
||||
CXXFLAGS += $(DEF_FLAGS) -D__STDC_CONSTANT_MACROS
|
||||
|
||||
libretro =
|
||||
libretro_new =
|
||||
libretro :=
|
||||
|
||||
ifeq ($(HAVE_STATIC_DUMMY),1)
|
||||
DEFINES += -DHAVE_STATIC_DUMMY
|
||||
else
|
||||
libretro = libretro_emscripten.bc
|
||||
libretro_new = libretro_emscripten.a
|
||||
libretro += libretro_emscripten.bc
|
||||
endif
|
||||
|
||||
ifneq ($(V), 1)
|
||||
|
@ -280,45 +100,41 @@ ifneq ($(V), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=2 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
|
||||
# -O0 in cflags gives "too many locals" errors
|
||||
CFLAGS += -O1 -g -gsource-map
|
||||
LDFLAGS += -O0 -g
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
LDFLAGS += -O3
|
||||
LDFLAGS += -O3 -s WASM=1
|
||||
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
||||
LDFLAGS += -s PRECISE_F32=$(PRECISE_F32)
|
||||
ifeq ($(LTO), 1)
|
||||
LDFLAGS += -flto
|
||||
LDFLAGS += --llvm-lto 3
|
||||
endif
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -I. -Ilibretro-common/include -Ideps/7zip -std=gnu99
|
||||
CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 $(LIBS) \
|
||||
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(libretro_new): ;
|
||||
|
||||
mv_libretro:
|
||||
$(Q)mv -f $(libretro) $(libretro_new) || true
|
||||
|
||||
$(TARGET): $(RARCH_OBJ) $(libretro_new) mv_libretro
|
||||
@$(if $(Q), $(shell echo echo "LD $@ \<obj\> $(libretro_new) $(LIBS) $(LDFLAGS)"),)
|
||||
$(Q)$(LD) -o $@ $(RARCH_OBJ) $(libretro_new) $(LIBS) $(LDFLAGS)
|
||||
$(TARGET): $(RARCH_OBJ) $(libretro)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) -o $@ $(RARCH_OBJ) $(libretro) $(LIBS) $(LDFLAGS)
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) $(EOPTS) -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $<
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) $(EOPTS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR)
|
||||
rm -f $(TARGET)
|
||||
|
||||
.PHONY: all clean mv_libretro
|
||||
.PHONY: all clean
|
||||
|
|
|
@ -116,7 +116,6 @@ else ifeq ($(platform), ps3-cobra)
|
|||
# NGC/Wii - libogc
|
||||
else ifeq ($(libogc_platform), 1)
|
||||
EXTERNAL_LIBOGC ?= 0
|
||||
HAVE_OGG_OGC ?= 0
|
||||
GX_PTHREAD_LEGACY ?= 1
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
|
@ -184,10 +183,6 @@ else ifeq ($(libogc_platform), 1)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OGG_OGC), 1)
|
||||
LIBS += -L$(DEVKITPRO)/portlibs/ppc/lib -lvorbisfile -lvorbis -logg
|
||||
endif
|
||||
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
LIBS += -lfat
|
||||
endif
|
||||
|
@ -219,6 +214,7 @@ else ifeq ($(libogc_platform), 1)
|
|||
HAVE_RTGA := 1
|
||||
HAVE_IBXM := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_ZLIB := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_CONFIGFILE := 1
|
||||
|
@ -352,6 +348,7 @@ else ifeq ($(platform), vita)
|
|||
HAVE_IFINFO := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -374,6 +371,7 @@ else ifeq ($(platform), windows_msvc6_x86)
|
|||
HAVE_NETWORK_CMD := 0
|
||||
HAVE_NETPLAYDISCOVERY := 0
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -421,6 +419,7 @@ else ifeq ($(platform), windows_msvc2003_x86)
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -476,6 +475,7 @@ else ifeq ($(platform), windows_msvc2005_x86)
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_OZONE := 1
|
||||
|
@ -509,9 +509,7 @@ else ifeq ($(platform), windows_msvc2005_x86)
|
|||
|
||||
PLATCFLAGS += -D_WIN32 -D_WIN32_WINNT=0x0410 -D__STDC_CONSTANT_MACROS -D_MBCS
|
||||
PLATCFLAGS += -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_OZONE -DHAVE_GFX_WIDGETS -DHAVE_CC_RESAMPLER
|
||||
PLATCFLAGS += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DHAVE_CDROM
|
||||
PLATCFLAGS += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_CDROM
|
||||
PLATCFLAGS += -bigobj
|
||||
|
||||
LDFLAGS += -MANIFEST shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib msimg32.lib
|
||||
|
@ -560,6 +558,7 @@ else ifneq (,$(findstring windows_msvc2010,$(platform)))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_OZONE := 1
|
||||
|
@ -595,9 +594,7 @@ else ifneq (,$(findstring windows_msvc2010,$(platform)))
|
|||
PLATCFLAGS += -D__i686__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS
|
||||
PLATCFLAGS += -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA
|
||||
PLATCFLAGS += -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_OZONE
|
||||
PLATCFLAGS += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DWIN32 -DHAVE_CDROM
|
||||
PLATCFLAGS += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
|
||||
PLATCFLAGS += -DHAVE_GFX_WIDGETS
|
||||
PLATCFLAGS += -bigobj
|
||||
|
||||
|
@ -656,6 +653,7 @@ else ifneq (,$(findstring windows_msvc2012,$(platform)))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -681,9 +679,7 @@ else ifneq (,$(findstring windows_msvc2012,$(platform)))
|
|||
LD = link.exe
|
||||
|
||||
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DWIN32 -DHAVE_CDROM
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
|
||||
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
|
||||
|
||||
PlatformSuffix = $(subst windows_msvc2012_,,$(platform))
|
||||
|
@ -743,6 +739,7 @@ else ifneq (,$(findstring windows_msvc2013,$(platform)))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -768,9 +765,7 @@ else ifneq (,$(findstring windows_msvc2013,$(platform)))
|
|||
LD = link.exe
|
||||
|
||||
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DWIN32 -DHAVE_CDROM
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
|
||||
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
|
||||
|
||||
PlatformSuffix = $(subst windows_msvc2013_,,$(platform))
|
||||
|
@ -830,6 +825,7 @@ else ifneq (,$(findstring windows_msvc2015,$(platform)))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -856,9 +852,7 @@ else ifneq (,$(findstring windows_msvc2015,$(platform)))
|
|||
|
||||
PLATCFLAGS += -utf-8
|
||||
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DWIN32 -DHAVE_CDROM
|
||||
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
|
||||
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
|
||||
|
||||
PlatformSuffix = $(subst windows_msvc2015_,,$(platform))
|
||||
|
@ -932,6 +926,7 @@ else ifeq (qnx,$(platform))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -956,9 +951,7 @@ else ifeq (qnx,$(platform))
|
|||
LDFLAGS += -g
|
||||
endif
|
||||
|
||||
PLATCFLAGS += -DHAVE_SHADERPIPELINE -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_GL_SYNC -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_XCB -DHAVE_EGL -DHAVE_BB10 -DHAVE_GLSL -DHAVE_AL -DHAVE_BSV_MOVIE -DRARCH_MOBILE
|
||||
PLATCFLAGS += -DHAVE_SHADERPIPELINE -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_GL_SYNC -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_XCB -DHAVE_EGL -DHAVE_BB10 -DHAVE_GLSL -DHAVE_AL -DHAVE_BSV_MOVIE -DRARCH_MOBILE
|
||||
EXT_TARGET := $(TARGET_NAME)
|
||||
EXT_INTER_TARGET := $(TARGET_NAME)
|
||||
INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I.
|
||||
|
@ -979,6 +972,7 @@ else ifneq (,$(findstring unix,$(platform)))
|
|||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_NETPLAYDISCOVERY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_STB_FONT := 1
|
||||
|
@ -996,9 +990,7 @@ else ifneq (,$(findstring unix,$(platform)))
|
|||
HAVE_CHEATS := 1
|
||||
HAVE_CORE_INFO_CACHE := 1
|
||||
|
||||
PLATCFLAGS += -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_GL_SYNC -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
PLATCFLAGS += -DHAVE_UPDATE_CORE_INFO
|
||||
PLATCFLAGS += -DHAVE_VULKAN -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_X11 -DHAVE_XCB -DHAVE_UDEV -DHAVE_BSV_MOVIE -DHAVE_PULSE
|
||||
PLATCFLAGS += -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_GL_SYNC -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_BUILTINGLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_GFX_WIDGETS -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_VULKAN -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_X11 -DHAVE_XCB -DHAVE_UDEV -DHAVE_BSV_MOVIE -DHAVE_PULSE
|
||||
EXT_TARGET := $(TARGET_NAME)
|
||||
EXT_INTER_TARGET := $(TARGET_NAME)
|
||||
INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I.
|
||||
|
@ -1122,6 +1114,10 @@ ifeq ($(HAVE_OVERLAY), 1)
|
|||
CFLAGS += -DHAVE_OVERLAY
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEO_LAYOUT), 1)
|
||||
CFLAGS += -DHAVE_VIDEO_LAYOUT
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NETWORKING), 1)
|
||||
CFLAGS += -DHAVE_NETWORKING
|
||||
endif
|
||||
|
|
250
Makefile.lfx000
250
Makefile.lfx000
|
@ -1,250 +0,0 @@
|
|||
#########################
|
||||
## Toolchain variables ##
|
||||
#########################
|
||||
|
||||
# Default toolchain directory
|
||||
TOOLCHAIN_DIR="$(HOST_DIR)"
|
||||
|
||||
# All toolchain-related variables may be
|
||||
# overridden via the command line
|
||||
|
||||
ifdef GCW0_CC
|
||||
CC = $(GCW0_CC)
|
||||
else
|
||||
CC = $(TOOLCHAIN_DIR)/usr/bin/arm-linux-gcc
|
||||
endif
|
||||
|
||||
ifdef GCW0_CXX
|
||||
CXX = $(GCW0_CXX)
|
||||
else
|
||||
CXX = $(TOOLCHAIN_DIR)/usr/bin/arm-linux-g++
|
||||
endif
|
||||
|
||||
ifdef GCW0_STRIP
|
||||
STRIP = $(GCW0_STRIP)
|
||||
else
|
||||
STRIP = $(TOOLCHAIN_DIR)/usr/bin/arm-linux-strip
|
||||
endif
|
||||
|
||||
GCW0_SDL_CONFIG ?= $(TOOLCHAIN_DIR)/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/sdl-config
|
||||
GCW0_FREETYPE_CONFIG ?= $(TOOLCHAIN_DIR)/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/freetype-config
|
||||
|
||||
GCW0_INC_DIR ?= $(TOOLCHAIN_DIR)/usr/arm-buildroot-linux-gnueabi/sysroot/usr/include
|
||||
GCW0_LIB_DIR ?= $(TOOLCHAIN_DIR)/usr/arm-buildroot-linux-gnueabi/sysroot/usr/lib
|
||||
|
||||
#########################
|
||||
#########################
|
||||
|
||||
PACKAGE_NAME = retroarch
|
||||
|
||||
DEBUG ?= 0
|
||||
|
||||
MIYOO = 1
|
||||
DINGUX = 1
|
||||
HAVE_SCREENSHOTS = 1
|
||||
HAVE_REWIND = 1
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_AL = 0
|
||||
HAVE_ALSA = 1
|
||||
HAVE_DSP_FILTER = 1
|
||||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
HAVE_FILTERS_BUILTIN = 1
|
||||
HAVE_BUILTINMBEDTLS = 0
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_C99 = 1
|
||||
HAVE_CC = 1
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
HAVE_CHD = 1
|
||||
HAVE_COMMAND = 0
|
||||
HAVE_CXX = 1
|
||||
HAVE_DR_MP3 = 1
|
||||
HAVE_DYNAMIC = 1
|
||||
HAVE_EGL = 0
|
||||
HAVE_FREETYPE = 0
|
||||
HAVE_GDI = 1
|
||||
HAVE_GETADDRINFO = 0
|
||||
HAVE_GETOPT_LONG = 1
|
||||
HAVE_GLSL = 0
|
||||
HAVE_HID = 0
|
||||
HAVE_IBXM = 1
|
||||
HAVE_IMAGEVIEWER = 0
|
||||
HAVE_LANGEXTRA = 0
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_MENU_COMMON = 1
|
||||
HAVE_GFX_WIDGETS = 0
|
||||
HAVE_MMAP = 1
|
||||
HAVE_OPENDINGUX_FBDEV = 0
|
||||
HAVE_OPENGL = 0
|
||||
HAVE_OPENGL1 = 0
|
||||
HAVE_OPENGLES = 0
|
||||
HAVE_OPENGLES3 = 0
|
||||
HAVE_OPENGL_CORE = 0
|
||||
HAVE_OPENSSL = 0
|
||||
HAVE_OVERLAY = 0
|
||||
HAVE_RBMP = 1
|
||||
HAVE_RJPEG = 1
|
||||
HAVE_RPILED = 0
|
||||
HAVE_RPNG = 1
|
||||
HAVE_RUNAHEAD = 0
|
||||
HAVE_SDL_DINGUX = 1
|
||||
HAVE_SHADERPIPELINE = 0
|
||||
HAVE_STB_FONT = 0
|
||||
HAVE_STB_IMAGE = 0
|
||||
HAVE_STB_VORBIS = 0
|
||||
HAVE_STDIN_CMD = 0
|
||||
HAVE_STRCASESTR = 1
|
||||
HAVE_THREADS = 1
|
||||
HAVE_UDEV = 0
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 0
|
||||
HAVE_XMB = 0
|
||||
HAVE_OZONE = 0
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_CHEEVOS = 0
|
||||
HAVE_LIBSHAKE = 0
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
#HAVE_TINYALSA = 1
|
||||
HAVE_NEAREST_RESAMPLER = 1
|
||||
|
||||
OS = Linux
|
||||
TARGET = retroarch
|
||||
|
||||
OBJ :=
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS := -march=armv5te -mtune=arm926ej-s -ffast-math -fomit-frame-pointer
|
||||
DEF_FLAGS += -ffunction-sections -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DMIYOO=1 -DDINGUX -MMD
|
||||
DEF_FLAGS += -Wall -Wno-unused-variable -flto
|
||||
DEF_FLAGS += -std=gnu99 -D_GNU_SOURCE
|
||||
LIBS := -ldl -lz -lrt -pthread -lasound
|
||||
CFLAGS :=
|
||||
CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS
|
||||
ASFLAGS :=
|
||||
LDFLAGS := -Wl,--gc-sections
|
||||
INCLUDE_DIRS = -I$(GCW0_INC_DIR)
|
||||
LIBRARY_DIRS = -L$(GCW0_LIB_DIR)
|
||||
DEFINES := -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64 -UHAVE_STATIC_DUMMY
|
||||
DEFINES += -DHAVE_C99=1 -DHAVE_CXX=1
|
||||
DEFINES += -DHAVE_GETOPT_LONG=1 -DHAVE_STRCASESTR=1 -DHAVE_DYNAMIC=1
|
||||
DEFINES += -DHAVE_FILTERS_BUILTIN -DHAVE_ALSA
|
||||
|
||||
SDL_DINGUX_CFLAGS := $(shell $(GCW0_SDL_CONFIG) --cflags)
|
||||
SDL_DINGUX_LIBS := $(shell $(GCW0_SDL_CONFIG) --libs)
|
||||
FREETYPE_CFLAGS := $(shell $(GCW0_FREETYPE_CONFIG) --cflags)
|
||||
FREETYPE_LIBS := $(shell $(GCW0_FREETYPE_CONFIG) --libs)
|
||||
MMAP_LIBS = -lc
|
||||
|
||||
OBJDIR_BASE := obj-unix
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OBJDIR := $(OBJDIR_BASE)/debug
|
||||
DEF_FLAGS += -O0 -g -DDEBUG -D_DEBUG
|
||||
else
|
||||
OBJDIR := $(OBJDIR_BASE)/release
|
||||
DEF_FLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
||||
DEF_FLAGS += $(INCLUDE_DIRS)
|
||||
LDFLAGS += $(CFLAGS) $(CXXFLAGS) $(DEF_FLAGS)
|
||||
CFLAGS += $(DEF_FLAGS)
|
||||
CXXFLAGS += $(DEF_FLAGS)
|
||||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
Q := @
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
||||
$(TARGET): $(RARCH_OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
|
||||
ifeq ($(STRIP_BIN),1)
|
||||
$(STRIP) --strip-unneeded $(TARGET)
|
||||
endif
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.m
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo OBJC $<),)
|
||||
$(Q)$(CXX) $(OBJCFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.S $(HEADERS)
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo AS $<),)
|
||||
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
|
||||
install: $(TARGET)
|
||||
mkdir -p $(DESTDIR)$(BIN_DIR) 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(GLOBAL_CONFIG_DIR) 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(DATA_DIR)/applications 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(DATA_DIR)/metainfo 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(DOC_DIR) 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(MAN_DIR)/man6 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(DATA_DIR)/pixmaps 2>/dev/null || /bin/true
|
||||
cp $(TARGET) $(DESTDIR)$(BIN_DIR)
|
||||
cp tools/cg2glsl.py $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
cp retroarch.cfg $(DESTDIR)$(GLOBAL_CONFIG_DIR)
|
||||
cp com.libretro.RetroArch.metainfo.xml $(DESTDIR)$(DATA_DIR)/metainfo
|
||||
cp com.libretro.RetroArch.desktop $(DESTDIR)$(DATA_DIR)/applications
|
||||
cp docs/retroarch.6 $(DESTDIR)$(MAN_DIR)/man6
|
||||
cp docs/retroarch-cg2glsl.6 $(DESTDIR)$(MAN_DIR)/man6
|
||||
cp media/com.libretro.RetroArch.svg $(DESTDIR)$(DATA_DIR)/pixmaps
|
||||
cp COPYING $(DESTDIR)$(DOC_DIR)
|
||||
cp README.md $(DESTDIR)$(DOC_DIR)
|
||||
chmod 755 $(DESTDIR)$(BIN_DIR)/$(TARGET)
|
||||
chmod 755 $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
chmod 644 $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/applications/com.libretro.RetroArch.desktop
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/metainfo/com.libretro.RetroArch.metainfo.xml
|
||||
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch.6
|
||||
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch-cg2glsl.6
|
||||
chmod 644 $(DESTDIR)$(DATA_DIR)/pixmaps/com.libretro.RetroArch.svg
|
||||
@if test -d media/assets && test $(HAVE_ASSETS); then \
|
||||
echo "Installing media assets..."; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
if test $(HAVE_MATERIALUI) = 1; then \
|
||||
cp -r media/assets/glui/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_XMB) = 1; then \
|
||||
cp -r media/assets/xmb/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_OZONE) = 1; then \
|
||||
cp -r media/assets/ozone/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
cp media/assets/COPYING $(DESTDIR)$(DOC_DIR)/COPYING.assets; \
|
||||
echo "Asset copying done."; \
|
||||
fi
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
|
@ -41,7 +41,6 @@ HAVE_DSP_FILTER = 1
|
|||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
HAVE_STATIC_CORES = 1
|
||||
HAVE_FILTERS_BUILTIN = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
|
@ -53,7 +52,7 @@ HAVE_IFINFO = 1
|
|||
HAVE_NETPLAYDISCOVERY = 1
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
HAVE_CHD = 1
|
||||
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
||||
HAVE_STB_VORBIS = 1
|
||||
HAVE_IBXM = 1
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
|
@ -76,6 +75,7 @@ ifeq ($(HAVE_OPENGL), 1)
|
|||
HAVE_XMB = 1
|
||||
HAVE_OZONE = 1
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_VIDEO_LAYOUT = 1
|
||||
HAVE_GLSL = 1
|
||||
else
|
||||
HAVE_RGUI = 1
|
||||
|
@ -127,10 +127,10 @@ APP_ICON := pkg/libnx/retroarch.jpg
|
|||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -mcpu=cortex-a57+crc+fp+simd
|
||||
|
||||
CFLAGS := -g -Wall -O3 -fcommon -ffunction-sections \
|
||||
CFLAGS := -g -Wall -O3 -fcommon -ffast-math -ffunction-sections \
|
||||
$(ARCH) $(DEFINES) $(INCLUDE_DIRS) -I$(LIBNX)/include -I$(PORTLIBS)/include/ -include $(LIBNX)/include/switch.h #$(shell $(PORTLIBS)/bin/freetype-config --cflags)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DSWITCH=1 -DHAVE_LIBNX=1 -DNXLINK=1 -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_UPDATE_CORE_INFO -DHAVE_STB_FONT #-DHAVE_FREETYPE
|
||||
CFLAGS += $(INCLUDE) -DSWITCH=1 -DHAVE_LIBNX=1 -DNXLINK=1 -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_STB_FONT #-DHAVE_FREETYPE
|
||||
|
||||
ifeq ($(HAVE_FILTERS_BUILTIN), 1)
|
||||
CFLAGS += -DHAVE_FILTERS_BUILTIN
|
||||
|
|
|
@ -105,7 +105,6 @@ HAVE_OZONE = 0
|
|||
HAVE_ZLIB = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_XDELTA = 0 # Disabled until we figure out how to include <lzma.h>
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_CHEEVOS = 0
|
||||
HAVE_LIBSHAKE = 0
|
||||
|
@ -118,7 +117,7 @@ TARGET = retroarch
|
|||
|
||||
OBJ :=
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS := -march=armv5te -mtune=arm926ej-s -fomit-frame-pointer
|
||||
DEF_FLAGS := -march=armv5te -mtune=arm926ej-s -ffast-math -fomit-frame-pointer
|
||||
DEF_FLAGS += -ffunction-sections -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DMIYOO=1 -DDINGUX -MMD
|
||||
DEF_FLAGS += -Wall -Wno-unused-variable -flto
|
||||
|
@ -160,36 +159,12 @@ CXXFLAGS += $(DEF_FLAGS)
|
|||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CPPFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBRARY_DIRS: $(LIBRARY_DIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
OBJCFLAGS: $(OBJCFLAGS)
|
||||
RARCH_OBJ: $(RARCH_OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
@ -223,10 +198,9 @@ $(OBJDIR)/%.o: %.S $(HEADERS)
|
|||
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -rf $(OBJDIR_BASE)
|
||||
$(Q)rm -f $(TARGET)
|
||||
$(Q)rm -f *.d
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ HAVE_GFX_WIDGETS := 1
|
|||
HAVE_VULKAN := 1
|
||||
HAVE_XAUDIO := 1
|
||||
HAVE_XINPUT := 1
|
||||
HAVE_WASAPI := 1
|
||||
HAVE_WASAPI := 0
|
||||
HAVE_THREAD_STORAGE := 1
|
||||
HAVE_WINMM := 1
|
||||
|
||||
|
@ -61,6 +61,7 @@ HAVE_NETWORKING := 1
|
|||
HAVE_IFINFO := 1
|
||||
HAVE_NETWORK_CMD := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_LANGEXTRA := 1
|
||||
HAVE_CHEEVOS := 1
|
||||
HAVE_SHADERPIPELINE := 1
|
||||
|
|
54
Makefile.ngc
54
Makefile.ngc
|
@ -58,7 +58,6 @@ LIBS := $(WHOLE_START) $(LIB_CORE) $(WHOLE_END)
|
|||
libogc_platform := 1
|
||||
|
||||
EXTERNAL_LIBOGC ?= 0
|
||||
HAVE_OGG_OGC ?= 0
|
||||
GX_PTHREAD_LEGACY ?= 1
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
|
@ -103,10 +102,6 @@ ifeq ($(BIG_STACK), 1)
|
|||
LDFLAGS += -T bootstrap/gx/ogc.ld
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OGG_OGC), 1)
|
||||
LIBS += -L$(DEVKITPRO)/portlibs/ppc/lib -lvorbisfile -lvorbis -logg
|
||||
endif
|
||||
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
LIBS += -lfat
|
||||
endif
|
||||
|
@ -130,11 +125,11 @@ HAVE_RBMP := 1
|
|||
HAVE_RTGA := 1
|
||||
HAVE_IBXM := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_ZLIB := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_CONFIGFILE := 1
|
||||
HAVE_PATCH := 1
|
||||
HAVE_XDELTA := 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_CHEATS := 1
|
||||
HAVE_SCREENSHOTS := 1
|
||||
HAVE_REWIND := 1
|
||||
|
@ -238,65 +233,34 @@ else
|
|||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
OBJOUT = -o
|
||||
LINKOUT = -o
|
||||
LINK = $(CXX)
|
||||
|
||||
all: $(EXT_TARGET)
|
||||
|
||||
define INFO
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
LD: $(LD)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
LINKOUT: $(LINKOUT)
|
||||
OBJ: $(OBJ)
|
||||
OBJOUT: $(OBJOUT)
|
||||
PLATEXTRA: $(PLATEXTRA)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
%.dol: %.elf
|
||||
$(ELF2DOL) $< $@
|
||||
|
||||
$(EXT_INTER_TARGET): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LINK $@),)
|
||||
$(Q)$(LINK) $(LINKOUT)$@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(PLATEXTRA) $(LIBS)
|
||||
$(LINK) $(LINKOUT)$@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(PLATEXTRA) $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CXX) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.S
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.binobj: %.bin
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) -r -b binary $(OBJOUT)$@ $<
|
||||
$(LD) -r -b binary $(OBJOUT)$@ $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -f $(EXT_TARGET)
|
||||
$(Q)rm -f $(EXT_INTER_TARGET)
|
||||
$(Q)rm -f $(OBJ)
|
||||
rm -f $(EXT_TARGET)
|
||||
rm -f $(EXT_INTER_TARGET)
|
||||
rm -f $(OBJ)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ DEFINES += -DHAVE_THREADS \
|
|||
-DHAVE_RPNG \
|
||||
-DHAVE_RJPEG \
|
||||
-DHAVE_OVERLAY \
|
||||
-DHAVE_VIDEO_LAYOUT \
|
||||
-DHAVE_ALSA \
|
||||
-DHAVE_ZLIB \
|
||||
-D__linux__ \
|
||||
|
|
|
@ -52,6 +52,7 @@ else
|
|||
HAVE_ZLIB := 1
|
||||
HAVE_BUILTINZLIB := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_EGL := 1
|
||||
HAVE_GFX_WIDGETS := 1
|
||||
|
@ -78,7 +79,7 @@ else
|
|||
HAVE_THREAD_ATTR := 1
|
||||
HAVE_LIBRETRODB := 1
|
||||
HAVE_CC_RESAMPLER := 1
|
||||
HAVE_CHEEVOS := 0
|
||||
HAVE_CHEEVOS := 1
|
||||
HAVE_RUNAHEAD := 1
|
||||
RARCH_CONSOLE := 1
|
||||
HAVE_MAIN := 1
|
||||
|
@ -86,7 +87,6 @@ else
|
|||
HAVE_COMPRESSION := 1
|
||||
HAVE_UPDATE_ASSETS := 1
|
||||
HAVE_UPDATE_CORES := 1
|
||||
HAVE_UPDATE_CORE_INFO := 1
|
||||
HAVE_CONFIGFILE := 1
|
||||
HAVE_CHD := 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
|
@ -123,7 +123,7 @@ INCDIRS += -I. -Idefines -Ideps -Ideps/7zip -Ideps/libz -Ilibretro-common/includ
|
|||
ARCHFLAGS += --target=x86_64-scei-ps4 -DORBIS -D__ORBIS__ -D__PS4__ -D_BSD_SOURCE
|
||||
DEFINES += -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_FILTERS_BUILTIN \
|
||||
-DHAVE_XMB -DHAVE_RGUI -DHAVE_OZONE \
|
||||
-DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_CORES -DHAVE_UPDATE_CORE_INFO -DHAVE_UPDATE_ASSETS \
|
||||
-DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_CORES -DHAVE_UPDATE_ASSETS \
|
||||
|
||||
# Compiling with -Werror and disabling some warnings
|
||||
DEFINES += -Werror -Wno-macro-redefined -Wno-typedef-redefinition -Wno-non-literal-null-conversion -Wno-void-pointer-to-int-cast \
|
||||
|
@ -176,67 +176,38 @@ else
|
|||
CXXFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
TARGETS := $(TARGET).self
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
define INFO
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
LD: $(LD)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBS: $(LIBS)
|
||||
OBJ: $(OBJ)
|
||||
OBJOUT: $(OBJOUT)
|
||||
ORBISDEV: $(ORBISDEV)
|
||||
TARGET: $(TARGET)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
OBJOUT = -o
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CXX) $(CXXFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.S
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.s
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c $(OBJOUT)$@ $<
|
||||
$(CC) -c $(OBJOUT)$@ $<
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) $(ORBISDEV)/usr/lib/crt0.o $(OBJ) $(LDFLAGS) $(LIBS) -o $(TARGET).elf
|
||||
$(LD) $(ORBISDEV)/usr/lib/crt0.o $(OBJ) $(LDFLAGS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
$(TARGET).oelf: $(TARGET).elf
|
||||
orbis-elf-create $(TARGET).elf $(TARGET).oelf
|
||||
@orbis-elf-create $(TARGET).elf $(TARGET).oelf
|
||||
|
||||
$(TARGET).self: $(TARGET).oelf
|
||||
python $(ORBISDEV)/bin/make_fself.py --auth-info $(AUTH_INFO) $(TARGET).oelf $(TARGET).self
|
||||
|
||||
install:
|
||||
cp $(TARGET).self $(SELF_PATH_INSTALL)/homebrew.self
|
||||
@cp $(TARGET).self $(SELF_PATH_INSTALL)/homebrew.self
|
||||
@echo "Installed!"
|
||||
|
||||
clean:
|
||||
$(Q)rm -f $(OBJ) $(TARGET).elf $(TARGET).oelf $(TARGET).self
|
||||
rm -f $(OBJ) $(TARGET).elf $(TARGET).oelf $(TARGET).self
|
||||
|
||||
.PHONY: clean all
|
||||
|
|
|
@ -11,7 +11,7 @@ all: $(BINDIR)/retroarch
|
|||
|
||||
pnd: retroarch.pnd
|
||||
|
||||
install: all $(BINDIR)/retroarch-zip $(PNDDIR)/readme.html
|
||||
install: all $(BINDIR)/retroarch-joyconfig $(BINDIR)/retroarch-zip $(PNDDIR)/readme.html
|
||||
|
||||
retroarch:
|
||||
./configure --prefix=$PND_BASEDIR/$PRJ --disable-ffmpeg --disable-cg --disable-pulse --disable-jack --enable-opengles
|
||||
|
@ -21,6 +21,10 @@ $(BINDIR)/retroarch: retroarch
|
|||
mkdir -p $(BINDIR)
|
||||
cp retroarch $(BINDIR)/retroarch
|
||||
|
||||
$(BINDIR)/retroarch-joyconfig: tools/retroarch-joyconfig
|
||||
mkdir -p $(BINDIR)
|
||||
cp tools/retroarch-joyconfig $(BINDIR)/retroarch-joyconfig
|
||||
|
||||
$(BINDIR)/retroarch-zip: retroarch-zip
|
||||
mkdir -p $(BINDIR)
|
||||
cp retroarch-zip $(BINDIR)/retroarch-zip
|
||||
|
@ -45,5 +49,6 @@ clean:
|
|||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f $(BINDIR)/retroarch
|
||||
rm -f $(BINDIR)/retroarch-joyconfig
|
||||
rm -f $(PNDDIR)/readme.html
|
||||
rm -f retroarch
|
||||
|
|
68
Makefile.ps2
68
Makefile.ps2
|
@ -16,6 +16,7 @@ ifeq ($(DEBUG), 1)
|
|||
DEFINES += -DDEBUG
|
||||
else
|
||||
OPTIMIZE_LV := -O3
|
||||
# LDFLAGS := -s
|
||||
endif
|
||||
|
||||
ifeq ($(MUTE_WARNINGS), 1)
|
||||
|
@ -54,7 +55,6 @@ else
|
|||
HAVE_MENU = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_PATCH = 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 0
|
||||
|
@ -83,20 +83,30 @@ ifeq ($(strip $(PS2SDK)),)
|
|||
$(error "Please set PS2SDK in your environment. export PS2SDK=<path to>ps2sdk")
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include
|
||||
INCDIR += -Ilibretro-common/include -Ideps -Ideps/stb -Ideps/7zip
|
||||
INCDIR += -Ips2/include -Ilibretro-common/include -Ideps -Ideps/stb -Ideps/7zip
|
||||
|
||||
LDFLAGS += -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ports/lib -L.
|
||||
# Lib cdvd is needed to get proper time
|
||||
LIBS += -lpatches -lgskit -ldmakit -lps2_drivers -lz -lelf-loader
|
||||
LIBS += -lpatches -lgskit -ldmakit -laudsrv -lmtap -lpadx -lz -lcdvd -lelf-loader -lfileXio -lpoweroff
|
||||
|
||||
CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) $(DEFINES) -DPS2 -fsingle-precision-constant
|
||||
|
||||
CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) $(DEFINES) -DPS2 -ffast-math -fsingle-precision-constant
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
# IRX libs
|
||||
IRX_FILES += sio2man.irx iomanX.irx fileXio.irx
|
||||
IRX_FILES += mcman.irx mcserv.irx
|
||||
IRX_FILES += usbd.irx bdm.irx bdmfs_vfat.irx usbmass_bd.irx
|
||||
IRX_FILES += libsd.irx audsrv.irx
|
||||
IRX_FILES += cdfs.irx
|
||||
IRX_FILES += ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx poweroff.irx
|
||||
IRX_FILES += mtapman.irx padman.irx
|
||||
EE_OBJS += $(IRX_FILES:.irx=_irx.o)
|
||||
|
||||
# Missing objecst on the PS2SDK
|
||||
EE_OBJS += ps2/compat_files/ps2_devices.o
|
||||
|
||||
EE_OBJS += $(OBJ)
|
||||
|
||||
EE_CFLAGS = $(CFLAGS)
|
||||
|
@ -108,27 +118,11 @@ EE_INCS = $(INCDIR)
|
|||
EE_BIN = $(TARGET).elf
|
||||
EE_GPVAL = $(GPVAL)
|
||||
|
||||
|
||||
all: $(EE_BIN)
|
||||
|
||||
define INFO
|
||||
EE_BIN: $(EE_BIN)
|
||||
EE_CC: $(EE_CC)
|
||||
EE_CFLAGS: $(EE_CFLAGS)
|
||||
EE_CXX: $(EE_CXX)
|
||||
EE_CXXFLAGS: $(EE_CXXFLAGS)
|
||||
EE_INCS: $(EE_INCS)
|
||||
EE_OBJS: $(EE_OBJS)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
clean:
|
||||
@$(if $(Q), $(shell echo echo RM $<),)
|
||||
$(Q)rm -f $(EE_BIN) $(EE_OBJS)
|
||||
rm -f $(EE_BIN) $(EE_OBJS)
|
||||
|
||||
prepare:
|
||||
ps2client -h $(PS2_IP) reset
|
||||
|
@ -138,29 +132,17 @@ run:
|
|||
ps2client -h $(PS2_IP) execee host:$(EE_BIN)
|
||||
|
||||
sim:
|
||||
ifeq ($(shell uname), Darwin)
|
||||
/Applications/PCSX2.app/Contents/MacOS/PCSX2 -elf $(PWD)/$(EE_BIN)
|
||||
else
|
||||
PCSX2 -elf $(PWD)/$(EE_BIN) -nogui
|
||||
endif
|
||||
PCSX2 --elf=$(PWD)/$(EE_BIN) --nogui
|
||||
|
||||
debug: clean all run
|
||||
|
||||
release: all
|
||||
ps2-packer $(EE_BIN) $(TARGET_RELEASE)
|
||||
|
||||
# IRX files
|
||||
%_irx.c:
|
||||
$(PS2SDK)/bin/bin2c $(PS2SDK)/iop/irx/$*.irx $@ $*_irx
|
||||
|
||||
#Include preferences
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.eeglobal_cpp
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@
|
||||
|
||||
%.o: %.cc
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) -c $< -o $@
|
||||
|
|
|
@ -20,15 +20,15 @@ ifeq ($(MUTE_WARNINGS), 1)
|
|||
endif
|
||||
|
||||
INCDIR = -Ilibretro-common/include
|
||||
INCDIR += -I$(PS2SDK)/ports/include
|
||||
CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) -fsingle-precision-constant
|
||||
INCDIR += -Ips2/include
|
||||
CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) -ffast-math -fsingle-precision-constant
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
RARCH_DEFINES += -DPS2 -DIS_SALAMANDER -DRARCH_CONSOLE
|
||||
|
||||
LIBDIR =
|
||||
LDFLAGS += -L$(PS2SDK)/ports/lib
|
||||
LIBS = -lelf-loader -lps2_drivers -lpatches
|
||||
LDFLAGS =
|
||||
LIBS = -lelf-loader -lpatches -lfileXio -lpoweroff
|
||||
|
||||
ifeq ($(SCREEN_DEBUG), 1)
|
||||
LIBS += -ldebug
|
||||
|
@ -60,7 +60,16 @@ EE_OBJS = frontend/frontend_salamander.o \
|
|||
libretro-common/vfs/vfs_implementation.o \
|
||||
libretro-common/hash/lrc_hash.o \
|
||||
libretro-common/time/rtime.o \
|
||||
verbosity.o
|
||||
verbosity.o \
|
||||
ps2/compat_files/ps2_devices.o
|
||||
|
||||
# IRX libs
|
||||
IRX_FILES += sio2man.irx iomanX.irx fileXio.irx
|
||||
IRX_FILES += mcman.irx mcserv.irx
|
||||
IRX_FILES += usbd.irx bdm.irx bdmfs_vfat.irx usbmass_bd.irx
|
||||
IRX_FILES += cdfs.irx
|
||||
IRX_FILES += ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx poweroff.irx
|
||||
EE_OBJS += $(IRX_FILES:.irx=_irx.o)
|
||||
|
||||
EE_CFLAGS = $(CFLAGS)
|
||||
EE_CXXFLAGS = $(CFLAGS)
|
||||
|
@ -84,6 +93,10 @@ run:
|
|||
release: all
|
||||
ps2-packer $(EE_BIN) $(TARGET_RELEASE)
|
||||
|
||||
# IRX files
|
||||
%_irx.c:
|
||||
$(PS2SDK)/bin/bin2c $(PS2SDK)/iop/irx/$*.irx $@ $*_irx
|
||||
|
||||
#Include preferences
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.eeglobal_cpp
|
||||
|
|
|
@ -27,20 +27,13 @@ ELF_TARGET := retroarch_psl1ght.elf
|
|||
SELF_TARGET := $(ELF_TARGET:.elf=.self)
|
||||
CORE_PATH = pkg/psl1ght/pkg/USRDIR/cores/CORE.SELF
|
||||
|
||||
INCLUDE += -I. -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude -Idefines -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2
|
||||
LIBDIRS += -L. -L$(PORTLIBS)/lib
|
||||
|
||||
ifeq ($(HAVE_STATIC_DUMMY),1)
|
||||
DEFINES += -DHAVE_STATIC_DUMMY
|
||||
LIBS :=
|
||||
else
|
||||
LIBS := -lretro_psl1ght
|
||||
endif
|
||||
INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude -Idefines
|
||||
LIBDIRS += -L.
|
||||
|
||||
MACHDEP := -D__PSL1GHT__ -D__PS3__ -mcpu=cell
|
||||
CFLAGS += -Wall $(DEFINES) $(MACHDEP) $(INCLUDE)
|
||||
CFLAGS += -Wall $(MACHDEP) $(INCLUDE)
|
||||
LDFLAGS := $(MACHDEP)
|
||||
LIBS += -lrt -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl -lsysfs -lfreetype -lcamera -lgem -lspurs
|
||||
LIBS := -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl -lsysfs -lfreetype -lcamera -lgem -lspurs
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
|
@ -60,14 +53,12 @@ else
|
|||
GIT = git.exe
|
||||
endif
|
||||
|
||||
SHADER_OBJS = gfx/drivers/rsx_shaders/modern_opaque.vpo.o \
|
||||
gfx/drivers/rsx_shaders/modern_opaque.fpo.o \
|
||||
gfx/drivers/rsx_shaders/modern_alpha_blend.vpo.o \
|
||||
gfx/drivers/rsx_shaders/modern_alpha_blend.fpo.o
|
||||
SHADER_OBJS = gfx/drivers/rsx_shaders/vpshader_basic.vpo.o \
|
||||
gfx/drivers/rsx_shaders/fpshader_basic.fpo.o
|
||||
|
||||
LIBCO_OBJ = libretro-common/libco/ps3.o
|
||||
|
||||
OBJ = $(SHADER_OBJS) $(LIBCO_OBJ) libretro-common/memmap/memmap.o griffin/griffin.o
|
||||
OBJ = $(SHADER_OBJS) $(LIBCO_OBJ) griffin/griffin.o
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_LOGGER
|
||||
|
@ -79,7 +70,7 @@ endif
|
|||
|
||||
SHARED_FLAGS :=
|
||||
|
||||
SHARED_FLAGS += -DHAVE_GCM
|
||||
SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT
|
||||
SHARED_FLAGS += -DHAVE_MENU \
|
||||
-DHAVE_CONFIGFILE \
|
||||
-DHAVE_PATCH \
|
||||
|
@ -87,11 +78,12 @@ SHARED_FLAGS += -DHAVE_MENU \
|
|||
-DRARCH_CONSOLE \
|
||||
-DHAVE_OVERLAY \
|
||||
-DHAVE_HEADSET \
|
||||
-DHAVE_CG \
|
||||
-DHAVE_CG_RUNTIME_COMPILER \
|
||||
-DHAVE_SYSMODULES \
|
||||
-DHAVE_SYSUTILS \
|
||||
-DHAVE_RARCH_EXEC \
|
||||
-DHAVE_MOUSE \
|
||||
-DHAVE_LIGHTGUN \
|
||||
-DHAVE_ZLIB \
|
||||
-DHAVE_RPNG \
|
||||
-DHAVE_GRIFFIN=1 \
|
||||
|
@ -107,15 +99,8 @@ SHARED_FLAGS += -DHAVE_MENU \
|
|||
-DHAVE_MULTIMAN \
|
||||
-DHAVE_MEMINFO \
|
||||
-DHAVE_RGUI \
|
||||
-DHAVE_XMB \
|
||||
-DHAVE_OZONE \
|
||||
-DHAVE_GFX_WIDGETS \
|
||||
-DHAVE_MENU_BUFFER \
|
||||
-DHAVE_FREETYPE \
|
||||
-DHAVE_CORE_INFO_CACHE \
|
||||
-DHAVE_7ZIP \
|
||||
-D_7ZIP_ST
|
||||
|
||||
-DHAVE_CORE_INFO_CACHE
|
||||
CFLAGS += -std=gnu99 $(SHARED_FLAGS)
|
||||
CXXFLAGS += $(SHARED_FLAGS)
|
||||
|
||||
|
@ -126,29 +111,10 @@ else
|
|||
CXXFLAGS += -03 -g
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
all: $(SELF_TARGET)
|
||||
|
||||
define INFO
|
||||
CXX: $(CXX)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
OBJ: $(OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
$(ELF_TARGET): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
|
||||
|
||||
create-core: $(SELF_TARGET)
|
||||
cp $(SELF_TARGET) $(CORE_PATH)
|
||||
|
@ -159,8 +125,7 @@ pkg: create-core
|
|||
# $(PACKAGE_FINALIZE) $(PACKAGE_BASENAME).gnpdrm.pkg
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -f $(ELF_TARGET)
|
||||
$(Q)rm -f $(OBJ)
|
||||
rm -f $(ELF_TARGET)
|
||||
rm -f $(OBJ)
|
||||
|
||||
.PHONY: clean
|
||||
|
|
|
@ -27,7 +27,7 @@ ELF_TARGET := retroarch_psl1ght_salamander.elf
|
|||
ELF_TARGET_NONSTRIPPED := retroarch_psl1ght_salamander_nonstripped.elf
|
||||
EBOOT_PATH = pkg/psl1ght/pkg/USRDIR/EBOOT.BIN
|
||||
|
||||
INCLUDE += -I. -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib \
|
||||
INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib \
|
||||
-Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude -Idefines
|
||||
LIBDIRS += -L.
|
||||
|
||||
|
@ -85,7 +85,8 @@ endif
|
|||
|
||||
SHARED_FLAGS :=
|
||||
|
||||
SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DHAVE_MULTIMAN -DHAVE_RGUI -DIS_SALAMANDER -DHAVE_GCM
|
||||
SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT
|
||||
SHARED_FLAGS += -DHAVE_MENU -DHAVE_CONFIGFILE -DRARCH_CONSOLE -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_GRIFFIN=1 -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts -DHAVE_CC_RESAMPLER -DHAVE_MULTIMAN -DHAVE_RGUI -DIS_SALAMANDER
|
||||
CFLAGS += -std=gnu99 $(SHARED_FLAGS)
|
||||
CXXFLAGS += $(SHARED_FLAGS)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ HAVE_THREADS ?= 1
|
|||
BIG_STACK ?= 0
|
||||
LOAD_WITHOUT_CORE_INFO ?= 0
|
||||
HAVE_STATIC_DUMMY ?= 0
|
||||
HAVE_XDELTA ?= 1
|
||||
|
||||
TARGET = retroarchpsp
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
|
@ -16,7 +16,7 @@ else
|
|||
endif
|
||||
|
||||
INCDIR = deps deps/stb deps/7zip libretro-common/include libretro-common/include/compat/zlib
|
||||
CFLAGS = $(OPTIMIZE_LV) -fsingle-precision-constant
|
||||
CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
RARCH_DEFINES = -DPSP \
|
||||
|
|
|
@ -12,7 +12,7 @@ else
|
|||
endif
|
||||
|
||||
INCDIR = $(PSPPATH)/include libretro-common/include
|
||||
CFLAGS = $(OPTIMIZE_LV) -fsingle-precision-constant
|
||||
CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
RARCH_DEFINES = -DPSP -DIS_SALAMANDER -DRARCH_CONSOLE
|
||||
|
|
|
@ -107,7 +107,6 @@ HAVE_OZONE = 0
|
|||
HAVE_ZLIB = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_XDELTA = 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_CHEEVOS = 0
|
||||
HAVE_LIBSHAKE = 0
|
||||
|
@ -120,7 +119,7 @@ OPK_NAME = retroarch_retrofw.opk
|
|||
|
||||
OBJ :=
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS := -march=mips32 -mtune=mips32 -mhard-float -fomit-frame-pointer
|
||||
DEF_FLAGS := -march=mips32 -mtune=mips32 -mhard-float -ffast-math -fomit-frame-pointer
|
||||
DEF_FLAGS += -mplt -mno-shared
|
||||
DEF_FLAGS += -ffunction-sections -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DDINGUX=1 -DRETROFW=1 -MMD
|
||||
|
@ -164,9 +163,7 @@ CXXFLAGS += $(DEF_FLAGS)
|
|||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
|
@ -184,30 +181,9 @@ X-OD-NeedsDownscaling=true
|
|||
endef
|
||||
export DESKTOP_ENTRY
|
||||
|
||||
|
||||
all: $(TARGET) opk
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CPPFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBRARY_DIRS: $(LIBRARY_DIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
OBJCFLAGS: $(OBJCFLAGS)
|
||||
RARCH_OBJ: $(RARCH_OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
@ -237,11 +213,10 @@ $(OBJDIR)/%.o: %.S $(HEADERS)
|
|||
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -rf $(OBJDIR_BASE)
|
||||
$(Q)rm -f $(TARGET)
|
||||
$(Q)rm -f *.d
|
||||
$(Q)rm -rf $(OPK_NAME)
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
rm -rf $(OPK_NAME)
|
||||
|
||||
opk: $(TARGET)
|
||||
echo "$$DESKTOP_ENTRY" > default.retrofw.desktop
|
||||
|
|
|
@ -76,7 +76,6 @@ HAVE_MENU = 1
|
|||
HAVE_MENU_COMMON = 1
|
||||
HAVE_GFX_WIDGETS = 0
|
||||
HAVE_MMAP = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_OPENDINGUX_FBDEV = 0
|
||||
HAVE_OPENGL = 0
|
||||
HAVE_OPENGL1 = 0
|
||||
|
|
|
@ -76,7 +76,6 @@ HAVE_MENU = 1
|
|||
HAVE_MENU_COMMON = 1
|
||||
HAVE_GFX_WIDGETS = 0
|
||||
HAVE_MMAP = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_OPENDINGUX_FBDEV = 0
|
||||
HAVE_OPENGL = 0
|
||||
HAVE_OPENGL1 = 0
|
||||
|
|
|
@ -107,7 +107,6 @@ HAVE_OZONE = 0
|
|||
HAVE_ZLIB = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_XDELTA = 0 # Disabled until we figure out how to include <lzma.h>
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_CHEEVOS = 0
|
||||
HAVE_LIBSHAKE = 0
|
||||
|
@ -166,9 +165,7 @@ CXXFLAGS += $(DEF_FLAGS)
|
|||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
|
@ -188,28 +185,6 @@ export DESKTOP_ENTRY
|
|||
|
||||
all: $(TARGET) opk
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CPPFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBRARY_DIRS: $(LIBRARY_DIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
OBJCFLAGS: $(OBJCFLAGS)
|
||||
RARCH_OBJ: $(RARCH_OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
@ -239,11 +214,10 @@ $(OBJDIR)/%.o: %.S $(HEADERS)
|
|||
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -rf $(OBJDIR_BASE)
|
||||
$(Q)rm -f $(TARGET)
|
||||
$(Q)rm -f *.d
|
||||
$(Q)rm -rf $(OPK_NAME)
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
rm -rf $(OPK_NAME)
|
||||
|
||||
opk: $(TARGET)
|
||||
echo "$$DESKTOP_ENTRY" > default.rs90.desktop
|
||||
|
|
|
@ -84,9 +84,9 @@ else
|
|||
HAVE_GFX_WIDGETS := 1
|
||||
HAVE_CONFIGFILE := 1
|
||||
HAVE_PATCH := 1
|
||||
HAVE_XDELTA := 1 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_CHEATS := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_MATERIALUI := 1
|
||||
HAVE_XMB := 1
|
||||
HAVE_RGUI := 1
|
||||
|
@ -138,7 +138,7 @@ ifeq ($(HAVE_VITAGLES), 1)
|
|||
ARCHFLAGS += -DSCE_LIBC_SIZE=$(SCE_LIBC_SIZE)
|
||||
endif
|
||||
|
||||
CFLAGS += $(ARCHFLAGS) -mword-relocations
|
||||
CFLAGS += $(ARCHFLAGS) -mword-relocations -fno-optimize-sibling-calls
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -g -Og
|
||||
|
@ -147,9 +147,9 @@ else
|
|||
endif
|
||||
|
||||
ASFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -Wl,-q,--pic-veneer
|
||||
LDFLAGS := -Wl,-q
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wall -ffast-math
|
||||
CFLAGS += -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DRARCH_CONSOLE
|
||||
CFLAGS += -DHAVE_DSP_FILTER
|
||||
CFLAGS += -DHAVE_VIDEO_FILTER
|
||||
|
@ -190,10 +190,6 @@ else
|
|||
LIBS += -lretro_vita
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
LIBS += $(WHOLE_END) $(VITA_LIBS) -lm -lc
|
||||
|
||||
TARGETS := $(TARGET).vpk
|
||||
|
@ -203,51 +199,25 @@ POSTCOMPILE = mv -f $*.Tdepend $*.depend
|
|||
|
||||
all: $(TARGETS)
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEPFLAGS: $(DEPFLAGS)
|
||||
INCDIRS: $(INCDIRS)
|
||||
LD: $(LD)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
OBJ: $(OBJ)
|
||||
POSTCOMPILE: $(POSTCOMPILE)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
%.o: %.cpp
|
||||
%.o: %.cpp %.depend
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(Q)$(POSTCOMPILE)
|
||||
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(POSTCOMPILE)
|
||||
|
||||
%.o: %.c
|
||||
%.o: %.c %.depend
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(Q)$(POSTCOMPILE)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(POSTCOMPILE)
|
||||
|
||||
%.o: %.S
|
||||
%.o: %.S %.depend
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(Q)$(POSTCOMPILE)
|
||||
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(POSTCOMPILE)
|
||||
|
||||
%.o: %.s
|
||||
%.o: %.s %.depend
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(Q)$(POSTCOMPILE)
|
||||
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
|
||||
$(POSTCOMPILE)
|
||||
|
||||
%.depend: ;
|
||||
|
||||
|
@ -258,8 +228,7 @@ liblibScePiglet_stub.a:
|
|||
cp deps/Pigs-In-A-Blanket/piglet_stub/libScePiglet/liblibScePiglet_stub.a .
|
||||
|
||||
$(TARGET).elf: $(OBJ) liblibScePiglet_stub.a
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
|
||||
$(LD) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
|
||||
|
||||
%.velf: %.elf
|
||||
cp $< $<.unstripped.elf
|
||||
|
@ -274,10 +243,9 @@ $(TARGET).elf: $(OBJ) liblibScePiglet_stub.a
|
|||
vita-pack-vpk -s param.sfo -b $< $@
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -f $(OBJ) $(TARGET).elf $(TARGET).elf.unstripped.elf $(TARGET).velf $(TARGET).self param.sfo $(TARGET).vpk
|
||||
$(Q)rm -rf deps/Pigs-In-A-Blanket/piglet_stub/libScePiglet
|
||||
$(Q)rm -f $(OBJ:.o=.depend)
|
||||
rm -f $(OBJ) $(TARGET).elf $(TARGET).elf.unstripped.elf $(TARGET).velf $(TARGET).self param.sfo $(TARGET).vpk
|
||||
rm -rf deps/Pigs-In-A-Blanket/piglet_stub/libScePiglet
|
||||
rm -f $(OBJ:.o=.depend)
|
||||
|
||||
# Useful for developers
|
||||
vpksend: $(TARGET).vpk
|
||||
|
|
|
@ -14,7 +14,7 @@ PREFIX = arm-vita-eabi
|
|||
CC = $(PREFIX)-gcc
|
||||
|
||||
INCDIR = libretro-common/include
|
||||
CFLAGS = -Wl,-q $(OPTIMIZE_LV) -I$(INCDIR) -std=gnu99 -mfloat-abi=hard -fsingle-precision-constant -mword-relocations
|
||||
CFLAGS = -Wl,-q $(OPTIMIZE_LV) -I$(INCDIR) -std=gnu99 -mfloat-abi=hard -ffast-math -fsingle-precision-constant -mword-relocations
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
RARCH_DEFINES = -DVITA -DIS_SALAMANDER -DRARCH_CONSOLE
|
||||
|
|
119
Makefile.webos
119
Makefile.webos
|
@ -1,34 +1,20 @@
|
|||
include version.all
|
||||
|
||||
ifneq ($(CROSS_COMPILE),arm-webos-linux-gnueabi-)
|
||||
$(error You need webOS toolchain to build this. See https://github.com/webosbrew/native-toolchain)
|
||||
endif
|
||||
$(call assert,$(call seq,$(TARGET_PREFIX),arm-webos-linux-gnueabi-),webOS SDK isn't setup properly. See https://github.com/webosbrew/meta-lg-webos-ndk#compile-program-by-command-line)
|
||||
|
||||
ifdef SDKTARGETSYSROOT
|
||||
$(warning "OE-based toolchain isn't supported anymore. Please use https://github.com/webosbrew/native-toolchain")
|
||||
STAGING_DIR = $(SDKTARGETSYSROOT)
|
||||
else ifndef STAGING_DIR
|
||||
$(error "Can't find buildroot based toolchain. Please use https://github.com/webosbrew/native-toolchain")
|
||||
endif
|
||||
WEBOS_FREETYPE_CONFIG ?= $(SDKTARGETSYSROOT)/usr/bin/freetype-config
|
||||
|
||||
WEBOS_FREETYPE_CONFIG ?= $(STAGING_DIR)/usr/bin/freetype-config
|
||||
|
||||
WEBOS_INC_DIR ?= $(STAGING_DIR)/usr/include
|
||||
WEBOS_USR_LIB_DIR ?= $(STAGING_DIR)/usr/lib
|
||||
WEBOS_LIB_DIR ?= $(STAGING_DIR)/lib
|
||||
|
||||
ADD_SDL2_LIB ?= 0
|
||||
SDL2_PREBUILT_ARCHIVE ?= https://github.com/webosbrew/SDL-webOS/releases/download/release-2.30.12-webos.1/SDL2-2.30.12-webos-abi.tar.gz
|
||||
WEBOS_INC_DIR ?= $(SDKTARGETSYSROOT)/usr/include
|
||||
WEBOS_LIB_DIR ?= $(SDKTARGETSYSROOT)/usr/lib
|
||||
|
||||
#########################
|
||||
#########################
|
||||
|
||||
APP_PACKAGE_NAME ?= com.retroarch.webos
|
||||
PACKAGE_NAME = com.retroarch
|
||||
PACKAGE_VERSION := $(patsubst "%",%,$(RARCH_VERSION))
|
||||
|
||||
DEBUG ?= 0
|
||||
|
||||
HAVE_CLOUDSYNC = 1
|
||||
HAVE_SCREENSHOTS = 1
|
||||
HAVE_REWIND = 1
|
||||
HAVE_7ZIP = 1
|
||||
|
@ -61,8 +47,8 @@ HAVE_DR_MP3 = 1
|
|||
HAVE_DYNAMIC = 1
|
||||
HAVE_DYLIB = 1
|
||||
HAVE_EGL = 0
|
||||
HAVE_FREETYPE = 1
|
||||
HAVE_GDI = 0
|
||||
HAVE_FREETYPE = 0
|
||||
HAVE_GDI = 1
|
||||
HAVE_GETADDRINFO = 1
|
||||
HAVE_GETOPT_LONG = 1
|
||||
HAVE_GLSL = 1
|
||||
|
@ -108,7 +94,7 @@ HAVE_RUNAHEAD = 1
|
|||
HAVE_SDL = 0
|
||||
HAVE_SDL2 = 1
|
||||
HAVE_SHADERPIPELINE = 1
|
||||
HAVE_STB_FONT = 0
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_STB_IMAGE = 1
|
||||
HAVE_STB_VORBIS = 1
|
||||
HAVE_STDIN_CMD = 1
|
||||
|
@ -120,7 +106,6 @@ HAVE_MATERIALUI = 0
|
|||
HAVE_XMB = 1
|
||||
HAVE_OZONE = 1
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_ZSTD = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_CHEATS = 1
|
||||
|
@ -128,25 +113,23 @@ HAVE_CHEEVOS = 1
|
|||
HAVE_LIBSHAKE = 1
|
||||
HAVE_UPDATE_ASSETS = 1
|
||||
HAVE_UPDATE_CORES = 1
|
||||
HAVE_UPDATE_CORE_INFO = 1
|
||||
HAVE_CORE_INFO_CACHE = 1
|
||||
|
||||
OS = Linux
|
||||
TARGET = retroarch
|
||||
|
||||
OBJ :=
|
||||
LINK := $(CC)
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS += -ffunction-sections -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DWEBOS=1 -MMD
|
||||
DEF_FLAGS += -Wall -Wno-unused-variable
|
||||
LIBS := -ldl -lz -lrt -pthread
|
||||
ARCHFLAGS := -mcpu=cortex-a9 -mtune=cortex-a53 -mfloat-abi=softfp
|
||||
CFLAGS := $(ARCHFLAGS)
|
||||
CXXFLAGS := $(ARCHFLAGS) -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS
|
||||
ASFLAGS := $(ARCHFLAGS)
|
||||
LDFLAGS := -Wl,-rpath=\$$ORIGIN/lib,--gc-sections
|
||||
CFLAGS :=
|
||||
CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS
|
||||
ASFLAGS :=
|
||||
LDFLAGS := -Wl,--gc-sections
|
||||
INCLUDE_DIRS = -I$(WEBOS_INC_DIR)
|
||||
LIBRARY_DIRS = -L$(WEBOS_USR_LIB_DIR)
|
||||
LIBRARY_DIRS = -L$(WEBOS_LIB_DIR)
|
||||
DEFINES := -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64 -UHAVE_STATIC_DUMMY
|
||||
DEFINES += -DHAVE_C99=1 -DHAVE_CXX=1 -D_GNU_SOURCE
|
||||
DEFINES += -DHAVE_GETOPT_LONG=1 -DHAVE_STRCASESTR=1 -DHAVE_DYNAMIC=1
|
||||
|
@ -154,20 +137,11 @@ DEFINES += -DHAVE_FILTERS_BUILTIN
|
|||
DEFINES += -DHAVE_SDL2
|
||||
DEFINES += -DHAVE_PULSE
|
||||
DEFINES += -DHAVE_NETWORKING -DHAVE_IFINFO -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
DEFINES += -DHAVE_NETWORKGAMEPAD
|
||||
DEFINES += -DHAVE_FREETYPE
|
||||
DEFINES += -DHAVE_UPDATE_CORE_INFO
|
||||
|
||||
PKG_CONFIG=pkg-config
|
||||
|
||||
SDL2_CFLAGS := $(shell $(PKG_CONFIG) --cflags sdl2)
|
||||
SDL2_LIBS := $(shell $(PKG_CONFIG) --libs sdl2)
|
||||
SDL2_CFLAGS := $(shell pkg-config --cflags sdl2)
|
||||
SDL2_LIBS := $(shell pkg-config --libs sdl2)
|
||||
OPENGLES_LIBS = -lGLESv2
|
||||
PULSE_LIBS = $(shell $(PKG_CONFIG) --libs libpulse)
|
||||
FREETYPE_CFLAGS := $(shell $(PKG_CONFIG) --cflags freetype2)
|
||||
FREETYPE_LIBS := $(shell $(PKG_CONFIG) --libs freetype2)
|
||||
FONTCONFIG_CFLAGS := $(shell $(PKG_CONFIG) --cflags fontconfig)
|
||||
FONTCONFIG_LIBS := $(shell $(PKG_CONFIG) --libs fontconfig)
|
||||
PULSE_LIBS = $(shell pkg-config --libs libpulse)
|
||||
MMAP_LIBS = -lc
|
||||
NEON_CFLAGS = -mfpu=neon
|
||||
NEON_ASFLAGS = -mfpu=neon
|
||||
|
@ -192,15 +166,13 @@ CXXFLAGS += $(DEF_FLAGS)
|
|||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
define APPINFO
|
||||
{
|
||||
"id": "$(APP_PACKAGE_NAME)",
|
||||
"id": "$(PACKAGE_NAME)",
|
||||
"version": "$(PACKAGE_VERSION)",
|
||||
"vendor": "webosbrew.org",
|
||||
"title": "RetroArch",
|
||||
|
@ -215,28 +187,6 @@ export APPINFO
|
|||
|
||||
all: $(TARGET) ipk
|
||||
|
||||
define INFO
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CPPFLAGS: $(CPPFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBRARY_DIRS: $(LIBRARY_DIRS)
|
||||
LIBS: $(LIBS)
|
||||
LINK: $(LINK)
|
||||
OBJCFLAGS: $(OBJCFLAGS)
|
||||
RARCH_OBJ: $(RARCH_OBJ)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
@ -266,41 +216,26 @@ $(OBJDIR)/%.o: %.S $(HEADERS)
|
|||
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -rf $(OBJDIR_BASE)
|
||||
$(Q)rm -f $(TARGET)
|
||||
$(Q)rm -f *.d
|
||||
$(Q)rm -rf SDL
|
||||
$(Q)rm -rf webos/*.ipk
|
||||
$(Q)rm -rf webos/dist
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
rm -rf webos/*.ipk
|
||||
rm -rf webos/dist
|
||||
|
||||
sdl2: $(TARGET)
|
||||
ifeq ($(ADD_SDL2_LIB), 1)
|
||||
@echo "Downloading SDL2 prebuilt"
|
||||
mkdir -p SDL
|
||||
wget -qO - $(SDL2_PREBUILT_ARCHIVE) | tar -C SDL -zxvf -
|
||||
endif
|
||||
|
||||
ipk: $(TARGET) sdl2
|
||||
ipk: $(TARGET)
|
||||
rm -rf webos/dist
|
||||
mkdir -p webos/dist/lib
|
||||
echo "$$APPINFO" > webos/dist/appinfo.json
|
||||
cp -t webos/dist -vf $(TARGET) webos/icon160.png
|
||||
cp -t webos/dist/lib -vf $(WEBOS_USR_LIB_DIR)/libstdc++.so.6
|
||||
cp -t webos/dist/lib -vf $(WEBOS_LIB_DIR)/libatomic.so.1
|
||||
ifeq ($(ADD_SDL2_LIB), 1)
|
||||
cp -t webos/dist/lib -vf SDL/lib/libSDL2-2.0.so.0
|
||||
endif
|
||||
ifneq ($(DEBUG), 1)
|
||||
cp -t webos/dist/lib -vf $(WEBOS_LIB_DIR)/libstdc++.so.6
|
||||
$(STRIP) webos/dist/$(TARGET)
|
||||
endif
|
||||
cd webos && ares-package dist
|
||||
|
||||
install: ipk
|
||||
ares-install webos/$(APP_PACKAGE_NAME)_$(PACKAGE_VERSION)_$(ARCH).ipk
|
||||
ares-install webos/$(PACKAGE_NAME)_$(PACKAGE_VERSION)_$(ARCH).ipk
|
||||
|
||||
launch: install
|
||||
ares-launch $(APP_PACKAGE_NAME)
|
||||
ares-launch com.retroarch
|
||||
|
||||
.PHONY: all clean ipk
|
||||
|
||||
|
|
47
Makefile.wii
47
Makefile.wii
|
@ -1,7 +1,6 @@
|
|||
ROOT_DIR := .
|
||||
DEPS_DIR := $(ROOT_DIR)/deps
|
||||
DEBUG ?= 0
|
||||
LOAD_WITHOUT_CORE_INFO ?= 0
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 0
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
|
@ -61,7 +60,6 @@ LIBS := $(WHOLE_START) $(LIB_CORE) $(WHOLE_END)
|
|||
libogc_platform := 1
|
||||
|
||||
EXTERNAL_LIBOGC ?= 0
|
||||
HAVE_OGG_OGC ?= 0
|
||||
GX_PTHREAD_LEGACY ?= 1
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
|
@ -106,10 +104,6 @@ ifeq ($(BIG_STACK), 1)
|
|||
LDFLAGS += -T bootstrap/gx/rvl.ld
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OGG_OGC), 1)
|
||||
LIBS += -L$(DEVKITPRO)/portlibs/ppc/lib -lvorbisfile -lvorbis -logg
|
||||
endif
|
||||
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
LIBS += -lfat
|
||||
endif
|
||||
|
@ -139,11 +133,11 @@ HAVE_RBMP := 1
|
|||
HAVE_RTGA := 1
|
||||
HAVE_IBXM := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_VIDEO_LAYOUT := 0
|
||||
HAVE_ZLIB := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_CONFIGFILE := 1
|
||||
HAVE_PATCH := 1
|
||||
HAVE_XDELTA := 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_CHEATS := 1
|
||||
HAVE_SCREENSHOTS := 1
|
||||
HAVE_REWIND := 1
|
||||
|
@ -167,9 +161,8 @@ HAVE_XMB := 0
|
|||
HAVE_OZONE := 0
|
||||
HAVE_RGUI := 1
|
||||
HAVE_MATERIALUI := 0
|
||||
HAVE_CHEEVOS := 1
|
||||
|
||||
CFLAGS += -DHAVE_SOCKET_LEGACY -DHAVE_CHEEVOS
|
||||
CFLAGS += -DHAVE_SOCKET_LEGACY
|
||||
|
||||
APP_BOOTER_DIR = wii/app_booter
|
||||
PLATOBJS := $(APP_BOOTER_DIR)/app_booter.binobj
|
||||
|
@ -180,7 +173,6 @@ endif
|
|||
|
||||
INCLUDE += -I./libretro-common/include \
|
||||
-Ideps \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ideps/stb
|
||||
CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(PLATCFLAGS) $(INCLUDE)
|
||||
|
||||
|
@ -266,32 +258,12 @@ else
|
|||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifeq ($(LOAD_WITHOUT_CORE_INFO),1)
|
||||
CFLAGS += -DLOAD_WITHOUT_CORE_INFO
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
OBJOUT = -o
|
||||
LINKOUT = -o
|
||||
LINK = $(CXX)
|
||||
|
||||
all: $(EXT_TARGET)
|
||||
|
||||
define INFO
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
OBJOUT: $(OBJOUT)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
%.dol: %.elf
|
||||
$(ELF2DOL) $< $@
|
||||
|
||||
|
@ -299,15 +271,13 @@ $(EXT_INTER_TARGET): $(OBJ)
|
|||
$(LINK) $(LINKOUT)$@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(PLATEXTRA) $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.o: %.S
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
$(CC) $(CFLAGS) -c $(OBJOUT)$@ $<
|
||||
|
||||
%.binobj: %.bin
|
||||
$(LD) -r -b binary $(OBJOUT)$@ $<
|
||||
|
@ -317,11 +287,10 @@ $(APP_BOOTER_DIR)/app_booter.bin:
|
|||
$(MAKE) -C $(APP_BOOTER_DIR)
|
||||
|
||||
clean:
|
||||
@$(if $(Q), echo $@,)
|
||||
$(Q)rm -f $(EXT_TARGET)
|
||||
$(Q)rm -f $(EXT_INTER_TARGET)
|
||||
$(Q)rm -f $(OBJ)
|
||||
$(Q)$(MAKE) -C $(APP_BOOTER_DIR) clean
|
||||
rm -f $(EXT_TARGET)
|
||||
rm -f $(EXT_INTER_TARGET)
|
||||
rm -f $(OBJ)
|
||||
$(MAKE) -C $(APP_BOOTER_DIR) clean
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ else
|
|||
DEFINES += -DHAVE_ONLINE_UPDATER
|
||||
DEFINES += -DHAVE_UPDATE_ASSETS
|
||||
DEFINES += -DHAVE_UPDATE_CORES
|
||||
DEFINES += -DHAVE_UPDATE_CORE_INFO
|
||||
DEFINES += -DHAVE_FILTERS_BUILTIN
|
||||
DEFINES += -DHAVE_SLANG
|
||||
DEFINES += -DHAVE_SHADERPIPELINE
|
||||
|
@ -143,7 +142,6 @@ endif
|
|||
HAVE_RBMP = 1
|
||||
HAVE_CONFIGFILE = 1
|
||||
HAVE_PATCH = 1
|
||||
HAVE_XDELTA = 0 # disabled because <lzma.h> isn't available (or we haven't figured out how to install it)
|
||||
HAVE_REWIND = 1
|
||||
HAVE_CHEATS = 1
|
||||
HAVE_MENU = 1
|
||||
|
@ -166,6 +164,7 @@ endif
|
|||
HAVE_OVERLAY = 1
|
||||
HAVE_SPIRV_CROSS = 1
|
||||
HAVE_SLANG = 1
|
||||
HAVE_VIDEO_LAYOUT = 0
|
||||
HAVE_DSP_FILTER = 1
|
||||
HAVE_VIDEO_FILTER = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
|
@ -203,7 +202,7 @@ INCDIRS += -Iwiiu
|
|||
INCDIRS += -Iwiiu/include
|
||||
|
||||
CFLAGS := -mcpu=750 -meabi -mhard-float
|
||||
CFLAGS += -Werror=implicit-function-declaration
|
||||
CFLAGS += -ffast-math -Werror=implicit-function-declaration
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
#CFLAGS += -fomit-frame-pointer -mword-relocations
|
||||
CFLAGS += -Wall
|
||||
|
@ -304,37 +303,6 @@ DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.depend
|
|||
|
||||
all: $(TARGETS)
|
||||
|
||||
define INFO
|
||||
AR: $(AR)
|
||||
ASFLAGS: $(ASFLAGS)
|
||||
BUILD_DIR: $(BUILD_DIR)
|
||||
CC: $(CC)
|
||||
CFLAGS: $(CFLAGS)
|
||||
CXX: $(CXX)
|
||||
CXXFLAGS: $(CXXFLAGS)
|
||||
DEFINES: $(DEFINES)
|
||||
DEPFLAGS: $(DEPFLAGS)
|
||||
ELF2RPL: $(ELF2RPL)
|
||||
HBL_ELF_LDFLAGS: $(HBL_ELF_LDFLAGS)
|
||||
HBL_ELF_OBJ: $(HBL_ELF_OBJ)
|
||||
INCDIRS: $(INCDIRS)
|
||||
LD: $(LD)
|
||||
LDFLAGS: $(LDFLAGS)
|
||||
LIBDIRS: $(LIBDIRS)
|
||||
LIBS: $(LIBS)
|
||||
MAKE: $(MAKE)
|
||||
OBJ: $(OBJ)
|
||||
RPX_LDFLAGS: $(RPX_LDFLAGS)
|
||||
RPX_OBJ: $(RPX_OBJ)
|
||||
TARGET: $(TARGET)
|
||||
endef
|
||||
export INFO
|
||||
|
||||
info:
|
||||
ifneq ($(V),1)
|
||||
@echo "$$INFO"
|
||||
endif
|
||||
|
||||
%: $(BUILD_DIR)/%
|
||||
cp $< $@
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ AVUTIL_LIBS := -lavutil
|
|||
SWSCALE_LIBS := -lswscale
|
||||
AVFORMAT_LIBS := -lavformat
|
||||
SWRESAMPLE_LIBS := -lswresample
|
||||
AVDEVICE_LIBS := -lavdevice
|
||||
FFMPEG_LIBS := -lws2_32 -lz
|
||||
endif
|
||||
|
||||
|
@ -100,6 +99,7 @@ OBJ :=
|
|||
LIBS := -lm
|
||||
DEFINES :=
|
||||
DEFINES += -I. -Ilibretro-common/include -Ilibretro-common/include/compat/zlib -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_OVERLAY
|
||||
#DEFINES += -DHAVE_VIDEO_LAYOUT
|
||||
LDFLAGS := -L. -static-libgcc
|
||||
|
||||
include Makefile.common
|
||||
|
@ -132,8 +132,8 @@ ifeq ($(DEBUG), 1)
|
|||
CFLAGS += -O0 -g
|
||||
CXXFLAGS += -O0 -g
|
||||
else
|
||||
CFLAGS += -O3
|
||||
CXXFLAGS += -O3
|
||||
CFLAGS += -O3 -ffast-math
|
||||
CXXFLAGS += -O3 -ffast-math
|
||||
endif
|
||||
|
||||
CFLAGS += $(DEF_FLAGS) -Wall -Wno-unused-result -Wno-unused-variable -I. -Ideps
|
||||
|
@ -170,7 +170,7 @@ $(OBJDIR)/%.o: %.cpp | $(dir $@)
|
|||
$(OBJDIR)/%.o: %.rc $(HEADERS)
|
||||
@-mkdir -p $(dir $@) || mkdir $(subst /,\,$(dir $@)) || echo .
|
||||
@$(if $(Q), $(shell echo echo WINDRES $<),)
|
||||
$(Q)$(WINDRES) $(DEFINES) -o $@ $<
|
||||
$(Q)$(WINDRES) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR)
|
||||
|
|
|
@ -6,7 +6,7 @@ good fbdev implementation. It is derived from the old Android GLES driver.
|
|||
|
||||
It was meant to be used on Cubieboard/Cubieboard2/Cubietruck, but it should not
|
||||
be used on an Odroid X2/U2/U3 where a superior solution (RetroArch exynos video driver) is available.
|
||||
Fbdev implementation on Odroid hardware is missing WAITFORVSYNC ioctl, so use Exynos driver there.
|
||||
Fbdev implementation on Odroid harware is missing WAITFORVSYNC ioctl, so use Exynos driver there.
|
||||
|
||||
This driver requires MALI r4p0 binary blobs for fbdev, and a kernel compatible with r4p0 binaries.
|
||||
|
||||
|
|
75
README.md
75
README.md
|
@ -64,53 +64,51 @@ RetroArch also emphasizes being easy to integrate into various launcher frontend
|
|||
## Platforms
|
||||
|
||||
RetroArch has been ported to the following platforms:
|
||||
- Android (2.x to most recent version)
|
||||
- Apple iOS
|
||||
- Apple macOS (PPC, x86-32 and x86-64)
|
||||
- Apple tvOS
|
||||
- Blackberry
|
||||
|
||||
- DOS
|
||||
- Windows 11
|
||||
- Windows 10
|
||||
- Windows 8
|
||||
- Windows 7
|
||||
- Windows Vista
|
||||
- Windows XP
|
||||
- Windows Millennium
|
||||
- Windows 2000
|
||||
- Windows NT 3.5
|
||||
- Windows 98
|
||||
- Windows 95
|
||||
- Linux
|
||||
- Emscripten (WebAssembly and JavaScript)
|
||||
- FreeBSD
|
||||
- Haiku
|
||||
- Linux
|
||||
- Original Microsoft Xbox
|
||||
- Microsoft Xbox 360 (Libxenon/XeXDK)
|
||||
- Microsoft Xbox One
|
||||
- Microsoft Xbox Series S/X
|
||||
- Miyoo
|
||||
- NetBSD
|
||||
- Nintendo NES/SNES Classic Edition
|
||||
- Nintendo GameCube
|
||||
- Nintendo Wii
|
||||
- Nintendo Switch
|
||||
- Nintendo Wii U
|
||||
- Nintendo 3DS/2DS
|
||||
- OpenBSD
|
||||
- OpenDingux
|
||||
- Haiku
|
||||
- Solaris
|
||||
- Apple macOS (PPC, x86-32 and x86-64)
|
||||
- Apple iOS
|
||||
- Apple tvOS
|
||||
- Android (2.x to most recent version)
|
||||
- PlayStation2
|
||||
- PlayStation3
|
||||
- PlayStation4
|
||||
- PlayStation Portable
|
||||
- PlayStation Vita
|
||||
- Original Microsoft Xbox
|
||||
- Microsoft Xbox 360 (Libxenon/XeXDK)
|
||||
- Microsoft Xbox One
|
||||
- Microsoft Xbox Series S/X
|
||||
- Nintendo GameCube
|
||||
- Nintendo Wii
|
||||
- Nintendo Wii U
|
||||
- Nintendo 3DS/2DS
|
||||
- Nintendo Switch
|
||||
- Nintendo NES/SNES Classic Edition
|
||||
- Raspberry Pi
|
||||
- ReactOS
|
||||
- Redox OS
|
||||
- RetroFW
|
||||
- Blackberry
|
||||
- OpenDingux
|
||||
- Miyoo
|
||||
- RS90
|
||||
- SerenityOS
|
||||
- Solaris
|
||||
- Windows NT 3.5
|
||||
- Windows 95
|
||||
- Windows 98
|
||||
- Windows 2000
|
||||
- Windows XP
|
||||
- Windows Millennium
|
||||
- Windows Vista
|
||||
- Windows 7
|
||||
- Windows 8
|
||||
- Windows 10
|
||||
- Windows 11
|
||||
- RetroFW
|
||||
|
||||
## Dependencies (PC)
|
||||
|
||||
|
@ -124,7 +122,7 @@ following dependencies come as recommended:
|
|||
- GL headers / Vulkan headers
|
||||
- X11 headers and libs, or EGL/KMS/GBM
|
||||
|
||||
OSX port of RetroArch requires latest versions of Xcode to build.
|
||||
OSX port of RetroArch requires latest versions of XCode to build.
|
||||
|
||||
RetroArch can utilize these libraries if enabled:
|
||||
|
||||
|
@ -141,7 +139,6 @@ RetroArch needs at least one of these audio driver libraries:
|
|||
- JACK
|
||||
- SDL
|
||||
- PulseAudio
|
||||
- PipeWire
|
||||
- XAudio2 (Win32, Xbox 360)
|
||||
- DirectSound (Win32, Xbox 1)
|
||||
- CoreAudio (OSX, iOS)
|
||||
|
@ -205,7 +202,7 @@ A sample configuration file is installed to `/etc/retroarch.cfg`. This is the sy
|
|||
RetroArch will on startup create a config file in `$XDG\_CONFIG\_HOME/retroarch/retroarch.cfg` if it does not exist.
|
||||
Users only need to configure a certain option if the desired value deviates from the value defined in config.def.h.
|
||||
|
||||
To configure joypads, use the built-in menu or manually configure them in `retroarch.cfg`.
|
||||
To configure joypads, use the built-in menu or the `retroarch-joyconfig` command-line tool.
|
||||
|
||||
## Compiling and installing
|
||||
|
||||
|
@ -338,7 +335,7 @@ The links below belong to our official channels. Links other than this may have
|
|||
- [YouTube Topic](https://www.youtube.com/channel/UC5q007PYyQPgin0HHbzF0zQ)
|
||||
- [Patreon](https://www.patreon.com/libretro)
|
||||
- [BOUNTYSOURCE](https://www.bountysource.com/teams/libretro/issues)
|
||||
- [Discord](https://discord.com/invite/VZ2b7wghxR)
|
||||
- [Discord](https://discord.gg/27Xxm2h)
|
||||
- [Teespring](https://teespring.com/stores/retroarch)
|
||||
- [Documentation](https://docs.libretro.com/)
|
||||
- [Forum](https://forums.libretro.com/)
|
||||
|
|
26
SECURITY.md
26
SECURITY.md
|
@ -1,26 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
## Reasonable expectations
|
||||
|
||||
RetroArch is a frontend for the libretro API. The main functionality is fulfilled by invoking other binary libraries ("cores") which are not restricted by RetroArch in any way. Cores are able to read/write/delete files, spawn processes, communicate over the network. Also, source for cores is not necessarily in control by libretro team, and core binaries / RetroArch binaries are not signed. For this reason, it is a bad idea to use RetroArch or any other libretro frontend on security critical systems.
|
||||
|
||||
Also, RetroArch and cores have been packaged in several ways. Content on the [official download site](https://buildbot.libretro.com/) is built from a direct mirror of the original RetroArch and core repositories, no binaries are reused. Note that source for the core repositories may be outside libretro team control.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
For most delivery channels, libretro team does not have control over the version. The exceptions are:
|
||||
- [official download site](https://buildbot.libretro.com/)
|
||||
- Steam release
|
||||
- Apple App Store release
|
||||
- various Android app store releases
|
||||
- note that Google Play Store version is years behind and can not be updated
|
||||
|
||||
You may report vulnerability against any recent version, but be reasonable.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report security vulnerabilities at libretro@gmail.com
|
||||
|
||||
## Possible remediation
|
||||
|
||||
Due to the variety of delivery channels, RetroArch team can not recall any given version universally. Security fixes are accepted for next release, and notice may be posted in the channels controlled by RetroArch team, depending on the severity assessed by RetroArch team.
|
216
ai/game_ai.c
216
ai/game_ai.c
|
@ -1,216 +0,0 @@
|
|||
#include "game_ai.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <retro_assert.h>
|
||||
#include <compat/strl.h>
|
||||
|
||||
#include "../deps/game_ai_lib/GameAI.h"
|
||||
|
||||
#define GAME_AI_MAX_PLAYERS 2
|
||||
|
||||
void * ga = NULL;
|
||||
volatile void * g_ram_ptr = NULL;
|
||||
volatile int g_ram_size = 0;
|
||||
volatile signed short int g_buttons_bits[GAME_AI_MAX_PLAYERS] = {0};
|
||||
volatile int g_frameCount = 0;
|
||||
volatile char game_ai_lib_path[1024] = {0};
|
||||
volatile char g_game_name[1024] = {0};
|
||||
retro_log_printf_t g_log = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
HINSTANCE g_lib_handle = NULL;
|
||||
#else
|
||||
void * g_lib_handle = NULL;
|
||||
#endif
|
||||
|
||||
/* GameAI Lib API*/
|
||||
create_game_ai_t create_game_ai = NULL;
|
||||
destroy_game_ai_t destroy_game_ai = NULL;
|
||||
game_ai_lib_init_t game_ai_lib_init = NULL;
|
||||
game_ai_lib_think_t game_ai_lib_think = NULL;
|
||||
game_ai_lib_set_show_debug_t game_ai_lib_set_show_debug = NULL;
|
||||
game_ai_lib_set_debug_log_t game_ai_lib_set_debug_log = NULL;
|
||||
|
||||
/* Helper functions */
|
||||
void game_ai_debug_log(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list vp;
|
||||
va_start(vp, fmt);
|
||||
|
||||
if (g_log)
|
||||
g_log((enum retro_log_level)level, fmt, vp);
|
||||
|
||||
va_end(vp);
|
||||
}
|
||||
|
||||
void array_to_bits_16(volatile signed short *result, const bool b[16])
|
||||
{
|
||||
for (int bit = 0; bit <= 15; bit++)
|
||||
*result |= b[bit] ? (1 << bit) : 0;
|
||||
}
|
||||
|
||||
/* Interface to RA */
|
||||
|
||||
signed short int game_ai_input(unsigned int port, unsigned int device,
|
||||
unsigned int idx, unsigned int id, signed short int result)
|
||||
{
|
||||
if (ga && (port < GAME_AI_MAX_PLAYERS))
|
||||
return g_buttons_bits[port];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void game_ai_init(void)
|
||||
{
|
||||
if (!create_game_ai)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
|
||||
|
||||
g_lib_handle = LoadLibrary(TEXT("game_ai.dll"));
|
||||
retro_assert(hinstLib);
|
||||
|
||||
char full_module_path[MAX_PATH];
|
||||
DWORD dwLen = GetModuleFileNameA(g_lib_handle, static_cast<char*>(&full_module_path), MAX_PATH);
|
||||
|
||||
if (hinstLib)
|
||||
{
|
||||
create_game_ai = (create_game_ai_t) GetProcAddress(hinstLib, "create_game_ai");
|
||||
retro_assert(create_game_ai);
|
||||
|
||||
destroy_game_ai = (destroy_game_ai_t) GetProcAddress(hinstLib, "destroy_game_ai");
|
||||
retro_assert(destroy_game_ai);
|
||||
|
||||
game_ai_lib_init = (game_ai_lib_init_t) GetProcAddress(hinstLib, "game_ai_lib_init");
|
||||
retro_assert(game_ai_lib_init);
|
||||
|
||||
game_ai_lib_think = (game_ai_lib_think_t) GetProcAddress(hinstLib, "game_ai_lib_think");
|
||||
retro_assert(game_ai_lib_think);
|
||||
|
||||
game_ai_lib_set_show_debug = (game_ai_lib_set_show_debug_t) GetProcAddress(hinstLib, "game_ai_lib_set_show_debug");
|
||||
retro_assert(game_ai_lib_set_show_debug);
|
||||
|
||||
game_ai_lib_set_debug_log = (game_ai_lib_set_debug_log_t) GetProcAddress(hinstLib, "game_ai_lib_set_debug_log");
|
||||
retro_assert(game_ai_lib_set_debug_log);
|
||||
}
|
||||
#else
|
||||
g_lib_handle = dlopen("./libgame_ai.so", RTLD_NOW);
|
||||
retro_assert(g_lib_handle);
|
||||
|
||||
if (g_lib_handle)
|
||||
{
|
||||
dlinfo(g_lib_handle, RTLD_DI_ORIGIN, (void *) &game_ai_lib_path);
|
||||
|
||||
create_game_ai = (create_game_ai_t)(dlsym(g_lib_handle, "create_game_ai"));
|
||||
retro_assert(create_game_ai);
|
||||
|
||||
destroy_game_ai = (destroy_game_ai_t)(dlsym(g_lib_handle, "destroy_game_ai"));
|
||||
retro_assert(destroy_game_ai);
|
||||
|
||||
game_ai_lib_init = (game_ai_lib_init_t)(dlsym(g_lib_handle, "game_ai_lib_init"));
|
||||
retro_assert(game_ai_lib_init);
|
||||
|
||||
game_ai_lib_think = (game_ai_lib_think_t)(dlsym(g_lib_handle, "game_ai_lib_think"));
|
||||
retro_assert(game_ai_lib_think);
|
||||
|
||||
game_ai_lib_set_show_debug = (game_ai_lib_set_show_debug_t)(dlsym(g_lib_handle, "game_ai_lib_set_show_debug"));
|
||||
retro_assert(game_ai_lib_set_show_debug);
|
||||
|
||||
game_ai_lib_set_debug_log = (game_ai_lib_set_debug_log_t)(dlsym(g_lib_handle, "game_ai_lib_set_debug_log"));
|
||||
retro_assert(game_ai_lib_set_debug_log);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void game_ai_shutdown(void)
|
||||
{
|
||||
if (g_lib_handle)
|
||||
{
|
||||
if (ga)
|
||||
{
|
||||
destroy_game_ai(ga);
|
||||
ga = NULL;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(g_lib_handle);
|
||||
#else
|
||||
dlclose(g_lib_handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void game_ai_load(const char * name, void * ram_ptr, int ram_size, retro_log_printf_t log)
|
||||
{
|
||||
strcpy((char *) &g_game_name[0], name);
|
||||
|
||||
g_ram_ptr = ram_ptr;
|
||||
g_ram_size = ram_size;
|
||||
|
||||
g_log = log;
|
||||
|
||||
if (ga)
|
||||
{
|
||||
destroy_game_ai(ga);
|
||||
ga = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void game_ai_think(bool override_p1, bool override_p2, bool show_debug,
|
||||
const void *frame_data, unsigned int frame_width, unsigned int frame_height,
|
||||
unsigned int frame_pitch, unsigned int pixel_format)
|
||||
{
|
||||
if (ga)
|
||||
game_ai_lib_set_show_debug(ga, show_debug);
|
||||
|
||||
if (!ga && g_ram_ptr)
|
||||
{
|
||||
ga = create_game_ai((char *) &g_game_name[0]);
|
||||
retro_assert(ga);
|
||||
|
||||
if (ga)
|
||||
{
|
||||
char data_path[1024] = {0};
|
||||
strcpy(&data_path[0], (char *)game_ai_lib_path);
|
||||
strcat(&data_path[0], "/data/");
|
||||
strcat(&data_path[0], (char *)g_game_name);
|
||||
|
||||
game_ai_lib_init(ga, (void *) g_ram_ptr, g_ram_size);
|
||||
game_ai_lib_set_debug_log(ga, game_ai_debug_log);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_frameCount >= (GAMEAI_SKIPFRAMES - 1))
|
||||
{
|
||||
if (ga)
|
||||
{
|
||||
bool b[GAMEAI_MAX_BUTTONS] = {0};
|
||||
|
||||
g_buttons_bits[0]=0;
|
||||
g_buttons_bits[1]=0;
|
||||
|
||||
if (override_p1)
|
||||
{
|
||||
game_ai_lib_think(ga, b, 0, frame_data, frame_width, frame_height, frame_pitch, pixel_format);
|
||||
array_to_bits_16(&g_buttons_bits[0], b);
|
||||
}
|
||||
|
||||
if (override_p2)
|
||||
{
|
||||
game_ai_lib_think(ga, b, 1, frame_data, frame_width, frame_height, frame_pitch, pixel_format);
|
||||
array_to_bits_16(&g_buttons_bits[1], b);
|
||||
}
|
||||
}
|
||||
g_frameCount=0;
|
||||
}
|
||||
else
|
||||
g_frameCount++;
|
||||
}
|
|
@ -21,21 +21,25 @@
|
|||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 512
|
||||
|
||||
/* So we don't get complete line-noise when fast-forwarding audio. */
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
|
||||
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_STREAMS 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 8)
|
||||
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 5)
|
||||
|
||||
/* Do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
|
||||
/* do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
|
||||
enum audio_mixer_system_slot
|
||||
{
|
||||
AUDIO_MIXER_SYSTEM_SLOT_OK = AUDIO_MIXER_MAX_STREAMS,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_CANCEL,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_NOTICE,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_NOTICE_BACK,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_BGM,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_ACHIEVEMENT_UNLOCK,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_UP,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_DOWN
|
||||
AUDIO_MIXER_SYSTEM_SLOT_ACHIEVEMENT_UNLOCK
|
||||
};
|
||||
|
||||
enum audio_action
|
||||
|
@ -71,93 +75,6 @@ enum audio_mixer_state
|
|||
AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL
|
||||
};
|
||||
|
||||
/**
|
||||
* Bit flags that describe the current state of the audio driver.
|
||||
*/
|
||||
enum audio_driver_state_flags
|
||||
{
|
||||
/**
|
||||
* Indicates that the driver was successfully created
|
||||
* and is currently valid.
|
||||
* You may submit samples for output at any time.
|
||||
*
|
||||
* This flag does \em not mean that the player will hear anything;
|
||||
* the driver might be suspended.
|
||||
*
|
||||
* @see AUDIO_FLAG_SUSPENDED
|
||||
*/
|
||||
AUDIO_FLAG_ACTIVE = (1 << 0),
|
||||
|
||||
/**
|
||||
* Indicates that the audio driver outputs floating-point samples,
|
||||
* as opposed to integer samples.
|
||||
*
|
||||
* All audio is sent through the resampler,
|
||||
* which operates on floating-point samples.
|
||||
*
|
||||
* If this flag is set, then the resampled output doesn't need
|
||||
* to be converted back to \c int16_t format.
|
||||
*
|
||||
* This won't affect the audio that the core writes;
|
||||
* either way, it's supposed to output \c int16_t samples.
|
||||
*
|
||||
* This flag won't be set if the selected audio driver
|
||||
* doesn't support (or is configured to not use) \c float samples.
|
||||
*
|
||||
* @see audio_driver_t::use_float
|
||||
*/
|
||||
AUDIO_FLAG_USE_FLOAT = (1 << 1),
|
||||
|
||||
/**
|
||||
* Indicates that the audio driver is not currently rendering samples,
|
||||
* although it's valid and can be resumed.
|
||||
*
|
||||
* Usually set when RetroArch needs to simulate audio output
|
||||
* without actually rendering samples (e.g. runahead),
|
||||
* or when reinitializing the driver.
|
||||
*
|
||||
* Samples will still be accepted, but they will be silently dropped.
|
||||
*/
|
||||
AUDIO_FLAG_SUSPENDED = (1 << 2),
|
||||
|
||||
/**
|
||||
* Indicates that the audio mixer is available
|
||||
* and can mix one or more audio streams.
|
||||
*
|
||||
* Will not be set if RetroArch was built without \c HAVE_AUDIOMIXER.
|
||||
*/
|
||||
AUDIO_FLAG_MIXER_ACTIVE = (1 << 3),
|
||||
|
||||
/**
|
||||
* Indicates that the frontend will never need audio from the core,
|
||||
* usually when runahead is active.
|
||||
*
|
||||
* When set, any audio received by the core will not be processed.
|
||||
*
|
||||
* Will not be set if RetroArch was built without \c HAVE_RUNAHEAD.
|
||||
*
|
||||
* @see RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE
|
||||
*/
|
||||
AUDIO_FLAG_HARD_DISABLE = (1 << 4),
|
||||
|
||||
/**
|
||||
* Indicates that audio rate control is enabled.
|
||||
* This means that the audio system will adjust the rate at which
|
||||
* it sends samples to the driver,
|
||||
* minimizing the occurrences of buffer overrun or underrun.
|
||||
*
|
||||
* @see audio_driver_t::write_avail
|
||||
* @see audio_driver_t::buffer_size
|
||||
*/
|
||||
AUDIO_FLAG_CONTROL = (1 << 5),
|
||||
|
||||
/**
|
||||
* Indicates that the audio driver is forcing gain to 0.
|
||||
* Used for temporary rewind and fast-forward muting.
|
||||
*/
|
||||
AUDIO_FLAG_MUTED = (1 << 6)
|
||||
};
|
||||
|
||||
typedef struct audio_statistics
|
||||
{
|
||||
unsigned samples;
|
||||
|
|
1422
audio/audio_driver.c
1422
audio/audio_driver.c
File diff suppressed because it is too large
Load Diff
|
@ -110,21 +110,12 @@ typedef struct audio_driver
|
|||
* Unless said otherwise with set_nonblock_state(), all writes
|
||||
* are blocking, and it should block till it has written all frames.
|
||||
*/
|
||||
ssize_t (*write)(void *data, const void *s, size_t len);
|
||||
ssize_t (*write)(void *data, const void *buf, size_t size);
|
||||
|
||||
/**
|
||||
* Temporarily pauses the audio driver.
|
||||
*
|
||||
* @param data Opaque handle to the audio driver context
|
||||
* that was returned by \c init.
|
||||
* @return \c true if the audio driver was successfully paused,
|
||||
* \c false if there was an error.
|
||||
**/
|
||||
/* Temporarily pauses the audio driver. */
|
||||
bool (*stop)(void *data);
|
||||
|
||||
/**
|
||||
* Resumes audio driver from the paused state.
|
||||
**/
|
||||
/* Resumes audio driver from the paused state. */
|
||||
bool (*start)(void *data, bool is_shutdown);
|
||||
|
||||
/* Is the audio driver currently running? */
|
||||
|
@ -139,7 +130,7 @@ typedef struct audio_driver
|
|||
* */
|
||||
void (*set_nonblock_state)(void *data, bool toggle);
|
||||
|
||||
/* Stops and frees driver. */
|
||||
/* Stops and frees driver data. */
|
||||
void (*free)(void *data);
|
||||
|
||||
/* Defines if driver will take standard floating point samples,
|
||||
|
@ -167,53 +158,41 @@ typedef struct audio_driver
|
|||
size_t (*buffer_size)(void *data);
|
||||
} audio_driver_t;
|
||||
|
||||
enum audio_driver_state_flags
|
||||
{
|
||||
AUDIO_FLAG_ACTIVE = (1 << 0),
|
||||
AUDIO_FLAG_USE_FLOAT = (1 << 1),
|
||||
AUDIO_FLAG_SUSPENDED = (1 << 2),
|
||||
AUDIO_FLAG_MIXER_ACTIVE = (1 << 3),
|
||||
AUDIO_FLAG_HARD_DISABLE = (1 << 4),
|
||||
AUDIO_FLAG_CONTROL = (1 << 5)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double src_ratio_orig;
|
||||
double src_ratio_curr;
|
||||
double source_ratio_original;
|
||||
double source_ratio_current;
|
||||
|
||||
uint64_t free_samples_count;
|
||||
|
||||
struct string_list *devices_list;
|
||||
|
||||
/**
|
||||
* A scratch buffer for audio output to be processed,
|
||||
* up to (but excluding) the point where it's converted to 16-bit audio
|
||||
* to give to the driver.
|
||||
*/
|
||||
float *output_samples_buf;
|
||||
size_t output_samples_buf_length;
|
||||
#ifdef HAVE_REWIND
|
||||
int16_t *rewind_buf;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A scratch buffer for processed audio output to be converted to 16-bit,
|
||||
* so that it can be sent to the driver.
|
||||
*/
|
||||
int16_t *output_samples_conv_buf;
|
||||
size_t output_samples_conv_buf_length;
|
||||
#ifdef HAVE_DSP_FILTER
|
||||
retro_dsp_filter_t *dsp;
|
||||
#endif
|
||||
const retro_resampler_t *resampler;
|
||||
|
||||
void *resampler_data;
|
||||
|
||||
/**
|
||||
* The current audio driver.
|
||||
*/
|
||||
const audio_driver_t *current_audio;
|
||||
|
||||
void *context_audio_data;
|
||||
|
||||
/**
|
||||
* Scratch buffer for preparing data for the resampler
|
||||
*/
|
||||
float *input_data;
|
||||
size_t input_data_length;
|
||||
#ifdef HAVE_AUDIOMIXER
|
||||
struct audio_mixer_stream mixer_streams[AUDIO_MIXER_MAX_SYSTEM_STREAMS];
|
||||
struct audio_mixer_stream
|
||||
mixer_streams[AUDIO_MIXER_MAX_SYSTEM_STREAMS];
|
||||
#endif
|
||||
struct retro_audio_callback callback; /* ptr alignment */
|
||||
/* ptr alignment */
|
||||
|
@ -228,7 +207,8 @@ typedef struct
|
|||
size_t buffer_size;
|
||||
size_t data_ptr;
|
||||
|
||||
unsigned free_samples_buf[AUDIO_BUFFER_FREE_SAMPLES_COUNT];
|
||||
unsigned free_samples_buf[
|
||||
AUDIO_BUFFER_FREE_SAMPLES_COUNT];
|
||||
|
||||
#ifdef HAVE_AUDIOMIXER
|
||||
float mixer_volume_gain;
|
||||
|
@ -248,11 +228,6 @@ typedef struct
|
|||
#ifdef HAVE_AUDIOMIXER
|
||||
bool mixer_mute_enable;
|
||||
#endif
|
||||
|
||||
/* Sample the flush delta-time when fast forwarding to find the correct ratio. */
|
||||
retro_time_t last_flush_time;
|
||||
/* Exponential moving average */
|
||||
retro_time_t avg_flush_delta;
|
||||
} audio_driver_state_t;
|
||||
|
||||
bool audio_driver_enable_callback(void);
|
||||
|
@ -292,8 +267,6 @@ void audio_driver_mixer_play_stream(unsigned i);
|
|||
|
||||
void audio_driver_mixer_play_menu_sound(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_scroll_sound(bool direction_up);
|
||||
|
||||
void audio_driver_mixer_play_menu_sound_looped(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_sequential(unsigned i);
|
||||
|
@ -325,6 +298,44 @@ bool audio_driver_stop(void);
|
|||
bool audio_driver_is_ai_service_speech_running(void);
|
||||
#endif
|
||||
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_audioio;
|
||||
extern audio_driver_t audio_oss;
|
||||
extern audio_driver_t audio_alsa;
|
||||
extern audio_driver_t audio_alsathread;
|
||||
extern audio_driver_t audio_tinyalsa;
|
||||
extern audio_driver_t audio_roar;
|
||||
extern audio_driver_t audio_openal;
|
||||
extern audio_driver_t audio_opensl;
|
||||
extern audio_driver_t audio_jack;
|
||||
extern audio_driver_t audio_sdl;
|
||||
extern audio_driver_t audio_xa;
|
||||
extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_wasapi;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_coreaudio3;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
extern audio_driver_t audio_ax;
|
||||
extern audio_driver_t audio_psp;
|
||||
extern audio_driver_t audio_ps2;
|
||||
extern audio_driver_t audio_ctr_csnd;
|
||||
extern audio_driver_t audio_ctr_dsp;
|
||||
#ifdef HAVE_THREADS
|
||||
extern audio_driver_t audio_ctr_dsp_thread;
|
||||
#endif
|
||||
extern audio_driver_t audio_switch;
|
||||
extern audio_driver_t audio_switch_thread;
|
||||
extern audio_driver_t audio_switch_libnx_audren;
|
||||
extern audio_driver_t audio_switch_libnx_audren_thread;
|
||||
extern audio_driver_t audio_rwebaudio;
|
||||
|
||||
audio_driver_state_t *audio_state_get_ptr(void);
|
||||
|
||||
extern audio_driver_t *audio_drivers[];
|
||||
|
||||
/**
|
||||
* audio_compute_buffer_statistics:
|
||||
*
|
||||
|
@ -333,12 +344,23 @@ bool audio_driver_is_ai_service_speech_running(void);
|
|||
**/
|
||||
bool audio_compute_buffer_statistics(audio_statistics_t *stats);
|
||||
|
||||
bool audio_driver_init_internal(void *data, bool audio_cb_inited);
|
||||
float audio_driver_monitor_adjust_system_rates(
|
||||
double input_sample_rate,
|
||||
double input_fps,
|
||||
float video_refresh_rate,
|
||||
unsigned video_swap_interval,
|
||||
float audio_max_timing_skew);
|
||||
|
||||
bool audio_driver_init_internal(
|
||||
void *settings_data,
|
||||
bool audio_cb_inited);
|
||||
|
||||
bool audio_driver_deinit(void);
|
||||
|
||||
bool audio_driver_find_driver(const char *audio_drv,
|
||||
const char *prefix, bool verbosity_enabled);
|
||||
bool audio_driver_find_driver(
|
||||
void *settings_data,
|
||||
const char *prefix,
|
||||
bool verbosity_enabled);
|
||||
|
||||
/**
|
||||
* audio_driver_sample:
|
||||
|
@ -392,48 +414,6 @@ size_t audio_driver_sample_batch_rewind(
|
|||
void audio_driver_menu_sample(void);
|
||||
#endif
|
||||
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_audioio;
|
||||
extern audio_driver_t audio_oss;
|
||||
extern audio_driver_t audio_alsa;
|
||||
extern audio_driver_t audio_alsathread;
|
||||
extern audio_driver_t audio_tinyalsa;
|
||||
extern audio_driver_t audio_roar;
|
||||
extern audio_driver_t audio_openal;
|
||||
extern audio_driver_t audio_opensl;
|
||||
extern audio_driver_t audio_jack;
|
||||
extern audio_driver_t audio_sdl;
|
||||
extern audio_driver_t audio_xa;
|
||||
extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_pipewire;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_wasapi;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_coreaudio3;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
extern audio_driver_t audio_ax;
|
||||
extern audio_driver_t audio_psp;
|
||||
extern audio_driver_t audio_ps2;
|
||||
extern audio_driver_t audio_ctr_csnd;
|
||||
extern audio_driver_t audio_ctr_dsp;
|
||||
#ifdef HAVE_THREADS
|
||||
extern audio_driver_t audio_ctr_dsp_thread;
|
||||
#endif
|
||||
extern audio_driver_t audio_switch;
|
||||
extern audio_driver_t audio_switch_thread;
|
||||
extern audio_driver_t audio_switch_libnx_audren;
|
||||
extern audio_driver_t audio_switch_libnx_audren_thread;
|
||||
extern audio_driver_t audio_rwebaudio;
|
||||
extern audio_driver_t audio_audioworklet;
|
||||
|
||||
audio_driver_state_t *audio_state_get_ptr(void);
|
||||
|
||||
const char *audio_driver_get_ident(void);
|
||||
|
||||
extern audio_driver_t *audio_drivers[];
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* __AUDIO_DRIVER__H */
|
||||
|
|
|
@ -51,10 +51,6 @@ typedef struct audio_thread
|
|||
|
||||
} audio_thread_t;
|
||||
|
||||
/**
|
||||
* The thread that manages the life of the audio driver.
|
||||
* The wrapped audio driver lives and dies with this function.
|
||||
*/
|
||||
static void audio_thread_loop(void *data)
|
||||
{
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
|
@ -117,10 +113,6 @@ static void audio_thread_loop(void *data)
|
|||
thr->driver->free(thr->driver_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets the audio thread finish what it's doing,
|
||||
* then stops it from doing further work.
|
||||
*/
|
||||
static void audio_thread_block(audio_thread_t *thr)
|
||||
{
|
||||
if (!thr)
|
||||
|
@ -141,19 +133,15 @@ static void audio_thread_block(audio_thread_t *thr)
|
|||
slock_unlock(thr->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes the audio thread.
|
||||
* This function is called from the main thread.
|
||||
*/
|
||||
static void audio_thread_unblock(audio_thread_t *thr)
|
||||
{
|
||||
if (!thr)
|
||||
return;
|
||||
|
||||
slock_lock(thr->lock); /* Prevent the audio thread from touching this flag... */
|
||||
thr->stopped = false; /* ...so that the main thread can do it. */
|
||||
scond_signal(thr->cond); /* Then let the audio thread know that it's okay to resume. */
|
||||
slock_unlock(thr->lock); /* "As you were." */
|
||||
slock_lock(thr->lock);
|
||||
thr->stopped = false;
|
||||
scond_signal(thr->cond);
|
||||
slock_unlock(thr->lock);
|
||||
}
|
||||
|
||||
static void audio_thread_free(void *data)
|
||||
|
@ -165,15 +153,13 @@ static void audio_thread_free(void *data)
|
|||
|
||||
if (thr->thread)
|
||||
{
|
||||
slock_lock(thr->lock); /* Let the audio thread finish what it's doing... */
|
||||
thr->stopped = false; /* Then stop it. "You're fired." */
|
||||
slock_lock(thr->lock);
|
||||
thr->stopped = false;
|
||||
thr->alive = false;
|
||||
scond_signal(thr->cond); /* Let the thread know it's okay to continue */
|
||||
slock_unlock(thr->lock); /* At this point, it will exit its loop. */
|
||||
scond_signal(thr->cond);
|
||||
slock_unlock(thr->lock);
|
||||
|
||||
sthread_join(thr->thread);
|
||||
/* Wait for the audio thread to exit, ensure that it's really dead.
|
||||
* (It will call the wrapped driver's free() function.) */
|
||||
}
|
||||
|
||||
if (thr->lock)
|
||||
|
@ -181,7 +167,6 @@ static void audio_thread_free(void *data)
|
|||
if (thr->cond)
|
||||
scond_free(thr->cond);
|
||||
free(thr);
|
||||
/* The audio driver is done, clean up the thread itself. */
|
||||
}
|
||||
|
||||
static bool audio_thread_alive(void *data)
|
||||
|
@ -206,9 +191,6 @@ static bool audio_thread_stop(void *data)
|
|||
if (!thr)
|
||||
return false;
|
||||
|
||||
/* Don't immediately call stop on the driver;
|
||||
* let the audio thread finish its current loop iteration.
|
||||
* It will call stop then. */
|
||||
audio_thread_block(thr);
|
||||
thr->is_paused = true;
|
||||
|
||||
|
@ -237,8 +219,6 @@ static void audio_thread_set_nonblock_state(void *data, bool state)
|
|||
{
|
||||
(void)data;
|
||||
(void)state;
|
||||
/* Ignored, because blocking state is irrelevant
|
||||
* when audio is running on a separate thread. */
|
||||
}
|
||||
|
||||
static bool audio_thread_use_float(void *data)
|
||||
|
@ -249,25 +229,29 @@ static bool audio_thread_use_float(void *data)
|
|||
return thr->use_float;
|
||||
}
|
||||
|
||||
static ssize_t audio_thread_write(void *data, const void *s, size_t len)
|
||||
static ssize_t audio_thread_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t _len;
|
||||
ssize_t ret;
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return 0;
|
||||
_len = thr->driver->write(thr->driver_data, s, len);
|
||||
if (_len < 0)
|
||||
|
||||
ret = thr->driver->write(thr->driver_data, buf, size);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
slock_lock(thr->lock);
|
||||
thr->alive = false;
|
||||
scond_signal(thr->cond);
|
||||
slock_unlock(thr->lock);
|
||||
}
|
||||
return _len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const audio_driver_t audio_thread = {
|
||||
NULL, /* No need to wrap init, it's called at the start of the thread loop */
|
||||
NULL,
|
||||
audio_thread_write,
|
||||
audio_thread_stop,
|
||||
audio_thread_start,
|
||||
|
@ -278,8 +262,6 @@ static const audio_driver_t audio_thread = {
|
|||
"audio-thread",
|
||||
NULL, /* No point in using rate control with threaded audio. */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,484 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 Daniel De Matteis
|
||||
* Copyright (C) 2023 Jesse Talavera-Greenberg
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <lists/string_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <asm-generic/errno.h>
|
||||
|
||||
#include "alsa.h"
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
int alsa_init_pcm(snd_pcm_t **pcm,
|
||||
const char* device,
|
||||
snd_pcm_stream_t stream,
|
||||
unsigned rate,
|
||||
unsigned latency,
|
||||
unsigned channels,
|
||||
alsa_stream_info_t *stream_info,
|
||||
unsigned *new_rate,
|
||||
int mode)
|
||||
{
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
snd_pcm_sw_params_t *sw_params = NULL;
|
||||
unsigned latency_usec = latency * 1000;
|
||||
unsigned periods = 4;
|
||||
unsigned orig_rate = rate;
|
||||
const char *alsa_dev = device ? device : "default";
|
||||
int errnum = 0;
|
||||
|
||||
RARCH_DBG("[ALSA] Requesting device \"%s\" for %s stream...\n", alsa_dev, snd_pcm_stream_name(stream));
|
||||
|
||||
if ((errnum = snd_pcm_open(pcm, alsa_dev, stream, mode)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to open %s stream on device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
alsa_dev,
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_malloc(¶ms)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate hardware parameters: %s.\n",
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_any(*pcm, params)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to query hardware parameters from %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
format = (snd_pcm_hw_params_test_format(*pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
stream_info->has_float = (format == SND_PCM_FORMAT_FLOAT);
|
||||
|
||||
RARCH_LOG("[ALSA] Using %s sample format for %s device \"%s\".\n",
|
||||
snd_pcm_format_name(format),
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm)
|
||||
);
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_set_access(*pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to set %s access for %s device \"%s\": %s.\n",
|
||||
snd_pcm_access_name(SND_PCM_ACCESS_RW_INTERLEAVED),
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
stream_info->frame_bits = snd_pcm_format_physical_width(format) * channels;
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_set_format(*pcm, params, format)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to set %s format for %s device \"%s\": %s.\n",
|
||||
snd_pcm_format_name(format),
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_set_channels(*pcm, params, channels)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to set %u-channel audio for %s device \"%s\": %s.\n",
|
||||
channels,
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Don't allow rate resampling when probing for the default rate (but ignore if this call fails) */
|
||||
if ((errnum = snd_pcm_hw_params_set_rate_resample(*pcm, params, false)) < 0)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Failed to request a default unsampled rate for %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_set_rate_near(*pcm, params, &rate, 0)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to request a rate near %uHz for %s device \"%s\": %s.\n",
|
||||
rate,
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (new_rate)
|
||||
*new_rate = rate;
|
||||
|
||||
if ((snd_pcm_hw_params_set_buffer_time_near(*pcm, params, &latency_usec, NULL)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to request a buffer time near %uus for %s device \"%s\": %s.\n",
|
||||
latency_usec,
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_set_periods_near(*pcm, params, &periods, NULL)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to request %u periods per buffer for %s device \"%s\": %s.\n",
|
||||
periods,
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_hw_params(*pcm, params)) < 0)
|
||||
{ /* This calls snd_pcm_prepare() under the hood */
|
||||
RARCH_ERR("[ALSA] Failed to install hardware parameters for %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Shouldn't have to bother with this,
|
||||
* but some drivers are apparently broken. */
|
||||
if ((errnum = snd_pcm_hw_params_get_period_size(params, &stream_info->period_frames, NULL)) < 0)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Failed to get an exact period size from %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
RARCH_WARN("[ALSA] Trying the minimum period size instead.\n");
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_get_period_size_min(params, &stream_info->period_frames, NULL)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to get min period size from %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
stream_info->period_size = snd_pcm_frames_to_bytes(*pcm, stream_info->period_frames);
|
||||
if (stream_info->period_size < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to convert a period size of %lu frames to bytes: %s.\n",
|
||||
stream_info->period_frames,
|
||||
snd_strerror(stream_info->period_frames));
|
||||
goto error;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA] Period: %u periods per buffer (%lu frames, %lu bytes).\n",
|
||||
periods,
|
||||
stream_info->period_frames,
|
||||
stream_info->period_size);
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_get_buffer_size(params, &buffer_size)) < 0)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Failed to get exact buffer size from %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
RARCH_WARN("[ALSA] Trying the maximum buffer size instead.\n");
|
||||
|
||||
if ((errnum = snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to get max buffer size from %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stream_info->buffer_size = snd_pcm_frames_to_bytes(*pcm, buffer_size);
|
||||
if (stream_info->buffer_size < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to convert a buffer size of %lu frames to bytes: %s.\n",
|
||||
buffer_size,
|
||||
snd_strerror(buffer_size));
|
||||
goto error;
|
||||
}
|
||||
RARCH_LOG("[ALSA] Buffer size: %lu frames (%lu bytes).\n", buffer_size, stream_info->buffer_size);
|
||||
|
||||
stream_info->can_pause = snd_pcm_hw_params_can_pause(params);
|
||||
|
||||
RARCH_LOG("[ALSA] Can pause: %s.\n", stream_info->can_pause ? "yes" : "no");
|
||||
|
||||
if ((errnum = snd_pcm_sw_params_malloc(&sw_params)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate software parameters: %s.\n",
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_sw_params_current(*pcm, sw_params)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to query current software parameters for %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_sw_params_set_start_threshold(*pcm, sw_params, buffer_size / 2)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to set start %lu-frame threshold for %s device \"%s\": %s.\n",
|
||||
buffer_size / 2,
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_sw_params(*pcm, sw_params)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to install software parameters for %s device \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
snd_pcm_hw_params_free(params);
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
RARCH_LOG("[ALSA] Initialized %s device \"%s\".\n",
|
||||
snd_pcm_stream_name(stream),
|
||||
snd_pcm_name(*pcm));
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (params)
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
||||
if (sw_params)
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
if (*pcm)
|
||||
{
|
||||
alsa_free_pcm(*pcm);
|
||||
*pcm = NULL;
|
||||
}
|
||||
|
||||
return errnum;
|
||||
}
|
||||
|
||||
void alsa_free_pcm(snd_pcm_t *pcm)
|
||||
{
|
||||
if (pcm)
|
||||
{
|
||||
int errnum = 0;
|
||||
|
||||
if ((errnum = snd_pcm_drop(pcm)) < 0)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Failed to drop remaining samples in %s stream \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_strerror(errnum));
|
||||
}
|
||||
|
||||
if ((errnum = snd_pcm_close(pcm)) < 0)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Failed to close %s stream \"%s\": %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_strerror(errnum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool alsa_start_pcm(snd_pcm_t *pcm)
|
||||
{
|
||||
int errnum = 0;
|
||||
snd_pcm_state_t pcm_state;
|
||||
|
||||
if (!pcm)
|
||||
return false;
|
||||
|
||||
pcm_state = snd_pcm_state(pcm);
|
||||
switch (pcm_state)
|
||||
{
|
||||
case SND_PCM_STATE_PAUSED: /* If we're unpausing a valid (but paused) stream... */
|
||||
if ((errnum = snd_pcm_pause(pcm, false)) < 0) /* ...but we failed... */
|
||||
goto error;
|
||||
|
||||
break;
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
/* If we're starting this stream for the first time... */
|
||||
if ((errnum = snd_pcm_start(pcm)) < 0) /* ..but we failed... */
|
||||
goto error;
|
||||
|
||||
break;
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
RARCH_DBG("[ALSA] %s stream \"%s\" is already running, no action needed.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm));
|
||||
return true;
|
||||
default:
|
||||
RARCH_ERR("[ALSA] Failed to start %s stream \"%s\" in unexpected state %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state));
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_DBG("[ALSA] Started %s stream \"%s\", transitioning from %s to %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state),
|
||||
snd_pcm_state_name(snd_pcm_state(pcm)));
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to start %s stream \"%s\" in state %s: %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state),
|
||||
snd_strerror(errnum));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool alsa_stop_pcm(snd_pcm_t *pcm)
|
||||
{
|
||||
int errnum = 0;
|
||||
snd_pcm_state_t pcm_state;
|
||||
|
||||
if (!pcm)
|
||||
return false;
|
||||
|
||||
pcm_state = snd_pcm_state(pcm);
|
||||
switch (pcm_state)
|
||||
{
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
RARCH_DBG("[ALSA] %s stream \"%s\" is already paused, no action needed.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm));
|
||||
return true;
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
RARCH_DBG("[ALSA] %s stream \"%s\" is prepared but not running, no action needed.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm));
|
||||
return true;
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
/* If we're pausing an active stream... */
|
||||
if ((errnum = snd_pcm_pause(pcm, true)) < 0) /* ...but we failed... */
|
||||
goto error;
|
||||
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("[ALSA] Failed to stop %s stream \"%s\" in unexpected state %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_DBG("[ALSA] Stopped %s stream \"%s\", transitioning from %s to %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state),
|
||||
snd_pcm_state_name(snd_pcm_state(pcm)));
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to stop %s stream \"%s\" in state %s: %s.\n",
|
||||
snd_pcm_stream_name(snd_pcm_stream(pcm)),
|
||||
snd_pcm_name(pcm),
|
||||
snd_pcm_state_name(pcm_state),
|
||||
snd_strerror(errnum));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct string_list *alsa_device_list_type_new(const char* type)
|
||||
{
|
||||
void **hints, **n;
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *s = string_list_new();
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (snd_device_name_hint(-1, "pcm", &hints) != 0)
|
||||
{
|
||||
string_list_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = hints;
|
||||
|
||||
while (*n)
|
||||
{
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
char *desc = snd_device_name_get_hint(*n, "DESC");
|
||||
|
||||
/* description of device IOID - input / output identification
|
||||
* ("Input" or "Output"), NULL means both) */
|
||||
|
||||
if (!io || (string_is_equal(io, type)))
|
||||
string_list_append(s, name, attr);
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
if (io)
|
||||
free(io);
|
||||
if (desc)
|
||||
free(desc);
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
/* free hint buffer too */
|
||||
snd_device_name_free_hint(hints);
|
||||
|
||||
return s;
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2023 The RetroArch team
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _RETROARCH_ALSA
|
||||
#define _RETROARCH_ALSA
|
||||
|
||||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
|
||||
/* Header file for common functions that are used by alsa and alsathread. */
|
||||
|
||||
/**
|
||||
* Used for info that's common to all pcm devices
|
||||
* that's relevant for our purposes.
|
||||
*/
|
||||
typedef struct alsa_stream_info
|
||||
{
|
||||
size_t buffer_size;
|
||||
size_t period_size;
|
||||
snd_pcm_uframes_t period_frames;
|
||||
unsigned int frame_bits;
|
||||
bool has_float;
|
||||
bool can_pause;
|
||||
} alsa_stream_info_t;
|
||||
|
||||
int alsa_init_pcm(snd_pcm_t **pcm,
|
||||
const char* device,
|
||||
snd_pcm_stream_t stream,
|
||||
unsigned rate,
|
||||
unsigned latency,
|
||||
unsigned channels,
|
||||
alsa_stream_info_t *stream_info,
|
||||
unsigned *new_rate,
|
||||
int mode);
|
||||
|
||||
void alsa_free_pcm(snd_pcm_t *pcm);
|
||||
void *alsa_device_list_new(void *data);
|
||||
struct string_list *alsa_device_list_type_new(const char* type);
|
||||
void alsa_device_list_free(void *data, void *array_list_data);
|
||||
|
||||
bool alsa_start_pcm(snd_pcm_t *pcm);
|
||||
bool alsa_stop_pcm(snd_pcm_t *pcm);
|
||||
|
||||
#endif /* _RETROARCH_ALSA */
|
|
@ -17,410 +17,24 @@
|
|||
|
||||
#include <encodings/utf.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "mmdevice_common.h"
|
||||
#include "mmdevice_common_inline.h"
|
||||
|
||||
#include "../../verbosity.h"
|
||||
|
||||
static const char *mmdevice_data_flow_name(unsigned data_flow)
|
||||
{
|
||||
switch (data_flow)
|
||||
{
|
||||
case 0:
|
||||
return "eRender";
|
||||
case 1:
|
||||
return "eCapture";
|
||||
case 2:
|
||||
return "eAll";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
const char *mmdevice_hresult_name(int hr)
|
||||
{
|
||||
switch (hr)
|
||||
{
|
||||
/* Standard error codes */
|
||||
case E_INVALIDARG:
|
||||
return "E_INVALIDARG";
|
||||
case E_NOINTERFACE:
|
||||
return "E_NOINTERFACE";
|
||||
case E_OUTOFMEMORY:
|
||||
return "E_OUTOFMEMORY";
|
||||
case E_POINTER:
|
||||
return "E_POINTER";
|
||||
/* Standard success codes */
|
||||
case S_FALSE:
|
||||
return "S_FALSE";
|
||||
case S_OK:
|
||||
return "S_OK";
|
||||
/* AUDCLNT error codes */
|
||||
case AUDCLNT_E_ALREADY_INITIALIZED:
|
||||
return "AUDCLNT_E_ALREADY_INITIALIZED";
|
||||
case AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL:
|
||||
return "AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL";
|
||||
case AUDCLNT_E_BUFFER_ERROR:
|
||||
return "AUDCLNT_E_BUFFER_ERROR";
|
||||
case AUDCLNT_E_BUFFER_OPERATION_PENDING:
|
||||
return "AUDCLNT_E_BUFFER_OPERATION_PENDING";
|
||||
case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED:
|
||||
return "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED";
|
||||
case AUDCLNT_E_BUFFER_SIZE_ERROR:
|
||||
return "AUDCLNT_E_BUFFER_SIZE_ERROR";
|
||||
case AUDCLNT_E_CPUUSAGE_EXCEEDED:
|
||||
return "AUDCLNT_E_CPUUSAGE_EXCEEDED";
|
||||
case AUDCLNT_E_DEVICE_IN_USE:
|
||||
return "AUDCLNT_E_DEVICE_IN_USE";
|
||||
case AUDCLNT_E_DEVICE_INVALIDATED:
|
||||
return "AUDCLNT_E_DEVICE_INVALIDATED";
|
||||
case AUDCLNT_E_ENDPOINT_CREATE_FAILED:
|
||||
return "AUDCLNT_E_ENDPOINT_CREATE_FAILED";
|
||||
case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED:
|
||||
return "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED";
|
||||
case AUDCLNT_E_INVALID_DEVICE_PERIOD:
|
||||
return "AUDCLNT_E_INVALID_DEVICE_PERIOD";
|
||||
case AUDCLNT_E_INVALID_SIZE:
|
||||
return "AUDCLNT_E_INVALID_SIZE";
|
||||
case AUDCLNT_E_NOT_INITIALIZED:
|
||||
return "AUDCLNT_E_NOT_INITIALIZED";
|
||||
case AUDCLNT_E_OUT_OF_ORDER:
|
||||
return "AUDCLNT_E_OUT_OF_ORDER";
|
||||
case AUDCLNT_E_SERVICE_NOT_RUNNING:
|
||||
return "AUDCLNT_E_SERVICE_NOT_RUNNING";
|
||||
case AUDCLNT_E_UNSUPPORTED_FORMAT:
|
||||
return "AUDCLNT_E_UNSUPPORTED_FORMAT";
|
||||
case AUDCLNT_E_WRONG_ENDPOINT_TYPE:
|
||||
return "AUDCLNT_E_WRONG_ENDPOINT_TYPE";
|
||||
/* AUDCLNT success codes */
|
||||
case AUDCLNT_S_BUFFER_EMPTY:
|
||||
return "AUDCLNT_S_BUFFER_EMPTY";
|
||||
/* Something else; probably from an API that we started using
|
||||
* after mic support was implemented */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
size_t mmdevice_samplerate(void *data)
|
||||
{
|
||||
HRESULT hr;
|
||||
PWAVEFORMATEX devfmt_props;
|
||||
PROPVARIANT prop_var;
|
||||
IMMDevice *device = (IMMDevice*)data;
|
||||
IPropertyStore *prop_store = NULL;
|
||||
DWORD result = 0;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
hr = _IMMDevice_OpenPropertyStore(device,
|
||||
STGM_READ, &prop_store);
|
||||
|
||||
if (FAILED(hr))
|
||||
return 0;
|
||||
|
||||
PropVariantInit(&prop_var);
|
||||
hr = _IPropertyStore_GetValue(prop_store,
|
||||
PKEY_AudioEngine_DeviceFormat, &prop_var);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
devfmt_props = (PWAVEFORMATEX)prop_var.blob.pBlobData;
|
||||
result = devfmt_props->nSamplesPerSec;
|
||||
}
|
||||
|
||||
PropVariantClear(&prop_var);
|
||||
if (prop_store)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
prop_store->Release();
|
||||
#else
|
||||
prop_store->lpVtbl->Release(prop_store);
|
||||
#endif
|
||||
prop_store = NULL;
|
||||
}
|
||||
return (size_t)result;
|
||||
}
|
||||
|
||||
char *mmdevice_name(void *data)
|
||||
{
|
||||
HRESULT hr;
|
||||
PROPVARIANT prop_var;
|
||||
IMMDevice *device = (IMMDevice*)data;
|
||||
IPropertyStore *prop_store = NULL;
|
||||
char* result = NULL;
|
||||
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
hr = _IMMDevice_OpenPropertyStore(device,
|
||||
STGM_READ, &prop_store);
|
||||
|
||||
if (FAILED(hr))
|
||||
return NULL;
|
||||
|
||||
PropVariantInit(&prop_var);
|
||||
hr = _IPropertyStore_GetValue(prop_store,
|
||||
PKEY_Device_FriendlyName, &prop_var);
|
||||
if (SUCCEEDED(hr))
|
||||
result = utf16_to_utf8_string_alloc(prop_var.pwszVal);
|
||||
|
||||
PropVariantClear(&prop_var);
|
||||
if (prop_store)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
prop_store->Release();
|
||||
#else
|
||||
prop_store->lpVtbl->Release(prop_store);
|
||||
#endif
|
||||
prop_store = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void *mmdevice_handle(int id, unsigned data_flow)
|
||||
{
|
||||
HRESULT hr;
|
||||
IMMDeviceEnumerator *enumerator = NULL;
|
||||
IMMDevice *device = NULL;
|
||||
IMMDeviceCollection *collection = NULL;
|
||||
#ifdef __cplusplus
|
||||
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
IID_IMMDeviceEnumerator, (void **)&enumerator);
|
||||
#else
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
&IID_IMMDeviceEnumerator, (void **)&enumerator);
|
||||
#endif
|
||||
if (FAILED(hr))
|
||||
return NULL;
|
||||
hr = _IMMDeviceEnumerator_EnumAudioEndpoints(enumerator,
|
||||
data_flow, DEVICE_STATE_ACTIVE, &collection);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to enumerate audio endpoints: %s.\n", mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
hr = _IMMDeviceCollection_Item(collection, id, &device);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to get IMMDevice #%d: %s.\n", id, mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
return device;
|
||||
|
||||
error:
|
||||
if (collection)
|
||||
#ifdef __cplusplus
|
||||
collection->Release();
|
||||
#else
|
||||
collection->lpVtbl->Release(collection);
|
||||
#endif
|
||||
if (enumerator)
|
||||
#ifdef __cplusplus
|
||||
enumerator->Release();
|
||||
#else
|
||||
enumerator->lpVtbl->Release(enumerator);
|
||||
#endif
|
||||
collection = NULL;
|
||||
enumerator = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t mmdevice_get_samplerate(int id)
|
||||
{
|
||||
IMMDevice *device = (IMMDevice*)mmdevice_handle(id, 0 /* eRender */);
|
||||
if (device)
|
||||
{
|
||||
size_t _len = mmdevice_samplerate(device);
|
||||
#ifdef __cplusplus
|
||||
device->Release();
|
||||
#else
|
||||
device->lpVtbl->Release(device);
|
||||
#endif
|
||||
return _len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *mmdevice_init_device(const char *id, unsigned data_flow)
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT32 dev_count, i;
|
||||
IMMDeviceEnumerator *enumerator = NULL;
|
||||
IMMDevice *device = NULL;
|
||||
IMMDeviceCollection *collection = NULL;
|
||||
const char *data_flow_name = mmdevice_data_flow_name(data_flow);
|
||||
|
||||
if (id)
|
||||
RARCH_DBG("[MMDevice] Initializing %s device \"%s\"...\n", data_flow_name, id);
|
||||
else
|
||||
RARCH_DBG("[MMDevice] Initializing default %s device...\n", data_flow_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
IID_IMMDeviceEnumerator, (void **)&enumerator);
|
||||
#else
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
&IID_IMMDeviceEnumerator, (void **)&enumerator);
|
||||
#endif
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to create device enumerator: %s.\n", mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (id)
|
||||
{
|
||||
/* If a specific device was requested... */
|
||||
int32_t idx_found = -1;
|
||||
struct string_list *list = (struct string_list*)mmdevice_list_new(NULL, data_flow);
|
||||
|
||||
if (!list)
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to allocate %s device list.\n", data_flow_name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (list->elems)
|
||||
{
|
||||
size_t d;
|
||||
/* If any devices were found... */
|
||||
for (d = 0; d < list->size; d++)
|
||||
{
|
||||
if (string_is_equal(id, list->elems[d].data))
|
||||
{
|
||||
RARCH_DBG("[MMDevice] Found device #%d: \"%s\".\n", d,
|
||||
list->elems[d].data);
|
||||
idx_found = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Index was not found yet based on name string,
|
||||
* just assume id is a one-character number index. */
|
||||
if (idx_found == -1 && isdigit(id[0]))
|
||||
{
|
||||
idx_found = strtoul(id, NULL, 0);
|
||||
RARCH_LOG("[MMDevice] Fallback, %s device index is a single number index instead: %u.\n",
|
||||
data_flow_name, idx_found);
|
||||
}
|
||||
}
|
||||
string_list_free(list);
|
||||
|
||||
if (idx_found == -1)
|
||||
idx_found = 0;
|
||||
|
||||
hr = _IMMDeviceEnumerator_EnumAudioEndpoints(enumerator,
|
||||
data_flow, DEVICE_STATE_ACTIVE, &collection);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to enumerate audio endpoints: %s.\n", mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
hr = _IMMDeviceCollection_GetCount(collection, &dev_count);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to count IMMDevices: %s.\n", mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev_count; ++i)
|
||||
{
|
||||
hr = _IMMDeviceCollection_Item(collection, i, &device);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to get IMMDevice #%d: %s.\n", i, mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (i == (UINT32)idx_found)
|
||||
break;
|
||||
|
||||
if (device)
|
||||
#ifdef __cplusplus
|
||||
device->Release();
|
||||
#else
|
||||
device->lpVtbl->Release(device);
|
||||
#endif
|
||||
device = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = _IMMDeviceEnumerator_GetDefaultAudioEndpoint(
|
||||
enumerator, data_flow, eConsole, &device);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[MMDevice] Failed to get default audio endpoint: %s.\n", mmdevice_hresult_name(hr));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!device)
|
||||
goto error;
|
||||
|
||||
if (collection)
|
||||
#ifdef __cplusplus
|
||||
collection->Release();
|
||||
#else
|
||||
collection->lpVtbl->Release(collection);
|
||||
#endif
|
||||
if (enumerator)
|
||||
#ifdef __cplusplus
|
||||
enumerator->Release();
|
||||
#else
|
||||
enumerator->lpVtbl->Release(enumerator);
|
||||
#endif
|
||||
collection = NULL;
|
||||
enumerator = NULL;
|
||||
|
||||
return device;
|
||||
|
||||
error:
|
||||
if (collection)
|
||||
#ifdef __cplusplus
|
||||
collection->Release();
|
||||
#else
|
||||
collection->lpVtbl->Release(collection);
|
||||
#endif
|
||||
if (enumerator)
|
||||
#ifdef __cplusplus
|
||||
enumerator->Release();
|
||||
#else
|
||||
enumerator->lpVtbl->Release(enumerator);
|
||||
#endif
|
||||
collection = NULL;
|
||||
enumerator = NULL;
|
||||
|
||||
if (id)
|
||||
RARCH_WARN("[MMDevice] Failed to initialize %s device \"%s\".\n", data_flow_name, id);
|
||||
else
|
||||
RARCH_ERR("[MMDevice] Failed to initialize default %s device.\n", data_flow_name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *mmdevice_list_new(const void *u, unsigned data_flow)
|
||||
void *mmdevice_list_new(void *u)
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT i;
|
||||
PROPVARIANT prop_var;
|
||||
union string_list_elem_attr attr;
|
||||
IMMDeviceEnumerator *enumerator = NULL;
|
||||
IMMDeviceCollection *collection = NULL;
|
||||
UINT dev_count = 0;
|
||||
IMMDevice *device = NULL;
|
||||
LPWSTR dev_id_wstr = NULL;
|
||||
IPropertyStore *prop_store = NULL;
|
||||
bool br = false;
|
||||
bool prop_var_init = false;
|
||||
char *dev_id_str = NULL;
|
||||
char *dev_name_str = NULL;
|
||||
struct string_list *sl = string_list_new();
|
||||
|
@ -440,7 +54,7 @@ void *mmdevice_list_new(const void *u, unsigned data_flow)
|
|||
goto error;
|
||||
|
||||
hr = _IMMDeviceEnumerator_EnumAudioEndpoints(enumerator,
|
||||
data_flow, DEVICE_STATE_ACTIVE, &collection);
|
||||
eRender, DEVICE_STATE_ACTIVE, &collection);
|
||||
if (FAILED(hr))
|
||||
goto error;
|
||||
|
||||
|
@ -461,7 +75,19 @@ void *mmdevice_list_new(const void *u, unsigned data_flow)
|
|||
if (!(dev_id_str = utf16_to_utf8_string_alloc(dev_id_wstr)))
|
||||
goto error;
|
||||
|
||||
if (!(dev_name_str = mmdevice_name(device)))
|
||||
hr = _IMMDevice_OpenPropertyStore(device, STGM_READ, &prop_store);
|
||||
if (FAILED(hr))
|
||||
goto error;
|
||||
|
||||
PropVariantInit(&prop_var);
|
||||
prop_var_init = true;
|
||||
hr = _IPropertyStore_GetValue(
|
||||
prop_store, PKEY_Device_FriendlyName,
|
||||
&prop_var);
|
||||
if (FAILED(hr))
|
||||
goto error;
|
||||
|
||||
if (!(dev_name_str = utf16_to_utf8_string_alloc(prop_var.pwszVal)))
|
||||
goto error;
|
||||
|
||||
br = string_list_append(sl, dev_name_str, attr);
|
||||
|
@ -470,41 +96,20 @@ void *mmdevice_list_new(const void *u, unsigned data_flow)
|
|||
if (dev_id_str)
|
||||
sl->elems[sl->size-1].userdata = dev_id_str;
|
||||
|
||||
PropVariantClear(&prop_var);
|
||||
prop_var_init = false;
|
||||
if (dev_id_wstr)
|
||||
CoTaskMemFree(dev_id_wstr);
|
||||
if (dev_name_str)
|
||||
free(dev_name_str);
|
||||
dev_name_str = NULL;
|
||||
dev_id_wstr = NULL;
|
||||
if (device)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
device->Release();
|
||||
#else
|
||||
device->lpVtbl->Release(device);
|
||||
#endif
|
||||
device = NULL;
|
||||
}
|
||||
IFACE_RELEASE(prop_store);
|
||||
IFACE_RELEASE(device);
|
||||
}
|
||||
|
||||
if (collection)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
collection->Release();
|
||||
#else
|
||||
collection->lpVtbl->Release(collection);
|
||||
#endif
|
||||
collection = NULL;
|
||||
}
|
||||
if (enumerator)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
enumerator->Release();
|
||||
#else
|
||||
enumerator->lpVtbl->Release(enumerator);
|
||||
#endif
|
||||
enumerator = NULL;
|
||||
}
|
||||
IFACE_RELEASE(collection);
|
||||
IFACE_RELEASE(enumerator);
|
||||
|
||||
return sl;
|
||||
|
||||
|
@ -515,36 +120,15 @@ error:
|
|||
free(dev_name_str);
|
||||
dev_id_str = NULL;
|
||||
dev_name_str = NULL;
|
||||
if (prop_var_init)
|
||||
PropVariantClear(&prop_var);
|
||||
IFACE_RELEASE(prop_store);
|
||||
if (dev_id_wstr)
|
||||
CoTaskMemFree(dev_id_wstr);
|
||||
dev_id_wstr = NULL;
|
||||
if (device)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
device->Release();
|
||||
#else
|
||||
device->lpVtbl->Release(device);
|
||||
#endif
|
||||
device = NULL;
|
||||
}
|
||||
if (collection)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
collection->Release();
|
||||
#else
|
||||
collection->lpVtbl->Release(collection);
|
||||
#endif
|
||||
collection = NULL;
|
||||
}
|
||||
if (enumerator)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
enumerator->Release();
|
||||
#else
|
||||
enumerator->lpVtbl->Release(enumerator);
|
||||
#endif
|
||||
enumerator = NULL;
|
||||
}
|
||||
IFACE_RELEASE(device);
|
||||
IFACE_RELEASE(collection);
|
||||
IFACE_RELEASE(enumerator);
|
||||
if (sl)
|
||||
string_list_free(sl);
|
||||
|
||||
|
|
|
@ -18,34 +18,9 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
void *mmdevice_list_new(const void *u, unsigned data_flow);
|
||||
|
||||
/**
|
||||
* Gets the friendly name of the provided IMMDevice.
|
||||
* The string must be freed with free().
|
||||
*/
|
||||
char* mmdevice_name(void *data);
|
||||
|
||||
/**
|
||||
* Gets the samplerate of the provided IMMDevice.
|
||||
*/
|
||||
size_t mmdevice_samplerate(void *data);
|
||||
|
||||
/**
|
||||
* Gets the handle of the IMMDevice.
|
||||
*/
|
||||
void *mmdevice_handle(int id, unsigned data_flow);
|
||||
|
||||
size_t mmdevice_get_samplerate(int id);
|
||||
|
||||
const char *mmdevice_hresult_name(int hr);
|
||||
|
||||
|
||||
void *mmdevice_init_device(const char *id, unsigned data_flow);
|
||||
void *mmdevice_list_new(void *u);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Fix for MSYS2 increasing _WIN32_WINNT to 0x0603 */
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <winerror.h>
|
||||
|
@ -36,7 +37,6 @@
|
|||
#ifdef _MSC_VER
|
||||
DEFINE_GUID(IID_IAudioClient, 0x1CB9AD4C, 0xDBFA, 0x4C32, 0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2);
|
||||
DEFINE_GUID(IID_IAudioRenderClient, 0xF294ACFC, 0x3146, 0x4483, 0xA7, 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2);
|
||||
DEFINE_GUID(IID_IAudioCaptureClient, 0xC8ADBD64, 0xE71E, 0x48A0, 0xA4, 0xDE, 0x18, 0x5C, 0x39, 0x5C, 0xD3, 0x17);
|
||||
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
|
||||
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
|
||||
#undef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
|
@ -60,10 +60,6 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0
|
|||
#define _IAudioClient_GetBufferSize(This,pNumBufferFrames) ( (This)->GetBufferSize(pNumBufferFrames) )
|
||||
#define _IAudioClient_GetStreamLatency(This,phnsLatency) ( (This)->GetStreamLatency(phnsLatency) )
|
||||
#define _IAudioClient_GetDevicePeriod(This,phnsDefaultDevicePeriod,phnsMinimumDevicePeriod) ( (This)->GetDevicePeriod(phnsDefaultDevicePeriod,phnsMinimumDevicePeriod) )
|
||||
#define _IAudioClient_Initialize(This,ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid) \
|
||||
( (This)->Initialize(ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid))
|
||||
#define _IAudioClient_IsFormatSupported(This,ShareMode,pFormat,ppClosestMatch) \
|
||||
( (This)->IsFormatSupported(ShareMode,pFormat,ppClosestMatch))
|
||||
#define _IMMDevice_Activate(This,iid,dwClsCtx,pActivationParams,ppv) ((This)->Activate(iid,(dwClsCtx),pActivationParams,ppv))
|
||||
#define _IMMDeviceEnumerator_EnumAudioEndpoints(This,dataFlow,dwStateMask,ppDevices) (This)->EnumAudioEndpoints(dataFlow,dwStateMask,ppDevices)
|
||||
#define _IMMDeviceEnumerator_GetDefaultAudioEndpoint(This,dataFlow,role,ppEndpoint) (This)->GetDefaultAudioEndpoint(dataFlow,role,ppEndpoint)
|
||||
|
@ -71,12 +67,6 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0
|
|||
#define _IMMDevice_GetId(This,ppstrId) ((This)->GetId(ppstrId))
|
||||
#define _IPropertyStore_GetValue(This,key,pv) ( (This)->GetValue(key,pv) )
|
||||
#define _IMMDeviceCollection_GetCount(This,cProps) ( (This)->GetCount(cProps) )
|
||||
#define _IAudioCaptureClient_GetBuffer(This,ppData,pNumFramesToRead,pdwFlags,pu64DevicePosition,pu64QPCPosition) \
|
||||
( (This) -> GetBuffer(ppData,pNumFramesToRead,pdwFlags,pu64DevicePosition,pu64QPCPosition) )
|
||||
#define _IAudioCaptureClient_ReleaseBuffer(This,NumFramesRead) \
|
||||
( (This) -> ReleaseBuffer(NumFramesRead) )
|
||||
#define _IAudioCaptureClient_GetNextPacketSize(This,pNumFramesInNextPacket) \
|
||||
( (This) -> GetNextPacketSize(pNumFramesInNextPacket) )
|
||||
#else
|
||||
#define _IMMDeviceCollection_Item(This,nDevice,ppdevice) (This)->lpVtbl->Item(This,nDevice,ppdevice)
|
||||
#define _IAudioClient_Start(This) ( (This)->lpVtbl -> Start(This) )
|
||||
|
@ -92,10 +82,6 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0
|
|||
#define _IAudioClient_GetBufferSize(This,pNumBufferFrames) ( (This)->lpVtbl -> GetBufferSize(This,pNumBufferFrames) )
|
||||
#define _IAudioClient_GetStreamLatency(This,phnsLatency) ( (This)->lpVtbl -> GetStreamLatency(This,phnsLatency) )
|
||||
#define _IAudioClient_GetDevicePeriod(This,phnsDefaultDevicePeriod,phnsMinimumDevicePeriod) ( (This)->lpVtbl -> GetDevicePeriod(This,phnsDefaultDevicePeriod,phnsMinimumDevicePeriod) )
|
||||
#define _IAudioClient_Initialize(This,ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid) \
|
||||
( (This)->lpVtbl->Initialize(This,ShareMode,StreamFlags,hnsBufferDuration,hnsPeriodicity,pFormat,AudioSessionGuid))
|
||||
#define _IAudioClient_IsFormatSupported(This,ShareMode,pFormat,ppClosestMatch) \
|
||||
( (This)->lpVtbl->IsFormatSupported(This,ShareMode,pFormat,ppClosestMatch))
|
||||
#define _IMMDevice_Activate(This,iid,dwClsCtx,pActivationParams,ppv) ((This)->lpVtbl->Activate(This,&(iid),dwClsCtx,pActivationParams,ppv))
|
||||
#define _IMMDeviceEnumerator_EnumAudioEndpoints(This,dataFlow,dwStateMask,ppDevices) (This)->lpVtbl->EnumAudioEndpoints(This,dataFlow,dwStateMask,ppDevices)
|
||||
#define _IMMDeviceEnumerator_GetDefaultAudioEndpoint(This,dataFlow,role,ppEndpoint) (This)->lpVtbl->GetDefaultAudioEndpoint(This,dataFlow,role,ppEndpoint)
|
||||
|
@ -103,12 +89,26 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0
|
|||
#define _IMMDevice_GetId(This,ppstrId) (This)->lpVtbl->GetId(This,ppstrId)
|
||||
#define _IPropertyStore_GetValue(This,key,pv) ( (This)->lpVtbl -> GetValue(This,&(key),pv) )
|
||||
#define _IMMDeviceCollection_GetCount(This,cProps) ( (This)->lpVtbl -> GetCount(This,cProps) )
|
||||
#define _IAudioCaptureClient_GetBuffer(This,ppData,pNumFramesToRead,pdwFlags,pu64DevicePosition,pu64QPCPosition) \
|
||||
( (This)->lpVtbl -> GetBuffer(This,ppData,pNumFramesToRead,pdwFlags,pu64DevicePosition,pu64QPCPosition) )
|
||||
#define _IAudioCaptureClient_ReleaseBuffer(This,NumFramesRead) \
|
||||
( (This)->lpVtbl -> ReleaseBuffer(This,NumFramesRead) )
|
||||
#define _IAudioCaptureClient_GetNextPacketSize(This,pNumFramesInNextPacket) \
|
||||
( (This)-> lpVtbl -> GetNextPacketSize(This,pNumFramesInNextPacket) )
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef IFACE_RELEASE
|
||||
#define IFACE_RELEASE(iface) \
|
||||
if (iface) \
|
||||
{ \
|
||||
iface->Release(); \
|
||||
iface = NULL; \
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#ifndef IFACE_RELEASE
|
||||
#define IFACE_RELEASE(iface) \
|
||||
if (iface) \
|
||||
{ \
|
||||
iface->lpVtbl->Release(iface);\
|
||||
iface = NULL; \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2024 Viachaslau Khalikin
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pipewire.h"
|
||||
|
||||
#include <spa/utils/result.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
#include "../../verbosity.h"
|
||||
|
||||
|
||||
static void core_error_cb(void *data, uint32_t id, int seq, int res, const char *message)
|
||||
{
|
||||
pipewire_core_t *pw = (pipewire_core_t*)data;
|
||||
|
||||
RARCH_ERR("[PipeWire] Error id:%u seq:%d res:%d (%s): %s.\n",
|
||||
id, seq, res, spa_strerror(res), message);
|
||||
|
||||
pw_thread_loop_stop(pw->thread_loop);
|
||||
}
|
||||
|
||||
static void core_done_cb(void *data, uint32_t id, int seq)
|
||||
{
|
||||
pipewire_core_t *pw = (pipewire_core_t*)data;
|
||||
|
||||
retro_assert(id == PW_ID_CORE);
|
||||
|
||||
pw->last_seq = seq;
|
||||
|
||||
if (pw->pending_seq == seq)
|
||||
pw_thread_loop_signal(pw->thread_loop, false);
|
||||
}
|
||||
|
||||
static const struct pw_core_events core_events = {
|
||||
PW_VERSION_CORE_EVENTS,
|
||||
.done = core_done_cb,
|
||||
.error = core_error_cb,
|
||||
};
|
||||
|
||||
void pipewire_core_wait_resync(pipewire_core_t *pw)
|
||||
{
|
||||
retro_assert(pw);
|
||||
pw->pending_seq = pw_core_sync(pw->core, PW_ID_CORE, pw->pending_seq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
pw_thread_loop_wait(pw->thread_loop);
|
||||
if (pw->pending_seq == pw->last_seq)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pipewire_stream_set_active(struct pw_thread_loop *loop, struct pw_stream *stream, bool active)
|
||||
{
|
||||
enum pw_stream_state st;
|
||||
const char *error;
|
||||
|
||||
retro_assert(loop);
|
||||
retro_assert(stream);
|
||||
|
||||
pw_thread_loop_lock(loop);
|
||||
pw_stream_set_active(stream, active);
|
||||
pw_thread_loop_wait(loop);
|
||||
pw_thread_loop_unlock(loop);
|
||||
|
||||
st = pw_stream_get_state(stream, &error);
|
||||
return active ? st == PW_STREAM_STATE_STREAMING : st == PW_STREAM_STATE_PAUSED;
|
||||
}
|
||||
|
||||
bool pipewire_core_init(pipewire_core_t **pw, const char *loop_name, const struct pw_registry_events *events)
|
||||
{
|
||||
retro_assert(!*pw);
|
||||
|
||||
*pw = (pipewire_core_t*)calloc(1, sizeof(pipewire_core_t));
|
||||
if (!*pw)
|
||||
return false;
|
||||
|
||||
(*pw)->devicelist = string_list_new();
|
||||
if (!(*pw)->devicelist)
|
||||
{
|
||||
free(*pw);
|
||||
*pw = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
pw_init(NULL, NULL);
|
||||
|
||||
(*pw)->thread_loop = pw_thread_loop_new(loop_name, NULL);
|
||||
if (!(*pw)->thread_loop)
|
||||
return false;
|
||||
|
||||
(*pw)->ctx = pw_context_new(pw_thread_loop_get_loop((*pw)->thread_loop), NULL, 0);
|
||||
if (!(*pw)->ctx)
|
||||
return false;
|
||||
|
||||
if (pw_thread_loop_start((*pw)->thread_loop) < 0)
|
||||
return false;
|
||||
|
||||
pw_thread_loop_lock((*pw)->thread_loop);
|
||||
|
||||
(*pw)->core = pw_context_connect((*pw)->ctx, NULL, 0);
|
||||
if (!(*pw)->core)
|
||||
goto unlock;
|
||||
|
||||
if (pw_core_add_listener((*pw)->core,
|
||||
&(*pw)->core_listener,
|
||||
&core_events, *pw) < 0)
|
||||
goto unlock;
|
||||
|
||||
if (events)
|
||||
{
|
||||
(*pw)->registry = pw_core_get_registry((*pw)->core, PW_VERSION_REGISTRY, 0);
|
||||
spa_zero((*pw)->registry_listener);
|
||||
pw_registry_add_listener((*pw)->registry, &(*pw)->registry_listener, events, *pw);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
unlock:
|
||||
pw_thread_loop_unlock((*pw)->thread_loop);
|
||||
return false;
|
||||
}
|
||||
|
||||
void pipewire_core_deinit(pipewire_core_t *pw)
|
||||
{
|
||||
if (!pw)
|
||||
return pw_deinit();
|
||||
|
||||
if (pw->thread_loop)
|
||||
pw_thread_loop_stop(pw->thread_loop);
|
||||
|
||||
if (pw->registry)
|
||||
{
|
||||
spa_hook_remove(&pw->registry_listener);
|
||||
pw_proxy_destroy((struct pw_proxy*)pw->registry);
|
||||
}
|
||||
|
||||
if (pw->core)
|
||||
{
|
||||
spa_hook_remove(&pw->core_listener);
|
||||
pw_core_disconnect(pw->core);
|
||||
}
|
||||
|
||||
if (pw->ctx)
|
||||
pw_context_destroy(pw->ctx);
|
||||
|
||||
if (pw->thread_loop)
|
||||
pw_thread_loop_destroy(pw->thread_loop);
|
||||
|
||||
if (pw->devicelist)
|
||||
string_list_free(pw->devicelist);
|
||||
|
||||
free(pw);
|
||||
pw_deinit();
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2024 The RetroArch team
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Found- ation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* RetroArch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _RETROARCH_PIPEWIRE
|
||||
#define _RETROARCH_PIPEWIRE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include <lists/string_list.h>
|
||||
|
||||
|
||||
#define PW_RARCH_APPNAME "RetroArch"
|
||||
|
||||
/* String literals are part of the PipeWire specification */
|
||||
#define PW_RARCH_MEDIA_TYPE_AUDIO "Audio"
|
||||
#define PW_RARCH_MEDIA_TYPE_VIDEO "Video"
|
||||
#define PW_RARCH_MEDIA_TYPE_MIDI "Midi"
|
||||
#define PW_RARCH_MEDIA_CATEGORY_PLAYBACK "Playback"
|
||||
#define PW_RARCH_MEDIA_CATEGORY_RECORD "Capture"
|
||||
#define PW_RARCH_MEDIA_ROLE "Game"
|
||||
|
||||
typedef struct pipewire_core
|
||||
{
|
||||
struct pw_thread_loop *thread_loop;
|
||||
struct pw_context *ctx;
|
||||
|
||||
struct pw_core *core;
|
||||
struct spa_hook core_listener;
|
||||
int last_seq, pending_seq;
|
||||
|
||||
struct pw_registry *registry;
|
||||
struct spa_hook registry_listener;
|
||||
|
||||
struct string_list *devicelist;
|
||||
bool nonblock;
|
||||
} pipewire_core_t;
|
||||
|
||||
bool pipewire_core_init(pipewire_core_t **pw, const char *loop_name, const struct pw_registry_events *events);
|
||||
|
||||
void pipewire_core_deinit(pipewire_core_t *pw);
|
||||
|
||||
void pipewire_core_wait_resync(pipewire_core_t *pw);
|
||||
|
||||
bool pipewire_stream_set_active(struct pw_thread_loop *loop, struct pw_stream *stream, bool active);
|
||||
|
||||
#endif /* _RETROARCH_PIPEWIRE */
|
|
@ -1,7 +1,6 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2023-2025 - Jesse Talavera-Greenberg
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
|
@ -21,361 +20,179 @@
|
|||
#include <string/stdstring.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <alsa/pcm.h>
|
||||
#include <asm-generic/errno.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../common/alsa.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifdef HAVE_MICROPHONE
|
||||
#include "../microphone_driver.h"
|
||||
|
||||
#define BYTES_TO_FRAMES(bytes, frame_bits) ((bytes) * 8 / frame_bits)
|
||||
#define FRAMES_TO_BYTES(frames, frame_bits) ((frames) * frame_bits / 8)
|
||||
|
||||
typedef struct alsa_microphone_handle
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
alsa_stream_info_t stream_info;
|
||||
} alsa_microphone_handle_t;
|
||||
|
||||
typedef struct alsa_microphone
|
||||
{
|
||||
bool nonblock;
|
||||
} alsa_microphone_t;
|
||||
|
||||
static void *alsa_microphone_init(void)
|
||||
{
|
||||
alsa_microphone_t *alsa = (alsa_microphone_t*)calloc(1, sizeof(alsa_microphone_t));
|
||||
|
||||
if (!alsa)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate driver context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA] Using ALSA version %s.\n", snd_asoundlib_version());
|
||||
|
||||
return alsa;
|
||||
}
|
||||
|
||||
static void alsa_microphone_close_mic(void *driver_context, void *mic_context);
|
||||
static void alsa_microphone_free(void *driver_context)
|
||||
{
|
||||
alsa_microphone_t *alsa = (alsa_microphone_t*)driver_context;
|
||||
/* The mic frontend should've closed all mics before calling free(). */
|
||||
|
||||
if (alsa)
|
||||
{
|
||||
snd_config_update_free_global();
|
||||
free(alsa);
|
||||
}
|
||||
}
|
||||
|
||||
static bool alsa_microphone_start_mic(void *driver_context, void *mic_context);
|
||||
|
||||
static int alsa_microphone_read(void *driver_context, void *mic_context, void *s, size_t len)
|
||||
{
|
||||
size_t frames_size;
|
||||
snd_pcm_sframes_t size;
|
||||
snd_pcm_state_t state;
|
||||
alsa_microphone_t *alsa = (alsa_microphone_t*)driver_context;
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
uint8_t *buf = (uint8_t*)s;
|
||||
snd_pcm_sframes_t read = 0;
|
||||
int errnum = 0;
|
||||
|
||||
if (!alsa || !mic || !buf)
|
||||
return -1;
|
||||
|
||||
size = BYTES_TO_FRAMES(len, mic->stream_info.frame_bits);
|
||||
frames_size = mic->stream_info.has_float ? sizeof(float) : sizeof(int16_t);
|
||||
|
||||
state = snd_pcm_state(mic->pcm);
|
||||
if (state != SND_PCM_STATE_RUNNING)
|
||||
{
|
||||
RARCH_WARN("[ALSA] Expected microphone \"%s\" to be in state RUNNING, was in state %s.\n",
|
||||
snd_pcm_name(mic->pcm),
|
||||
snd_pcm_state_name(state));
|
||||
|
||||
errnum = snd_pcm_start(mic->pcm);
|
||||
if (errnum < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to start microphone \"%s\": %s.\n",
|
||||
snd_pcm_name(mic->pcm),
|
||||
snd_strerror(errnum));
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (alsa->nonblock)
|
||||
{
|
||||
while (size)
|
||||
{
|
||||
snd_pcm_sframes_t frames = snd_pcm_readi(mic->pcm, buf, size);
|
||||
|
||||
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||
{
|
||||
errnum = snd_pcm_recover(mic->pcm, frames, 0);
|
||||
if (errnum < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to read from microphone: %s.\n", snd_strerror(frames));
|
||||
RARCH_ERR("[ALSA] Additionally, recovery failed with: %s.\n", snd_strerror(errnum));
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (frames == -EAGAIN)
|
||||
break;
|
||||
else if (frames < 0)
|
||||
return -1;
|
||||
|
||||
read += frames;
|
||||
buf += frames_size;
|
||||
size -= frames;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool eagain_retry = true;
|
||||
|
||||
while (size)
|
||||
{
|
||||
snd_pcm_sframes_t frames;
|
||||
int rc = snd_pcm_wait(mic->pcm, -1);
|
||||
|
||||
if (rc == -EPIPE || rc == -ESTRPIPE || rc == -EINTR)
|
||||
{
|
||||
if (snd_pcm_recover(mic->pcm, rc, 1) < 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
frames = snd_pcm_readi(mic->pcm, buf, size);
|
||||
|
||||
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||
{
|
||||
if (snd_pcm_recover(mic->pcm, frames, 1) < 0)
|
||||
return -1;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (frames == -EAGAIN)
|
||||
{
|
||||
/* Definitely not supposed to happen. */
|
||||
if (eagain_retry)
|
||||
{
|
||||
eagain_retry = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (frames < 0)
|
||||
return -1;
|
||||
|
||||
read += frames;
|
||||
buf += frames_size;
|
||||
size -= frames;
|
||||
}
|
||||
}
|
||||
|
||||
return FRAMES_TO_BYTES(read, mic->stream_info.frame_bits);
|
||||
}
|
||||
|
||||
static bool alsa_microphone_mic_alive(const void *driver_context, const void *mic_context)
|
||||
{
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
(void)driver_context;
|
||||
|
||||
if (!mic)
|
||||
return false;
|
||||
|
||||
return snd_pcm_state(mic->pcm) == SND_PCM_STATE_RUNNING;
|
||||
}
|
||||
|
||||
static void alsa_microphone_set_nonblock_state(void *driver_context, bool nonblock)
|
||||
{
|
||||
alsa_microphone_t *alsa = (alsa_microphone_t*)driver_context;
|
||||
alsa->nonblock = nonblock;
|
||||
}
|
||||
|
||||
static struct string_list *alsa_microphone_device_list_new(const void *data)
|
||||
{
|
||||
return alsa_device_list_type_new("Input");
|
||||
}
|
||||
|
||||
static void alsa_microphone_device_list_free(const void *driver_context, struct string_list *devices)
|
||||
{
|
||||
(void)driver_context;
|
||||
string_list_free(devices);
|
||||
/* Does nothing if devices is NULL */
|
||||
}
|
||||
|
||||
static void *alsa_microphone_open_mic(void *driver_context,
|
||||
const char *device,
|
||||
unsigned rate,
|
||||
unsigned latency,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
alsa_microphone_t *alsa = (alsa_microphone_t*)driver_context;
|
||||
alsa_microphone_handle_t *mic = NULL;
|
||||
|
||||
if (!alsa) /* If we weren't given a valid ALSA context... */
|
||||
return NULL;
|
||||
|
||||
/* If the microphone context couldn't be allocated... */
|
||||
if (!(mic = calloc(1, sizeof(alsa_microphone_handle_t))))
|
||||
return NULL;
|
||||
|
||||
/* channels hardcoded to 1, because we only support mono mic input */
|
||||
if (alsa_init_pcm(&mic->pcm, device, SND_PCM_STREAM_CAPTURE, rate, latency, 1,
|
||||
&mic->stream_info, new_rate, SND_PCM_NONBLOCK) < 0)
|
||||
goto error;
|
||||
|
||||
return mic;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to initialize microphone.\n");
|
||||
|
||||
alsa_microphone_close_mic(alsa, mic);
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
static void alsa_microphone_close_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
(void)driver_context;
|
||||
|
||||
if (mic)
|
||||
{
|
||||
alsa_free_pcm(mic->pcm);
|
||||
free(mic);
|
||||
}
|
||||
}
|
||||
|
||||
static bool alsa_microphone_start_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
if (!mic)
|
||||
return false;
|
||||
return alsa_start_pcm(mic->pcm);
|
||||
}
|
||||
|
||||
static bool alsa_microphone_stop_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
if (!mic)
|
||||
return false;
|
||||
return alsa_stop_pcm(mic->pcm);
|
||||
}
|
||||
|
||||
static bool alsa_microphone_mic_use_float(const void *driver_context, const void *mic_context)
|
||||
{
|
||||
alsa_microphone_handle_t *mic = (alsa_microphone_handle_t*)mic_context;
|
||||
return mic->stream_info.has_float;
|
||||
}
|
||||
|
||||
microphone_driver_t microphone_alsa = {
|
||||
alsa_microphone_init,
|
||||
alsa_microphone_free,
|
||||
alsa_microphone_read,
|
||||
alsa_microphone_set_nonblock_state,
|
||||
"alsa",
|
||||
alsa_microphone_device_list_new,
|
||||
alsa_microphone_device_list_free,
|
||||
alsa_microphone_open_mic,
|
||||
alsa_microphone_close_mic,
|
||||
alsa_microphone_mic_alive,
|
||||
alsa_microphone_start_mic,
|
||||
alsa_microphone_stop_mic,
|
||||
alsa_microphone_mic_use_float
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct alsa
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
alsa_stream_info_t stream_info;
|
||||
size_t buffer_size;
|
||||
unsigned int frame_bits;
|
||||
bool nonblock;
|
||||
bool has_float;
|
||||
bool can_pause;
|
||||
bool is_paused;
|
||||
} alsa_t;
|
||||
|
||||
static bool alsa_use_float(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->stream_info.has_float;
|
||||
return alsa->has_float;
|
||||
}
|
||||
|
||||
static bool find_float_format(snd_pcm_t *pcm, void *data)
|
||||
{
|
||||
snd_pcm_hw_params_t *params = (snd_pcm_hw_params_t*)data;
|
||||
|
||||
if (snd_pcm_hw_params_test_format(pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
{
|
||||
RARCH_LOG("[ALSA]: Using floating point format.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA]: Using signed 16-bit format.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void alsa_free(void *data);
|
||||
static void *alsa_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
snd_pcm_sw_params_t *sw_params = NULL;
|
||||
unsigned latency_usec = latency * 1000;
|
||||
unsigned channels = 2;
|
||||
unsigned periods = 4;
|
||||
unsigned orig_rate = rate;
|
||||
const char *alsa_dev = "default";
|
||||
alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
|
||||
if (!alsa)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate driver context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA] Using ALSA version %s.\n", snd_asoundlib_version());
|
||||
if (device)
|
||||
alsa_dev = device;
|
||||
|
||||
if (alsa_init_pcm(&alsa->pcm, device, SND_PCM_STREAM_PLAYBACK, rate,
|
||||
latency, 2, &alsa->stream_info, new_rate, SND_PCM_NONBLOCK) < 0)
|
||||
if (snd_pcm_open(
|
||||
&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_hw_params_malloc(¶ms) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_hw_params_any(alsa->pcm, params) < 0)
|
||||
goto error;
|
||||
|
||||
alsa->has_float = find_float_format(alsa->pcm, params);
|
||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
if (snd_pcm_hw_params_set_access(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
||||
goto error;
|
||||
|
||||
/* channels hardcoded to 2 for now */
|
||||
alsa->frame_bits = snd_pcm_format_physical_width(format) * 2;
|
||||
|
||||
if (snd_pcm_hw_params_set_format(alsa->pcm, params, format) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_hw_params_set_channels(alsa->pcm, params, channels) < 0)
|
||||
goto error;
|
||||
|
||||
/* Don't allow rate resampling when probing for the default rate (but ignore if this call fails) */
|
||||
snd_pcm_hw_params_set_rate_resample(alsa->pcm, params, 0 );
|
||||
if (snd_pcm_hw_params_set_rate_near(alsa->pcm, params, &rate, 0) < 0)
|
||||
goto error;
|
||||
|
||||
if (rate != orig_rate)
|
||||
*new_rate = rate;
|
||||
|
||||
if (snd_pcm_hw_params_set_buffer_time_near(
|
||||
alsa->pcm, params, &latency_usec, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_hw_params_set_periods_near(
|
||||
alsa->pcm, params, &periods, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_hw_params(alsa->pcm, params) < 0)
|
||||
goto error;
|
||||
|
||||
/* Shouldn't have to bother with this,
|
||||
* but some drivers are apparently broken. */
|
||||
if (snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL))
|
||||
snd_pcm_hw_params_get_period_size_min(params, &buffer_size, NULL);
|
||||
|
||||
RARCH_LOG("[ALSA]: Period size: %d frames\n", (int)buffer_size);
|
||||
|
||||
if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size))
|
||||
snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size);
|
||||
|
||||
RARCH_LOG("[ALSA]: Buffer size: %d frames\n", (int)buffer_size);
|
||||
|
||||
alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
|
||||
alsa->can_pause = snd_pcm_hw_params_can_pause(params);
|
||||
|
||||
RARCH_LOG("[ALSA]: Can pause: %s.\n", alsa->can_pause ? "yes" : "no");
|
||||
|
||||
if (snd_pcm_sw_params_malloc(&sw_params) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_sw_params_current(alsa->pcm, sw_params) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_sw_params_set_start_threshold(
|
||||
alsa->pcm, sw_params, buffer_size / 2) < 0)
|
||||
goto error;
|
||||
|
||||
if (snd_pcm_sw_params(alsa->pcm, sw_params) < 0)
|
||||
goto error;
|
||||
|
||||
snd_pcm_hw_params_free(params);
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
return alsa;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to initialize.\n");
|
||||
RARCH_ERR("[ALSA]: Failed to initialize...\n");
|
||||
if (params)
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
||||
alsa_free(alsa);
|
||||
if (sw_params)
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
if (alsa)
|
||||
{
|
||||
if (alsa->pcm)
|
||||
{
|
||||
snd_pcm_close(alsa->pcm);
|
||||
snd_config_update_free_global();
|
||||
}
|
||||
|
||||
free(alsa);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define BYTES_TO_FRAMES(bytes, frame_bits) ((bytes) * 8 / frame_bits)
|
||||
#define FRAMES_TO_BYTES(frames, frame_bits) ((frames) * frame_bits / 8)
|
||||
|
||||
static bool alsa_start(void *data, bool is_shutdown)
|
||||
static bool alsa_start(void *data, bool is_shutdown);
|
||||
static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (!alsa->is_paused)
|
||||
return true;
|
||||
|
||||
if ( alsa->stream_info.can_pause
|
||||
&& alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_pause(alsa->pcm, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
alsa->is_paused = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static ssize_t alsa_write(void *data, const void *buf_, size_t len)
|
||||
{
|
||||
ssize_t _len = 0;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
snd_pcm_sframes_t size = BYTES_TO_FRAMES(len, alsa->stream_info.frame_bits);
|
||||
size_t frames_size = alsa->stream_info.has_float ? sizeof(float) : sizeof(int16_t);
|
||||
snd_pcm_sframes_t written = 0;
|
||||
snd_pcm_sframes_t size = BYTES_TO_FRAMES(size_, alsa->frame_bits);
|
||||
size_t frames_size = alsa->has_float ? sizeof(float) : sizeof(int16_t);
|
||||
|
||||
/* Workaround buggy menu code.
|
||||
* If a write happens while we're paused, we might never progress. */
|
||||
if (alsa->is_paused && !alsa_start(alsa, false))
|
||||
if (alsa->is_paused)
|
||||
if (!alsa_start(alsa, false))
|
||||
return -1;
|
||||
|
||||
if (alsa->nonblock)
|
||||
|
@ -396,7 +213,7 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t len)
|
|||
else if (frames < 0)
|
||||
return -1;
|
||||
|
||||
_len += frames;
|
||||
written += frames;
|
||||
buf += (frames << 1) * frames_size;
|
||||
size -= frames;
|
||||
}
|
||||
|
@ -439,13 +256,13 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t len)
|
|||
else if (frames < 0)
|
||||
return -1;
|
||||
|
||||
_len += frames;
|
||||
written += frames;
|
||||
buf += (frames << 1) * frames_size;
|
||||
size -= frames;
|
||||
}
|
||||
}
|
||||
|
||||
return _len;
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool alsa_alive(void *data)
|
||||
|
@ -462,7 +279,7 @@ static bool alsa_stop(void *data)
|
|||
if (alsa->is_paused)
|
||||
return true;
|
||||
|
||||
if (alsa->stream_info.can_pause
|
||||
if (alsa->can_pause
|
||||
&& !alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_pause(alsa->pcm, 1);
|
||||
|
@ -482,15 +299,42 @@ static void alsa_set_nonblock_state(void *data, bool state)
|
|||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool alsa_start(void *data, bool is_shutdown)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (!alsa->is_paused)
|
||||
return true;
|
||||
|
||||
if (alsa->can_pause
|
||||
&& alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_pause(alsa->pcm, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
alsa->is_paused = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void alsa_free(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
if (alsa)
|
||||
{
|
||||
alsa_free_pcm(alsa->pcm);
|
||||
|
||||
if (alsa->pcm)
|
||||
{
|
||||
snd_pcm_drop(alsa->pcm);
|
||||
snd_pcm_close(alsa->pcm);
|
||||
snd_config_update_free_global();
|
||||
}
|
||||
|
||||
free(alsa);
|
||||
}
|
||||
}
|
||||
|
@ -501,27 +345,72 @@ static size_t alsa_write_avail(void *data)
|
|||
snd_pcm_sframes_t avail = snd_pcm_avail(alsa->pcm);
|
||||
|
||||
if (avail < 0)
|
||||
return alsa->stream_info.buffer_size;
|
||||
return alsa->buffer_size;
|
||||
|
||||
return FRAMES_TO_BYTES(avail, alsa->stream_info.frame_bits);
|
||||
return FRAMES_TO_BYTES(avail, alsa->frame_bits);
|
||||
}
|
||||
|
||||
static size_t alsa_buffer_size(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->stream_info.buffer_size;
|
||||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
void *alsa_device_list_new(void *data)
|
||||
static void *alsa_device_list_new(void *data)
|
||||
{
|
||||
return alsa_device_list_type_new("Output");
|
||||
void **hints, **n;
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *s = string_list_new();
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (snd_device_name_hint(-1, "pcm", &hints) != 0)
|
||||
goto error;
|
||||
|
||||
n = hints;
|
||||
|
||||
while (*n)
|
||||
{
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
char *desc = snd_device_name_get_hint(*n, "DESC");
|
||||
|
||||
/* description of device IOID - input / output identifcation
|
||||
* ("Input" or "Output"), NULL means both) */
|
||||
|
||||
if (!io || (string_is_equal(io, "Output")))
|
||||
string_list_append(s, name, attr);
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
if (io)
|
||||
free(io);
|
||||
if (desc)
|
||||
free(desc);
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
void alsa_device_list_free(void *data, void *array_list_data)
|
||||
/* free hint buffer too */
|
||||
snd_device_name_free_hint(hints);
|
||||
|
||||
return s;
|
||||
|
||||
error:
|
||||
string_list_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void alsa_device_list_free(void *data, void *array_list_data)
|
||||
{
|
||||
struct string_list *s = (struct string_list*)array_list_data;
|
||||
|
||||
if (s)
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
string_list_free(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,14 +64,14 @@ static void *alsa_qsa_init(const char *device,
|
|||
if ((err = snd_pcm_open_preferred(&alsa->pcm, &card, &dev,
|
||||
SND_PCM_OPEN_PLAYBACK)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Audio open error: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Audio open error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if((err = snd_pcm_nonblock_mode(alsa->pcm, 1)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Can't set blocking mode: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Can't set blocking mode: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ static void *alsa_qsa_init(const char *device,
|
|||
pi.channel = SND_PCM_CHANNEL_PLAYBACK;
|
||||
if ((err = snd_pcm_channel_info(alsa->pcm, &pi)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] snd_pcm_channel_info failed: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: snd_pcm_channel_info failed: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
@ -102,13 +102,13 @@ static void *alsa_qsa_init(const char *device,
|
|||
params.buf.block.frags_min = 2;
|
||||
params.buf.block.frags_max = 8;
|
||||
|
||||
RARCH_LOG("[ALSA QSA] Fragment size: %d.\n", params.buf.block.frag_size);
|
||||
RARCH_LOG("[ALSA QSA] Min Fragment size: %d.\n", params.buf.block.frags_min);
|
||||
RARCH_LOG("[ALSA QSA] Max Fragment size: %d.\n", params.buf.block.frags_max);
|
||||
RARCH_LOG("Fragment size: %d\n", params.buf.block.frag_size);
|
||||
RARCH_LOG("Min Fragment size: %d\n", params.buf.block.frags_min);
|
||||
RARCH_LOG("Max Fragment size: %d\n", params.buf.block.frags_max);
|
||||
|
||||
if ((err = snd_pcm_channel_params(alsa->pcm, ¶ms)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Channel Parameter Error: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ static void *alsa_qsa_init(const char *device,
|
|||
|
||||
if ((err = snd_pcm_channel_setup(alsa->pcm, &setup)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Channel Parameter Read Back Error: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Read Back Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ static void *alsa_qsa_init(const char *device,
|
|||
else
|
||||
alsa->buf_size = next_pow2(32 * latency);
|
||||
|
||||
RARCH_LOG("[ALSA QSA] Buffer size: %u bytes.\n", alsa->buf_size);
|
||||
RARCH_LOG("[ALSA QSA]: buffer size: %u bytes\n", alsa->buf_size);
|
||||
|
||||
alsa->buf_count = (latency * 4 * rate + 500) / 1000;
|
||||
alsa->buf_count = (alsa->buf_count + alsa->buf_size / 2) / alsa->buf_size;
|
||||
|
@ -135,7 +135,7 @@ static void *alsa_qsa_init(const char *device,
|
|||
if ((err = snd_pcm_channel_prepare(alsa->pcm,
|
||||
SND_PCM_CHANNEL_PLAYBACK)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Channel Prepare Error: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Channel Prepare Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ static void *alsa_qsa_init(const char *device,
|
|||
|
||||
alsa->has_float = false;
|
||||
alsa->can_pause = true;
|
||||
RARCH_LOG("[ALSA QSA] Can pause: %s.\n",
|
||||
RARCH_LOG("[ALSA QSA]: Can pause: %s.\n",
|
||||
alsa->can_pause ? "yes" : "no");
|
||||
|
||||
return alsa;
|
||||
|
@ -175,35 +175,35 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
{
|
||||
if (status.status == SND_PCM_STATUS_UNSECURE)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] check_pcm_status got SND_PCM_STATUS_UNSECURE, aborting playback.\n");
|
||||
RARCH_ERR("check_pcm_status got SND_PCM_STATUS_UNSECURE, aborting playback\n");
|
||||
ret = -EPROTO;
|
||||
}
|
||||
else if (status.status == SND_PCM_STATUS_UNDERRUN)
|
||||
{
|
||||
RARCH_LOG("[ALSA QSA] check_pcm_status: SNDP_CM_STATUS_UNDERRUN.\n");
|
||||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_UNDERRUN.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Invalid state detected for underrun on snd_pcm_channel_prepare: %s.\n",
|
||||
RARCH_ERR("Invalid state detected for underrun on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
}
|
||||
else if (status.status == SND_PCM_STATUS_OVERRUN)
|
||||
{
|
||||
RARCH_LOG("[ALSA QSA] check_pcm_status: SNDP_CM_STATUS_OVERRUN.\n");
|
||||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_OVERRUN.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Invalid state detected for overrun on snd_pcm_channel_prepare: %s.\n",
|
||||
RARCH_ERR("Invalid state detected for overrun on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
}
|
||||
else if (status.status == SND_PCM_STATUS_CHANGE)
|
||||
{
|
||||
RARCH_LOG("[ALSA QSA] check_pcm_status: SNDP_CM_STATUS_CHANGE.\n");
|
||||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_CHANGE.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Invalid state detected for change on snd_pcm_channel_prepare: %s.\n",
|
||||
RARCH_ERR("Invalid state detected for change on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] check_pcm_status failed: %s.\n", snd_strerror(ret));
|
||||
RARCH_ERR("check_pcm_status failed: %s\n", snd_strerror(ret));
|
||||
if (ret == -ESRCH)
|
||||
ret = -EBADF;
|
||||
}
|
||||
|
@ -219,14 +219,14 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t alsa_qsa_write(void *data, const void *buf, size_t len)
|
||||
static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t _len = 0;
|
||||
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
|
||||
snd_pcm_sframes_t written = 0;
|
||||
|
||||
while (size)
|
||||
{
|
||||
size_t avail_write = MIN(alsa->buf_size - alsa->buffer_ptr, len);
|
||||
size_t avail_write = MIN(alsa->buf_size - alsa->buffer_ptr, size);
|
||||
|
||||
if (avail_write)
|
||||
{
|
||||
|
@ -235,8 +235,8 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t len)
|
|||
|
||||
alsa->buffer_ptr += avail_write;
|
||||
buf = (void*)((uint8_t*)buf + avail_write);
|
||||
len -= avail_write;
|
||||
_len += avail_write;
|
||||
size -= avail_write;
|
||||
written += avail_write;
|
||||
}
|
||||
|
||||
if (alsa->buffer_ptr >= alsa->buf_size)
|
||||
|
@ -260,9 +260,10 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t len)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return _len;
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_stop(void *data)
|
||||
|
@ -299,7 +300,7 @@ static bool alsa_qsa_start(void *data, bool is_shutdown)
|
|||
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Failed to unpause: %s.\n",
|
||||
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
|
@ -312,12 +313,13 @@ static bool alsa_qsa_start(void *data, bool is_shutdown)
|
|||
|
||||
static void alsa_qsa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
int err;
|
||||
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
|
||||
|
||||
int err;
|
||||
|
||||
if((err = snd_pcm_nonblock_mode(alsa->pcm, state)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA] Can't set blocking mode to %d: %s.\n", state,
|
||||
RARCH_ERR("Can't set blocking mode to %d: %s\n", state,
|
||||
snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2012-2015 - Michael Lelli
|
||||
* Copyright (C) 2023-2025 - Jesse Talavera-Greenberg
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
|
@ -16,21 +15,22 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <lists/string_list.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <alsa/pcm.h>
|
||||
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <asm-generic/errno.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../common/alsa.h" /* For some common functions/types */
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct alsa_thread_info
|
||||
#define TRY_ALSA(x) if (x < 0) \
|
||||
goto error;
|
||||
|
||||
typedef struct alsa_thread
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
fifo_buffer_t *buffer;
|
||||
|
@ -38,446 +38,49 @@ typedef struct alsa_thread_info
|
|||
slock_t *fifo_lock;
|
||||
scond_t *cond;
|
||||
slock_t *cond_lock;
|
||||
alsa_stream_info_t stream_info;
|
||||
volatile bool thread_dead;
|
||||
} alsa_thread_info_t;
|
||||
|
||||
static void alsa_thread_free_info_members(alsa_thread_info_t *info)
|
||||
{
|
||||
if (info)
|
||||
{
|
||||
if (info->worker_thread)
|
||||
{
|
||||
slock_lock(info->cond_lock);
|
||||
info->thread_dead = true;
|
||||
slock_unlock(info->cond_lock);
|
||||
sthread_join(info->worker_thread);
|
||||
}
|
||||
if (info->buffer)
|
||||
fifo_free(info->buffer);
|
||||
if (info->cond)
|
||||
scond_free(info->cond);
|
||||
if (info->fifo_lock)
|
||||
slock_free(info->fifo_lock);
|
||||
if (info->cond_lock)
|
||||
slock_free(info->cond_lock);
|
||||
if (info->pcm)
|
||||
alsa_free_pcm(info->pcm);
|
||||
}
|
||||
/* Do NOT free() info itself; it's embedded within another struct
|
||||
* that will be freed. */
|
||||
}
|
||||
|
||||
#ifdef HAVE_MICROPHONE
|
||||
#include "../microphone_driver.h"
|
||||
|
||||
typedef struct alsa_thread_microphone_handle
|
||||
{
|
||||
alsa_thread_info_t info;
|
||||
} alsa_thread_microphone_handle_t;
|
||||
|
||||
typedef struct alsa_thread_microphone
|
||||
{
|
||||
bool nonblock;
|
||||
} alsa_thread_microphone_t;
|
||||
|
||||
static void *alsa_thread_microphone_init(void)
|
||||
{
|
||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)calloc(1, sizeof(alsa_thread_microphone_t));
|
||||
|
||||
if (!alsa)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate driver context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA] Using ALSA version %s\n", snd_asoundlib_version());
|
||||
|
||||
return alsa;
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static void alsa_thread_microphone_close_mic(void *driver_context, void *mic_context);
|
||||
|
||||
static void alsa_thread_microphone_free(void *driver_context)
|
||||
{
|
||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
||||
|
||||
if (alsa)
|
||||
free(alsa);
|
||||
}
|
||||
|
||||
/** @see alsa_thread_read_microphone() */
|
||||
static void alsa_microphone_worker_thread(void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
uint8_t *buf = NULL;
|
||||
uintptr_t thread_id = sthread_get_current_thread_id();
|
||||
|
||||
if (!(buf = (uint8_t *)calloc(1, mic->info.stream_info.period_size)))
|
||||
{
|
||||
RARCH_ERR("[ALSA] [capture thread %p] Failed to allocate audio buffer.\n", thread_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
RARCH_DBG("[ALSA] [capture thread %p] Beginning microphone worker thread.\n", thread_id);
|
||||
RARCH_DBG("[ALSA] [capture thread %p] Microphone \"%s\" is in state %s.\n",
|
||||
thread_id,
|
||||
snd_pcm_name(mic->info.pcm),
|
||||
snd_pcm_state_name(snd_pcm_state(mic->info.pcm)));
|
||||
|
||||
/* Until we're told to stop... */
|
||||
while (!mic->info.thread_dead)
|
||||
{
|
||||
size_t avail;
|
||||
size_t fifo_size;
|
||||
snd_pcm_sframes_t frames;
|
||||
int errnum = 0;
|
||||
|
||||
/* Lock the incoming sample queue (the main thread may block) */
|
||||
slock_lock(mic->info.fifo_lock);
|
||||
|
||||
/* Fill the incoming sample queue with whatever we recently read */
|
||||
avail = FIFO_WRITE_AVAIL(mic->info.buffer);
|
||||
fifo_size = MIN(mic->info.stream_info.period_size, avail);
|
||||
fifo_write(mic->info.buffer, buf, fifo_size);
|
||||
|
||||
/* Tell the main thread that it's okay to query the mic again */
|
||||
scond_signal(mic->info.cond);
|
||||
|
||||
/* Unlock the incoming sample queue (the main thread may resume) */
|
||||
slock_unlock(mic->info.fifo_lock);
|
||||
|
||||
/* If underrun, fill rest with silence. */
|
||||
memset(buf + fifo_size, 0, mic->info.stream_info.period_size - fifo_size);
|
||||
|
||||
errnum = snd_pcm_wait(mic->info.pcm, 33);
|
||||
|
||||
if (errnum == 0)
|
||||
{
|
||||
RARCH_DBG("[ALSA] [capture thread %p] Timeout after 33ms waiting for input.\n", thread_id);
|
||||
continue;
|
||||
}
|
||||
else if (errnum == -EPIPE || errnum == -ESTRPIPE || errnum == -EINTR)
|
||||
{
|
||||
RARCH_WARN("[ALSA] [capture thread %p] Wait error: %s.\n",
|
||||
thread_id,
|
||||
snd_strerror(errnum));
|
||||
|
||||
if ((errnum = snd_pcm_recover(mic->info.pcm, errnum, false)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [capture thread %p] Failed to recover from prior wait error: %s.\n",
|
||||
thread_id,
|
||||
snd_strerror(errnum));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
frames = snd_pcm_readi(mic->info.pcm, buf, mic->info.stream_info.period_frames);
|
||||
|
||||
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||
{
|
||||
RARCH_WARN("[ALSA] [capture thread %p] Read error: %s.\n",
|
||||
thread_id,
|
||||
snd_strerror(frames));
|
||||
|
||||
if ((errnum = snd_pcm_recover(mic->info.pcm, frames, false)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [capture thread %p] Failed to recover from prior read error: %s.\n",
|
||||
thread_id,
|
||||
snd_strerror(errnum));
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [capture thread %p] Read error: %s.\n",
|
||||
thread_id,
|
||||
snd_strerror(frames));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
slock_lock(mic->info.cond_lock);
|
||||
mic->info.thread_dead = true;
|
||||
scond_signal(mic->info.cond);
|
||||
slock_unlock(mic->info.cond_lock);
|
||||
free(buf);
|
||||
RARCH_DBG("[ALSA] [capture thread %p] Ending microphone worker thread.\n", thread_id);
|
||||
}
|
||||
|
||||
static int alsa_thread_microphone_read(void *driver_context, void *mic_context, void *s, size_t len)
|
||||
{
|
||||
snd_pcm_state_t state;
|
||||
size_t _len = 0;
|
||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
|
||||
if (!alsa || !mic || !s) /* If any of the parameters were invalid... */
|
||||
return -1;
|
||||
|
||||
if (mic->info.thread_dead) /* If the mic thread is shutting down... */
|
||||
return -1;
|
||||
|
||||
state = snd_pcm_state(mic->info.pcm);
|
||||
if (state != SND_PCM_STATE_RUNNING)
|
||||
{
|
||||
int errnum;
|
||||
RARCH_WARN("[ALSA] Expected microphone \"%s\" to be in state RUNNING, was in state %s.\n",
|
||||
snd_pcm_name(mic->info.pcm), snd_pcm_state_name(state));
|
||||
|
||||
errnum = snd_pcm_start(mic->info.pcm);
|
||||
if (errnum < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to start microphone \"%s\": %s.\n",
|
||||
snd_pcm_name(mic->info.pcm), snd_strerror(errnum));
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If driver interactions shouldn't block... */
|
||||
if (alsa->nonblock)
|
||||
{
|
||||
size_t avail;
|
||||
|
||||
/* "Hey, I'm gonna borrow the queue." */
|
||||
slock_lock(mic->info.fifo_lock);
|
||||
|
||||
avail = FIFO_READ_AVAIL(mic->info.buffer);
|
||||
_len = MIN(avail, len);
|
||||
|
||||
/* "It's okay if you don't have any new samples, I'll just check in on you later." */
|
||||
fifo_read(mic->info.buffer, s, _len);
|
||||
|
||||
/* "Here, take this queue back." */
|
||||
slock_unlock(mic->info.fifo_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Until we've read all requested samples (or we're told to stop)... */
|
||||
while (_len < len && !mic->info.thread_dead)
|
||||
{
|
||||
size_t avail;
|
||||
|
||||
/* "Hey, I'm gonna borrow the queue." */
|
||||
slock_lock(mic->info.fifo_lock);
|
||||
|
||||
avail = FIFO_READ_AVAIL(mic->info.buffer);
|
||||
|
||||
if (avail == 0)
|
||||
{ /* "Oh, wait, it's empty." */
|
||||
|
||||
/* "Here, take it back..." */
|
||||
slock_unlock(mic->info.fifo_lock);
|
||||
|
||||
/* "...I'll just wait right here." */
|
||||
slock_lock(mic->info.cond_lock);
|
||||
|
||||
/* "Unless we're closing up shop..." */
|
||||
if (!mic->info.thread_dead)
|
||||
/* "...let me know when you've produced some samples." */
|
||||
scond_wait(mic->info.cond, mic->info.cond_lock);
|
||||
|
||||
/* "Oh, you're ready? Okay, I'm gonna continue." */
|
||||
slock_unlock(mic->info.cond_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t read_amt = MIN(len - _len, avail);
|
||||
|
||||
/* "I'll just go ahead and consume all these samples..."
|
||||
* (As many as will fit in s, or as many as are available.) */
|
||||
fifo_read(mic->info.buffer,s + _len, read_amt);
|
||||
|
||||
/* "I'm done, you can take the queue back now." */
|
||||
slock_unlock(mic->info.fifo_lock);
|
||||
_len += read_amt;
|
||||
}
|
||||
/* "I'll be right back..." */
|
||||
}
|
||||
}
|
||||
return _len;
|
||||
}
|
||||
|
||||
static bool alsa_thread_microphone_mic_alive(const void *driver_context, const void *mic_context);
|
||||
|
||||
static void *alsa_thread_microphone_open_mic(void *driver_context,
|
||||
const char *device, unsigned rate, unsigned latency, unsigned *new_rate)
|
||||
{
|
||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
||||
alsa_thread_microphone_handle_t *mic = NULL;
|
||||
|
||||
if (!alsa) /* If we weren't given a valid ALSA context... */
|
||||
return NULL;
|
||||
|
||||
/* If the microphone context couldn't be allocated... */
|
||||
if (!(mic = calloc(1, sizeof(alsa_thread_microphone_handle_t))))
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate microphone context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (alsa_init_pcm(&mic->info.pcm, device, SND_PCM_STREAM_CAPTURE, rate, latency,
|
||||
1, &mic->info.stream_info, new_rate, 0) < 0)
|
||||
goto error;
|
||||
|
||||
mic->info.fifo_lock = slock_new();
|
||||
mic->info.cond_lock = slock_new();
|
||||
mic->info.cond = scond_new();
|
||||
mic->info.buffer = fifo_new(mic->info.stream_info.buffer_size);
|
||||
if (!mic->info.fifo_lock || !mic->info.cond_lock || !mic->info.cond || !mic->info.buffer || !mic->info.pcm)
|
||||
goto error;
|
||||
|
||||
mic->info.worker_thread = sthread_create(alsa_microphone_worker_thread, mic);
|
||||
if (!mic->info.worker_thread)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to initialize microphone worker thread.\n");
|
||||
goto error;
|
||||
}
|
||||
RARCH_DBG("[ALSA] Initialized microphone worker thread.\n");
|
||||
|
||||
return mic;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to initialize microphone.\n");
|
||||
|
||||
if (mic)
|
||||
{
|
||||
if (mic->info.pcm)
|
||||
snd_pcm_close(mic->info.pcm);
|
||||
|
||||
alsa_thread_microphone_close_mic(alsa, mic);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void alsa_thread_microphone_close_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
if (mic)
|
||||
{
|
||||
alsa_thread_free_info_members(&mic->info);
|
||||
free(mic);
|
||||
}
|
||||
}
|
||||
|
||||
static bool alsa_thread_microphone_mic_alive(const void *driver_context, const void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t *)mic_context;
|
||||
if (!mic)
|
||||
return false;
|
||||
return snd_pcm_state(mic->info.pcm) == SND_PCM_STATE_RUNNING;
|
||||
}
|
||||
|
||||
static void alsa_thread_microphone_set_nonblock_state(void *driver_context, bool state)
|
||||
{
|
||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static struct string_list *alsa_thread_microphone_device_list_new(const void *data)
|
||||
{
|
||||
return alsa_device_list_type_new("Input");
|
||||
}
|
||||
|
||||
static void alsa_thread_microphone_device_list_free(const void *driver_context, struct string_list *devices)
|
||||
{
|
||||
string_list_free(devices);
|
||||
/* Does nothing if devices is NULL */
|
||||
}
|
||||
|
||||
static bool alsa_thread_microphone_start_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
if (!mic)
|
||||
return false;
|
||||
return alsa_start_pcm(mic->info.pcm);
|
||||
}
|
||||
|
||||
static bool alsa_thread_microphone_stop_mic(void *driver_context, void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
if (!mic)
|
||||
return false;
|
||||
return alsa_stop_pcm(mic->info.pcm);
|
||||
}
|
||||
|
||||
static bool alsa_thread_microphone_mic_use_float(const void *driver_context, const void *mic_context)
|
||||
{
|
||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||
return mic->info.stream_info.has_float;
|
||||
}
|
||||
|
||||
microphone_driver_t microphone_alsathread = {
|
||||
alsa_thread_microphone_init,
|
||||
alsa_thread_microphone_free,
|
||||
alsa_thread_microphone_read,
|
||||
alsa_thread_microphone_set_nonblock_state,
|
||||
"alsathread",
|
||||
alsa_thread_microphone_device_list_new,
|
||||
alsa_thread_microphone_device_list_free,
|
||||
alsa_thread_microphone_open_mic,
|
||||
alsa_thread_microphone_close_mic,
|
||||
alsa_thread_microphone_mic_alive,
|
||||
alsa_thread_microphone_start_mic,
|
||||
alsa_thread_microphone_stop_mic,
|
||||
alsa_thread_microphone_mic_use_float
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct alsa_thread
|
||||
{
|
||||
alsa_thread_info_t info;
|
||||
size_t buffer_size;
|
||||
size_t period_size;
|
||||
snd_pcm_uframes_t period_frames;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
bool has_float;
|
||||
volatile bool thread_dead;
|
||||
} alsa_thread_t;
|
||||
|
||||
static void alsa_worker_thread(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
uint8_t *buf = (uint8_t *)calloc(1, alsa->info.stream_info.period_size);
|
||||
uintptr_t thread_id = sthread_get_current_thread_id();
|
||||
uint8_t *buf = (uint8_t *)calloc(1, alsa->period_size);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [playback thread %u] Failed to allocate audio buffer.\n", thread_id);
|
||||
RARCH_ERR("failed to allocate audio buffer");
|
||||
goto end;
|
||||
}
|
||||
|
||||
RARCH_DBG("[ALSA] [playback thread %p] Beginning playback worker thread.\n", thread_id);
|
||||
while (!alsa->info.thread_dead)
|
||||
while (!alsa->thread_dead)
|
||||
{
|
||||
size_t avail;
|
||||
size_t fifo_size;
|
||||
snd_pcm_sframes_t frames;
|
||||
slock_lock(alsa->info.fifo_lock);
|
||||
avail = FIFO_READ_AVAIL(alsa->info.buffer);
|
||||
fifo_size = MIN(alsa->info.stream_info.period_size, avail);
|
||||
fifo_read(alsa->info.buffer, buf, fifo_size);
|
||||
scond_signal(alsa->info.cond);
|
||||
slock_unlock(alsa->info.fifo_lock);
|
||||
slock_lock(alsa->fifo_lock);
|
||||
avail = FIFO_READ_AVAIL(alsa->buffer);
|
||||
fifo_size = MIN(alsa->period_size, avail);
|
||||
fifo_read(alsa->buffer, buf, fifo_size);
|
||||
scond_signal(alsa->cond);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
|
||||
/* If underrun, fill rest with silence. */
|
||||
memset(buf + fifo_size, 0, alsa->info.stream_info.period_size - fifo_size);
|
||||
memset(buf + fifo_size, 0, alsa->period_size - fifo_size);
|
||||
|
||||
frames = snd_pcm_writei(alsa->info.pcm, buf, alsa->info.stream_info.period_frames);
|
||||
frames = snd_pcm_writei(alsa->pcm, buf, alsa->period_frames);
|
||||
|
||||
if ( frames == -EPIPE
|
||||
|| frames == -EINTR
|
||||
|| frames == -ESTRPIPE)
|
||||
if (frames == -EPIPE || frames == -EINTR ||
|
||||
frames == -ESTRPIPE)
|
||||
{
|
||||
if (snd_pcm_recover(alsa->info.pcm, frames, false) < 0)
|
||||
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [playback thread %u] Failed to recover from error: %s.\n",
|
||||
thread_id,
|
||||
RARCH_ERR("[ALSA]: (#2) Failed to recover from error (%s)\n",
|
||||
snd_strerror(frames));
|
||||
break;
|
||||
}
|
||||
|
@ -486,26 +89,36 @@ static void alsa_worker_thread(void *data)
|
|||
}
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA] [playback thread %u] Error writing audio to device: %s.\n",
|
||||
thread_id,
|
||||
RARCH_ERR("[ALSA]: Unknown error occurred (%s).\n",
|
||||
snd_strerror(frames));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
slock_lock(alsa->info.cond_lock);
|
||||
alsa->info.thread_dead = true;
|
||||
scond_signal(alsa->info.cond);
|
||||
slock_unlock(alsa->info.cond_lock);
|
||||
slock_lock(alsa->cond_lock);
|
||||
alsa->thread_dead = true;
|
||||
scond_signal(alsa->cond);
|
||||
slock_unlock(alsa->cond_lock);
|
||||
free(buf);
|
||||
RARCH_DBG("[ALSA] [playback thread %p] Ending playback worker thread...\n", thread_id);
|
||||
}
|
||||
|
||||
static bool alsa_thread_use_float(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
return alsa->info.stream_info.has_float;
|
||||
return alsa->has_float;
|
||||
}
|
||||
|
||||
static bool alsathread_find_float_format(snd_pcm_t *pcm,
|
||||
snd_pcm_hw_params_t *params)
|
||||
{
|
||||
if (snd_pcm_hw_params_test_format(pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
{
|
||||
RARCH_LOG("ALSA: Using floating point format.\n");
|
||||
return true;
|
||||
}
|
||||
RARCH_LOG("ALSA: Using signed 16-bit format.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void alsa_thread_free(void *data)
|
||||
|
@ -514,7 +127,26 @@ static void alsa_thread_free(void *data)
|
|||
|
||||
if (alsa)
|
||||
{
|
||||
alsa_thread_free_info_members(&alsa->info);
|
||||
if (alsa->worker_thread)
|
||||
{
|
||||
slock_lock(alsa->cond_lock);
|
||||
alsa->thread_dead = true;
|
||||
slock_unlock(alsa->cond_lock);
|
||||
sthread_join(alsa->worker_thread);
|
||||
}
|
||||
if (alsa->buffer)
|
||||
fifo_free(alsa->buffer);
|
||||
if (alsa->cond)
|
||||
scond_free(alsa->cond);
|
||||
if (alsa->fifo_lock)
|
||||
slock_free(alsa->fifo_lock);
|
||||
if (alsa->cond_lock)
|
||||
slock_free(alsa->cond_lock);
|
||||
if (alsa->pcm)
|
||||
{
|
||||
snd_pcm_drop(alsa->pcm);
|
||||
snd_pcm_close(alsa->pcm);
|
||||
}
|
||||
free(alsa);
|
||||
}
|
||||
}
|
||||
|
@ -524,90 +156,141 @@ static void *alsa_thread_init(const char *device,
|
|||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)calloc(1, sizeof(alsa_thread_t));
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
snd_pcm_sw_params_t *sw_params = NULL;
|
||||
const char *alsa_dev = device ? device : "default";
|
||||
unsigned latency_usec = latency * 1000 / 2;
|
||||
unsigned channels = 2;
|
||||
unsigned periods = 4;
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)
|
||||
calloc(1, sizeof(alsa_thread_t));
|
||||
|
||||
if (!alsa)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to allocate driver context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA] Using ALSA version %s.\n", snd_asoundlib_version());
|
||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));
|
||||
|
||||
if (alsa_init_pcm(&alsa->info.pcm, device, SND_PCM_STREAM_PLAYBACK, rate,
|
||||
latency, 2, &alsa->info.stream_info, new_rate, 0) < 0)
|
||||
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
|
||||
alsa->has_float = alsathread_find_float_format(alsa->pcm, params);
|
||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(
|
||||
alsa->pcm, params, &latency_usec, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(
|
||||
alsa->pcm, params, &periods, NULL));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
/* Shouldn't have to bother with this,
|
||||
* but some drivers are apparently broken. */
|
||||
if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL))
|
||||
snd_pcm_hw_params_get_period_size_min(
|
||||
params, &alsa->period_frames, NULL);
|
||||
RARCH_LOG("ALSA: Period size: %d frames\n", (int)alsa->period_frames);
|
||||
if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size))
|
||||
snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size);
|
||||
RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);
|
||||
|
||||
alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
|
||||
alsa->period_size = snd_pcm_frames_to_bytes(alsa->pcm, alsa->period_frames);
|
||||
|
||||
TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_set_start_threshold(
|
||||
alsa->pcm, sw_params, buffer_size / 2));
|
||||
TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));
|
||||
|
||||
snd_pcm_hw_params_free(params);
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
alsa->fifo_lock = slock_new();
|
||||
alsa->cond_lock = slock_new();
|
||||
alsa->cond = scond_new();
|
||||
alsa->buffer = fifo_new(alsa->buffer_size);
|
||||
if (!alsa->fifo_lock || !alsa->cond_lock || !alsa->cond || !alsa->buffer)
|
||||
goto error;
|
||||
|
||||
alsa->info.fifo_lock = slock_new();
|
||||
alsa->info.cond_lock = slock_new();
|
||||
alsa->info.cond = scond_new();
|
||||
alsa->info.buffer = fifo_new(alsa->info.stream_info.buffer_size);
|
||||
if (!alsa->info.fifo_lock || !alsa->info.cond_lock || !alsa->info.cond || !alsa->info.buffer)
|
||||
goto error;
|
||||
|
||||
alsa->info.worker_thread = sthread_create(alsa_worker_thread, alsa);
|
||||
if (!alsa->info.worker_thread)
|
||||
alsa->worker_thread = sthread_create(alsa_worker_thread, alsa);
|
||||
if (!alsa->worker_thread)
|
||||
{
|
||||
RARCH_ERR("[ALSA] Failed to initialize worker thread.\n");
|
||||
RARCH_ERR("error initializing worker thread");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return alsa;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA] Failed to initialize.\n");
|
||||
RARCH_ERR("ALSA: Failed to initialize...\n");
|
||||
if (params)
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
||||
if (sw_params)
|
||||
snd_pcm_sw_params_free(sw_params);
|
||||
|
||||
alsa_thread_free(alsa);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t alsa_thread_write(void *data, const void *s, size_t len)
|
||||
static ssize_t alsa_thread_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t _len = 0;
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
|
||||
if (alsa->info.thread_dead)
|
||||
if (alsa->thread_dead)
|
||||
return -1;
|
||||
|
||||
if (alsa->nonblock)
|
||||
{
|
||||
size_t avail;
|
||||
size_t write_amt;
|
||||
|
||||
slock_lock(alsa->info.fifo_lock);
|
||||
avail = FIFO_WRITE_AVAIL(alsa->info.buffer);
|
||||
_len = MIN(avail, len);
|
||||
slock_lock(alsa->fifo_lock);
|
||||
avail = FIFO_WRITE_AVAIL(alsa->buffer);
|
||||
write_amt = MIN(avail, size);
|
||||
|
||||
fifo_write(alsa->info.buffer, s, _len);
|
||||
slock_unlock(alsa->info.fifo_lock);
|
||||
fifo_write(alsa->buffer, buf, write_amt);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
|
||||
return write_amt;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (_len < (ssize_t)len && !alsa->info.thread_dead)
|
||||
size_t written = 0;
|
||||
while (written < size && !alsa->thread_dead)
|
||||
{
|
||||
size_t avail;
|
||||
slock_lock(alsa->info.fifo_lock);
|
||||
avail = FIFO_WRITE_AVAIL(alsa->info.buffer);
|
||||
slock_lock(alsa->fifo_lock);
|
||||
avail = FIFO_WRITE_AVAIL(alsa->buffer);
|
||||
|
||||
if (avail == 0)
|
||||
{
|
||||
slock_unlock(alsa->info.fifo_lock);
|
||||
slock_lock(alsa->info.cond_lock);
|
||||
if (!alsa->info.thread_dead)
|
||||
scond_wait(alsa->info.cond, alsa->info.cond_lock);
|
||||
slock_unlock(alsa->info.cond_lock);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
slock_lock(alsa->cond_lock);
|
||||
if (!alsa->thread_dead)
|
||||
scond_wait(alsa->cond, alsa->cond_lock);
|
||||
slock_unlock(alsa->cond_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t write_amt = MIN(len - _len, avail);
|
||||
fifo_write(alsa->info.buffer,
|
||||
(const char*)s + _len, write_amt);
|
||||
slock_unlock(alsa->info.fifo_lock);
|
||||
_len += write_amt;
|
||||
size_t write_amt = MIN(size - written, avail);
|
||||
fifo_write(alsa->buffer,
|
||||
(const char*)buf + written, write_amt);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
written += write_amt;
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
return _len;
|
||||
}
|
||||
|
||||
static bool alsa_thread_alive(void *data)
|
||||
|
@ -621,6 +304,7 @@ static bool alsa_thread_alive(void *data)
|
|||
static bool alsa_thread_stop(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
|
||||
if (alsa)
|
||||
alsa->is_paused = true;
|
||||
return true;
|
||||
|
@ -643,20 +327,79 @@ static bool alsa_thread_start(void *data, bool is_shutdown)
|
|||
|
||||
static size_t alsa_thread_write_avail(void *data)
|
||||
{
|
||||
size_t _len;
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
if (alsa->info.thread_dead)
|
||||
size_t val;
|
||||
|
||||
if (alsa->thread_dead)
|
||||
return 0;
|
||||
slock_lock(alsa->info.fifo_lock);
|
||||
_len = FIFO_WRITE_AVAIL(alsa->info.buffer);
|
||||
slock_unlock(alsa->info.fifo_lock);
|
||||
return _len;
|
||||
slock_lock(alsa->fifo_lock);
|
||||
val = FIFO_WRITE_AVAIL(alsa->buffer);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
return val;
|
||||
}
|
||||
|
||||
static size_t alsa_thread_buffer_size(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
return alsa->info.stream_info.buffer_size;
|
||||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
static void *alsa_thread_device_list_new(void *data)
|
||||
{
|
||||
void **hints, **n;
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *s = string_list_new();
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
attr.i = 0;
|
||||
|
||||
if (snd_device_name_hint(-1, "pcm", &hints) != 0)
|
||||
goto error;
|
||||
|
||||
n = hints;
|
||||
|
||||
while (*n)
|
||||
{
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
char *desc = snd_device_name_get_hint(*n, "DESC");
|
||||
|
||||
/* description of device IOID - input / output identifcation
|
||||
* ("Input" or "Output"), NULL means both) */
|
||||
|
||||
if (!io || string_is_equal(io,"Output"))
|
||||
string_list_append(s, name, attr);
|
||||
|
||||
if (name)
|
||||
free(name);
|
||||
if (io)
|
||||
free(io);
|
||||
if (desc)
|
||||
free(desc);
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
/* free hint buffer too */
|
||||
snd_device_name_free_hint(hints);
|
||||
|
||||
return s;
|
||||
|
||||
error:
|
||||
string_list_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void alsa_thread_device_list_free(void *data, void *array_list_data)
|
||||
{
|
||||
struct string_list *s = (struct string_list*)array_list_data;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
string_list_free(s);
|
||||
}
|
||||
|
||||
audio_driver_t audio_alsathread = {
|
||||
|
@ -669,8 +412,8 @@ audio_driver_t audio_alsathread = {
|
|||
alsa_thread_free,
|
||||
alsa_thread_use_float,
|
||||
"alsathread",
|
||||
alsa_device_list_new, /* Reusing these functions from alsa.c */
|
||||
alsa_device_list_free, /* because they don't use the driver context */
|
||||
alsa_thread_device_list_new,
|
||||
alsa_thread_device_list_free,
|
||||
alsa_thread_write_avail,
|
||||
alsa_thread_buffer_size
|
||||
alsa_thread_buffer_size,
|
||||
};
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
#define DEFAULT_DEV "/dev/audio"
|
||||
|
||||
static void *audioio_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames, unsigned *new_out_rate)
|
||||
unsigned block_frames,
|
||||
unsigned *new_out_rate)
|
||||
{
|
||||
struct audio_info info;
|
||||
const char *audiodev = device ? device : DEFAULT_DEV;
|
||||
|
@ -81,15 +82,15 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t audioio_write(void *data, const void *s, size_t len)
|
||||
static ssize_t audioio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t _len;
|
||||
ssize_t ret;
|
||||
int *fd = (int*)data;
|
||||
|
||||
if (len == 0)
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
if ((_len = write(*fd, s, len)) < 0)
|
||||
if ((ret = write(*fd, buf, size)) < 0)
|
||||
{
|
||||
if (errno == EAGAIN && (fcntl(*fd, F_GETFL) & O_NONBLOCK))
|
||||
return 0;
|
||||
|
@ -97,7 +98,7 @@ static ssize_t audioio_write(void *data, const void *s, size_t len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
return _len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool audioio_stop(void *data)
|
||||
|
@ -157,7 +158,7 @@ static void audioio_set_nonblock_state(void *data, bool state)
|
|||
else
|
||||
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & (~O_NONBLOCK));
|
||||
if (rc != 0)
|
||||
RARCH_WARN("[AudioIO] Could not set nonblocking on audio file descriptor. Will not be able to fast-forward.\n");
|
||||
RARCH_WARN("Could not set nonblocking on audio file descriptor. Will not be able to fast-forward.\n");
|
||||
}
|
||||
|
||||
static void audioio_free(void *data)
|
||||
|
@ -188,8 +189,11 @@ static size_t audioio_write_avail(void *data)
|
|||
return audioio_buffer_size(data);
|
||||
}
|
||||
|
||||
/* TODO/FIXME - implement? */
|
||||
static bool audioio_use_float(void *data) { return false; }
|
||||
static bool audioio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_audioio = {
|
||||
audioio_init,
|
||||
|
|
|
@ -1,524 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2025 - OlyB
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <emscripten/wasm_worker.h>
|
||||
#include <emscripten/webaudio.h>
|
||||
#include <emscripten/atomic.h>
|
||||
#include "../../frontend/drivers/platform_emscripten.h"
|
||||
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define WORKLET_STACK_SIZE 4096
|
||||
|
||||
/* additional buffer size (for EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK only) */
|
||||
/* if this is too small, frames may be dropped and content could run too fast. */
|
||||
/* very large slow-motion rate values may be too large for this; avoid anything higher than 6 or 7. */
|
||||
#define EXTERNAL_BLOCK_BUFFER_MS 128
|
||||
|
||||
typedef struct audioworklet_data
|
||||
{
|
||||
uint8_t *worklet_stack;
|
||||
uint32_t write_avail_bytes; /* atomic */
|
||||
size_t visible_buffer_size;
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
size_t write_avail_diff;
|
||||
#endif
|
||||
#ifdef PROXY_TO_PTHREAD
|
||||
emscripten_lock_t trywrite_lock;
|
||||
emscripten_condvar_t trywrite_cond;
|
||||
#endif
|
||||
emscripten_lock_t buffer_lock;
|
||||
EMSCRIPTEN_WEBAUDIO_T context;
|
||||
float *tmpbuf;
|
||||
fifo_buffer_t *buffer;
|
||||
unsigned rate;
|
||||
unsigned latency;
|
||||
bool nonblock;
|
||||
bool initing;
|
||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||
bool block_requested;
|
||||
#endif
|
||||
volatile bool running; /* currently only used by RetroArch */
|
||||
volatile bool driver_running; /* whether the driver is running (buffer allocated) */
|
||||
volatile bool context_running; /* whether the AudioContext is running */
|
||||
volatile bool init_done;
|
||||
volatile bool init_error;
|
||||
} audioworklet_data_t;
|
||||
|
||||
/* We only ever want to create 1 worklet, so we need to keep its data even if the driver is inactive. */
|
||||
static audioworklet_data_t *audioworklet_static_data = NULL;
|
||||
|
||||
/* Note that we cannot allocate any heap in here. */
|
||||
static bool audioworklet_process_cb(int numInputs, const AudioSampleFrame *inputs,
|
||||
int numOutputs, AudioSampleFrame *outputs,
|
||||
int numParams, const AudioParamFrame *params,
|
||||
void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
size_t avail;
|
||||
size_t max_read;
|
||||
unsigned writing_frames = 0;
|
||||
int i;
|
||||
|
||||
/* TODO: do we need to pay attention to audioworklet->running here too? */
|
||||
if (audioworklet->driver_running)
|
||||
{
|
||||
/* can't use Atomics.wait in AudioWorklet */
|
||||
/* busyspin is safe as of emscripten 4.0.4 */
|
||||
if (!emscripten_lock_busyspin_wait_acquire(&audioworklet->buffer_lock, 2.5))
|
||||
{
|
||||
printf("[WARN] [AudioWorklet] Worklet: could not acquire lock\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
avail = FIFO_READ_AVAIL(audioworklet->buffer);
|
||||
max_read = MIN(avail, outputs[0].samplesPerChannel * 2 * sizeof(float));
|
||||
|
||||
if (max_read)
|
||||
{
|
||||
fifo_read(audioworklet->buffer, audioworklet->tmpbuf, max_read);
|
||||
emscripten_atomic_add_u32(&audioworklet->write_avail_bytes, max_read);
|
||||
}
|
||||
emscripten_lock_release(&audioworklet->buffer_lock);
|
||||
#ifdef PROXY_TO_PTHREAD
|
||||
emscripten_condvar_signal(&audioworklet->trywrite_cond, 1);
|
||||
#endif
|
||||
|
||||
writing_frames = max_read / 2 / sizeof(float);
|
||||
for (i = 0; i < writing_frames; i++)
|
||||
{
|
||||
outputs[0].data[i] = audioworklet->tmpbuf[i * 2];
|
||||
outputs[0].data[outputs[0].samplesPerChannel + i] = audioworklet->tmpbuf[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (writing_frames < outputs[0].samplesPerChannel)
|
||||
{
|
||||
int zero_frames = outputs[0].samplesPerChannel - writing_frames;
|
||||
memset(outputs[0].data + writing_frames, 0, zero_frames * sizeof(float));
|
||||
memset(outputs[0].data + writing_frames + outputs[0].samplesPerChannel, 0, zero_frames * sizeof(float));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void audioworklet_processor_inited_cb(EMSCRIPTEN_WEBAUDIO_T context, bool success, void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
int outputChannelCounts[1] = { 2 };
|
||||
EmscriptenAudioWorkletNodeCreateOptions opts = { 0, 1, outputChannelCounts };
|
||||
EMSCRIPTEN_AUDIO_WORKLET_NODE_T worklet_node;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
RARCH_ERR("[AudioWorklet] Failed to init AudioWorkletProcessor.\n");
|
||||
audioworklet->init_error = true;
|
||||
audioworklet->init_done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
worklet_node = emscripten_create_wasm_audio_worklet_node(context, "retroarch", &opts, audioworklet_process_cb, audioworklet);
|
||||
emscripten_audio_node_connect(worklet_node, context, 0, 0);
|
||||
|
||||
audioworklet->init_done = true;
|
||||
}
|
||||
|
||||
static void audioworklet_thread_inited_cb(EMSCRIPTEN_WEBAUDIO_T context, bool success, void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
WebAudioWorkletProcessorCreateOptions opts = { "retroarch", 0 };
|
||||
|
||||
if (success)
|
||||
emscripten_create_wasm_audio_worklet_processor_async(context, &opts,
|
||||
audioworklet_processor_inited_cb, audioworklet);
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[AudioWorklet] Failed to init worklet thread! Is the worklet file in the right place?\n");
|
||||
audioworklet->init_error = true;
|
||||
audioworklet->init_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void audioworklet_ctx_statechange_cb(void *data, bool state)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
audioworklet->context_running = state;
|
||||
}
|
||||
|
||||
static void audioworklet_ctx_create(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
audioworklet->context = emscripten_create_audio_context(0);
|
||||
|
||||
audioworklet->tmpbuf = memalign(16, emscripten_audio_context_quantum_size(audioworklet->context) * 2 * sizeof(float));
|
||||
audioworklet->rate = EM_ASM_INT({
|
||||
return emscriptenGetAudioObject($0).sampleRate;
|
||||
}, audioworklet->context);
|
||||
audioworklet->context_running = EM_ASM_INT({
|
||||
let ac = emscriptenGetAudioObject($0);
|
||||
ac.addEventListener("statechange", function() {
|
||||
getWasmTableEntry($2)($1, ac.state == "running");
|
||||
});
|
||||
return ac.state == "running";
|
||||
}, audioworklet->context, audioworklet, audioworklet_ctx_statechange_cb);
|
||||
|
||||
emscripten_start_wasm_audio_worklet_thread_async(audioworklet->context,
|
||||
audioworklet->worklet_stack, WORKLET_STACK_SIZE, audioworklet_thread_inited_cb, audioworklet);
|
||||
}
|
||||
|
||||
static void audioworklet_alloc_buffer(void *data)
|
||||
{
|
||||
size_t buffer_size;
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
audioworklet->visible_buffer_size = (audioworklet->latency * audioworklet->rate * 2 * sizeof(float)) / 1000;
|
||||
buffer_size = audioworklet->visible_buffer_size;
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
audioworklet->write_avail_diff = (EXTERNAL_BLOCK_BUFFER_MS * audioworklet->rate * 2 * sizeof(float)) / 1000;
|
||||
buffer_size += audioworklet->write_avail_diff;
|
||||
#endif
|
||||
audioworklet->buffer = fifo_new(buffer_size);
|
||||
emscripten_atomic_store_u32(&audioworklet->write_avail_bytes, buffer_size);
|
||||
RARCH_LOG("[AudioWorklet] Buffer size: %lu bytes.\n", audioworklet->visible_buffer_size);
|
||||
}
|
||||
|
||||
static void audioworklet_init_error(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
RARCH_ERR("[AudioWorklet] Failed to initialize driver.\n");
|
||||
free(audioworklet->worklet_stack);
|
||||
free(audioworklet->tmpbuf);
|
||||
free(audioworklet);
|
||||
}
|
||||
|
||||
static bool audioworklet_resume_ctx(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
if (!audioworklet->context_running)
|
||||
{
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
emscriptenGetAudioObject($0).resume();
|
||||
}, audioworklet->context);
|
||||
}
|
||||
return audioworklet->context_running;
|
||||
}
|
||||
|
||||
static void *audioworklet_init(const char *device, unsigned rate,
|
||||
unsigned latency, unsigned block_frames, unsigned *new_rate)
|
||||
{
|
||||
audioworklet_data_t *audioworklet;
|
||||
if (audioworklet_static_data)
|
||||
{
|
||||
if (audioworklet_static_data->driver_running || audioworklet_static_data->initing)
|
||||
{
|
||||
RARCH_ERR("[AudioWorklet] Tried to start already running driver.\n");
|
||||
return NULL;
|
||||
}
|
||||
RARCH_LOG("[AudioWorklet] Reusing old context.\n");
|
||||
audioworklet = audioworklet_static_data;
|
||||
audioworklet->latency = latency;
|
||||
*new_rate = audioworklet->rate;
|
||||
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
||||
audioworklet_alloc_buffer(audioworklet);
|
||||
audioworklet_resume_ctx(audioworklet);
|
||||
audioworklet->driver_running = true;
|
||||
return audioworklet;
|
||||
}
|
||||
|
||||
audioworklet = (audioworklet_data_t*)calloc(1, sizeof(audioworklet_data_t));
|
||||
if (!audioworklet)
|
||||
return NULL;
|
||||
audioworklet->worklet_stack = memalign(16, WORKLET_STACK_SIZE);
|
||||
if (!audioworklet->worklet_stack)
|
||||
return NULL;
|
||||
audioworklet_static_data = audioworklet;
|
||||
|
||||
audioworklet->latency = latency;
|
||||
platform_emscripten_run_on_browser_thread_sync(audioworklet_ctx_create, audioworklet);
|
||||
*new_rate = audioworklet->rate;
|
||||
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
||||
audioworklet->initing = true;
|
||||
audioworklet_alloc_buffer(audioworklet);
|
||||
emscripten_lock_init(&audioworklet->buffer_lock);
|
||||
#ifdef PROXY_TO_PTHREAD
|
||||
emscripten_lock_init(&audioworklet->trywrite_lock);
|
||||
emscripten_condvar_init(&audioworklet->trywrite_cond);
|
||||
#endif
|
||||
|
||||
#ifndef EMSCRIPTEN_AUDIO_EXTERNAL_BLOCK
|
||||
/* TODO: can MIN_ASYNCIFY block here too? */
|
||||
while (!audioworklet->init_done)
|
||||
retro_sleep(1);
|
||||
audioworklet->initing = false;
|
||||
if (audioworklet->init_error)
|
||||
{
|
||||
audioworklet_init_error(audioworklet);
|
||||
return NULL;
|
||||
}
|
||||
audioworklet->driver_running = true;
|
||||
#elif defined(EMSCRIPTEN_AUDIO_FAKE_BLOCK)
|
||||
audioworklet->block_requested = true;
|
||||
platform_emscripten_enter_fake_block(1);
|
||||
#endif
|
||||
/* external block: will be handled later */
|
||||
|
||||
return audioworklet;
|
||||
}
|
||||
|
||||
static ssize_t audioworklet_write(void *data, const void *s, size_t ss)
|
||||
{
|
||||
size_t avail;
|
||||
size_t max_write;
|
||||
size_t to_write_frames;
|
||||
size_t to_write_bytes;
|
||||
size_t _len = 0;
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
const float *samples = (const float*)s;
|
||||
size_t num_frames = ss / 2 / sizeof(float);
|
||||
|
||||
/* too early! might happen with external blocking */
|
||||
if (!audioworklet->driver_running)
|
||||
return 0;
|
||||
|
||||
/* don't write audio if the context isn't running, just try to start it */
|
||||
if (!audioworklet_resume_ctx(audioworklet))
|
||||
return 0;
|
||||
|
||||
while (num_frames)
|
||||
{
|
||||
#ifdef PROXY_TO_PTHREAD
|
||||
if (!emscripten_lock_wait_acquire(&audioworklet->buffer_lock, 2500000))
|
||||
#else
|
||||
if (!emscripten_lock_busyspin_wait_acquire(&audioworklet->buffer_lock, 2.5))
|
||||
#endif
|
||||
{
|
||||
RARCH_WARN("[AudioWorklet] Main thread: could not acquire lock.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
avail = FIFO_WRITE_AVAIL(audioworklet->buffer);
|
||||
max_write = avail;
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
/* make sure we don't write into the blocking buffer for nonblock */
|
||||
if (audioworklet->nonblock)
|
||||
{
|
||||
if (max_write > audioworklet->write_avail_diff)
|
||||
max_write -= audioworklet->write_avail_diff;
|
||||
else
|
||||
max_write = 0;
|
||||
}
|
||||
#endif
|
||||
to_write_frames = MIN(num_frames, max_write / 2 / sizeof(float));
|
||||
if (to_write_frames)
|
||||
{
|
||||
to_write_bytes = to_write_frames * 2 * sizeof(float);
|
||||
avail -= to_write_bytes;
|
||||
fifo_write(audioworklet->buffer, samples, to_write_bytes);
|
||||
emscripten_atomic_store_u32(&audioworklet->write_avail_bytes, (uint32_t)avail);
|
||||
num_frames -= to_write_frames;
|
||||
samples += (to_write_frames * 2);
|
||||
_len += to_write_frames;
|
||||
}
|
||||
|
||||
emscripten_lock_release(&audioworklet->buffer_lock);
|
||||
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||
/* see if we're over the threshold to go to fake block */
|
||||
if (avail < audioworklet->write_avail_diff)
|
||||
{
|
||||
audioworklet->block_requested = true;
|
||||
platform_emscripten_enter_fake_block(1);
|
||||
}
|
||||
#endif
|
||||
if (num_frames && !audioworklet->nonblock)
|
||||
RARCH_WARN("[AudioWorklet] Dropping %lu frames.\n", num_frames);
|
||||
break;
|
||||
#endif
|
||||
if (audioworklet->nonblock || !num_frames)
|
||||
break;
|
||||
#if defined(PROXY_TO_PTHREAD)
|
||||
emscripten_condvar_wait(&audioworklet->trywrite_cond, &audioworklet->trywrite_lock, 3000000);
|
||||
#elif defined(EMSCRIPTEN_FULL_ASYNCIFY)
|
||||
retro_sleep(1);
|
||||
#else /* equivalent to defined(EMSCRIPTEN_AUDIO_BUSYWAIT) */
|
||||
while (emscripten_atomic_load_u32(&audioworklet->write_avail_bytes) < 2 * sizeof(float))
|
||||
audioworklet_resume_ctx(audioworklet);
|
||||
#endif
|
||||
/* try resuming, on the off chance that the context was interrupted while blocking */
|
||||
audioworklet_resume_ctx(audioworklet);
|
||||
}
|
||||
|
||||
return _len;
|
||||
}
|
||||
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_BLOCK
|
||||
/* returns true if fake block should continue */
|
||||
bool audioworklet_external_block(void)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = audioworklet_static_data;
|
||||
|
||||
if (audioworklet)
|
||||
{
|
||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||
if (!audioworklet->block_requested)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
while (audioworklet->initing && !audioworklet->init_done)
|
||||
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
||||
retro_sleep(1);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
if (audioworklet->init_done && !audioworklet->driver_running)
|
||||
{
|
||||
audioworklet->initing = false;
|
||||
if (audioworklet->init_error)
|
||||
{
|
||||
audioworklet_init_error(audioworklet);
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
audioworklet->driver_running = true;
|
||||
}
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
if (!audioworklet->driver_running)
|
||||
return false;
|
||||
|
||||
while (emscripten_atomic_load_u32(&audioworklet->write_avail_bytes) < audioworklet->write_avail_diff)
|
||||
{
|
||||
audioworklet_resume_ctx(audioworklet);
|
||||
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
||||
retro_sleep(1);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||
audioworklet->block_requested = false;
|
||||
platform_emscripten_exit_fake_block();
|
||||
return true; /* return to RAF if needed */
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool audioworklet_stop(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
audioworklet->running = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool audioworklet_start(void *data, bool is_shutdown)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
audioworklet->running = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool audioworklet_alive(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
return audioworklet->running;
|
||||
}
|
||||
|
||||
static void audioworklet_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
audioworklet->nonblock = state;
|
||||
}
|
||||
|
||||
static void audioworklet_free(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
/* that's not good... this shouldn't happen? */
|
||||
if (!audioworklet->driver_running)
|
||||
{
|
||||
RARCH_ERR("[AudioWorklet] Tried to free before done initing.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PROXY_TO_PTHREAD
|
||||
if (!emscripten_lock_wait_acquire(&audioworklet->buffer_lock, 10000000))
|
||||
#else
|
||||
if (!emscripten_lock_busyspin_wait_acquire(&audioworklet->buffer_lock, 10))
|
||||
#endif
|
||||
{
|
||||
RARCH_ERR("[AudioWorklet] Main thread: could not acquire lock to free buffer.\n");
|
||||
return;
|
||||
}
|
||||
audioworklet->driver_running = false;
|
||||
fifo_free(audioworklet->buffer);
|
||||
emscripten_lock_release(&audioworklet->buffer_lock);
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
emscriptenGetAudioObject($0).suspend();
|
||||
}, audioworklet->context);
|
||||
}
|
||||
|
||||
static size_t audioworklet_write_avail(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
|
||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||
size_t avail = emscripten_atomic_load_u32(&audioworklet->write_avail_bytes);
|
||||
if (avail > audioworklet->write_avail_diff)
|
||||
return avail - audioworklet->write_avail_diff;
|
||||
return 0;
|
||||
#else
|
||||
return emscripten_atomic_load_u32(&audioworklet->write_avail_bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t audioworklet_buffer_size(void *data)
|
||||
{
|
||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||
return audioworklet->visible_buffer_size;
|
||||
}
|
||||
|
||||
static bool audioworklet_use_float(void *data) { return true; }
|
||||
|
||||
audio_driver_t audio_audioworklet = {
|
||||
audioworklet_init,
|
||||
audioworklet_write,
|
||||
audioworklet_stop,
|
||||
audioworklet_start,
|
||||
audioworklet_alive,
|
||||
audioworklet_set_nonblock_state,
|
||||
audioworklet_free,
|
||||
audioworklet_use_float,
|
||||
"audioworklet",
|
||||
NULL,
|
||||
NULL,
|
||||
audioworklet_write_avail,
|
||||
audioworklet_buffer_size
|
||||
};
|
|
@ -31,10 +31,9 @@
|
|||
#include <retro_endianness.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include <defines/cocoa_defines.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "defines/cocoa_defines.h"
|
||||
|
||||
typedef struct coreaudio
|
||||
{
|
||||
|
@ -52,6 +51,10 @@ typedef struct coreaudio
|
|||
bool nonblock;
|
||||
} coreaudio_t;
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
static bool g_interrupted;
|
||||
#endif
|
||||
|
||||
static void coreaudio_free(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
|
@ -78,7 +81,7 @@ static void coreaudio_free(void *data)
|
|||
free(dev);
|
||||
}
|
||||
|
||||
static OSStatus coreaudio_audio_write_cb(void *userdata,
|
||||
static OSStatus audio_write_cb(void *userdata,
|
||||
AudioUnitRenderActionFlags *action_flags,
|
||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||
UInt32 number_frames, AudioBufferList *io_data)
|
||||
|
@ -102,21 +105,36 @@ static OSStatus coreaudio_audio_write_cb(void *userdata,
|
|||
if (FIFO_READ_AVAIL(dev->buffer) < write_avail)
|
||||
{
|
||||
*action_flags = kAudioUnitRenderAction_OutputIsSilence;
|
||||
|
||||
/* Seems to be needed. */
|
||||
memset(outbuf, 0, write_avail);
|
||||
|
||||
slock_unlock(dev->lock);
|
||||
|
||||
/* Technically possible to deadlock without. */
|
||||
scond_signal(dev->cond);
|
||||
return noErr;
|
||||
}
|
||||
else
|
||||
|
||||
fifo_read(dev->buffer, outbuf, write_avail);
|
||||
slock_unlock(dev->lock);
|
||||
scond_signal(dev->cond);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
||||
#if TARGET_OS_IPHONE
|
||||
static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
|
||||
{
|
||||
int i;
|
||||
UInt32 device_count;
|
||||
(void)data;
|
||||
#if TARGET_OS_IOS
|
||||
g_interrupted = (interrupt_state == kAudioSessionBeginInterruption);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||
{
|
||||
unsigned i;
|
||||
UInt32 deviceCount;
|
||||
AudioObjectPropertyAddress propaddr;
|
||||
AudioDeviceID *devices = NULL;
|
||||
UInt32 size = 0;
|
||||
|
@ -133,19 +151,20 @@ static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
|||
&propaddr, 0, 0, &size) != noErr)
|
||||
return;
|
||||
|
||||
device_count = size / sizeof(AudioDeviceID);
|
||||
deviceCount = size / sizeof(AudioDeviceID);
|
||||
devices = (AudioDeviceID*)malloc(size);
|
||||
|
||||
if (devices && AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&propaddr, 0, 0, &size, devices) == noErr)
|
||||
{
|
||||
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&propaddr, 0, 0, &size, devices) != noErr)
|
||||
goto done;
|
||||
|
||||
#if HAS_MACOSX_10_12
|
||||
#else
|
||||
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
||||
#endif
|
||||
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
||||
|
||||
for (i = 0; i < (int)device_count; i ++)
|
||||
for (i = 0; i < deviceCount; i ++)
|
||||
{
|
||||
char device_name[1024];
|
||||
device_name[0] = 0;
|
||||
|
@ -157,11 +176,11 @@ static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
|||
{
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
free(devices);
|
||||
}
|
||||
#endif
|
||||
|
@ -184,6 +203,8 @@ static void *coreaudio_init(const char *device,
|
|||
#endif
|
||||
AURenderCallbackStruct cb = {0};
|
||||
AudioStreamBasicDescription stream_desc = {0};
|
||||
bool component_unavailable = false;
|
||||
static bool session_initialized = false;
|
||||
#if !HAS_MACOSX_10_12
|
||||
ComponentDescription desc = {0};
|
||||
#else
|
||||
|
@ -194,9 +215,21 @@ static void *coreaudio_init(const char *device,
|
|||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
(void)session_initialized;
|
||||
(void)device;
|
||||
|
||||
dev->lock = slock_new();
|
||||
dev->cond = scond_new();
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
if (!session_initialized)
|
||||
{
|
||||
session_initialized = true;
|
||||
AudioSessionInitialize(0, 0, coreaudio_interrupt_listener, 0);
|
||||
AudioSessionSetActive(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create AudioComponent */
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
#if TARGET_OS_IPHONE
|
||||
|
@ -207,24 +240,25 @@ static void *coreaudio_init(const char *device,
|
|||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
#if !HAS_MACOSX_10_12
|
||||
if (!(comp = FindNextComponent(NULL, &desc)))
|
||||
goto error;
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
#else
|
||||
if (!(comp = AudioComponentFindNext(NULL, &desc)))
|
||||
goto error;
|
||||
comp = AudioComponentFindNext(NULL, &desc);
|
||||
#endif
|
||||
if (!comp)
|
||||
goto error;
|
||||
|
||||
#if !HAS_MACOSX_10_12
|
||||
if ((OpenAComponent(comp, &dev->dev) != noErr))
|
||||
goto error;
|
||||
component_unavailable = (OpenAComponent(comp, &dev->dev) != noErr);
|
||||
#else
|
||||
if ((AudioComponentInstanceNew(comp, &dev->dev) != noErr))
|
||||
goto error;
|
||||
component_unavailable = (AudioComponentInstanceNew(comp, &dev->dev) != noErr);
|
||||
#endif
|
||||
|
||||
if (component_unavailable)
|
||||
goto error;
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (device)
|
||||
coreaudio_choose_output_device(dev, device);
|
||||
choose_output_device(dev, device);
|
||||
#endif
|
||||
|
||||
dev->dev_alive = true;
|
||||
|
@ -237,11 +271,9 @@ static void *coreaudio_init(const char *device,
|
|||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||
stream_desc.mFramesPerPacket = 1;
|
||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat
|
||||
| kAudioFormatFlagIsPacked;
|
||||
|
||||
if (!is_little_endian())
|
||||
stream_desc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat |
|
||||
kAudioFormatFlagIsPacked | (is_little_endian() ?
|
||||
0 : kAudioFormatFlagIsBigEndian);
|
||||
|
||||
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
|
||||
|
@ -262,7 +294,7 @@ static void *coreaudio_init(const char *device,
|
|||
if (real_desc.mFormatID != stream_desc.mFormatID)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio] Using output sample rate of %.1f Hz.\n",
|
||||
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n",
|
||||
(float)real_desc.mSampleRate);
|
||||
*new_rate = real_desc.mSampleRate;
|
||||
|
||||
|
@ -275,7 +307,7 @@ static void *coreaudio_init(const char *device,
|
|||
#endif
|
||||
|
||||
/* Set callbacks and finish up. */
|
||||
cb.inputProc = coreaudio_audio_write_cb;
|
||||
cb.inputProc = audio_write_cb;
|
||||
cb.inputProcRefCon = dev;
|
||||
|
||||
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
|
||||
|
@ -289,10 +321,11 @@ static void *coreaudio_init(const char *device,
|
|||
fifo_size *= 2 * sizeof(float);
|
||||
dev->buffer_size = fifo_size;
|
||||
|
||||
if (!(dev->buffer = fifo_new(fifo_size)))
|
||||
dev->buffer = fifo_new(fifo_size);
|
||||
if (!dev->buffer)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio] Using buffer size of %u bytes: (latency = %u ms).\n",
|
||||
RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n",
|
||||
(unsigned)fifo_size, latency);
|
||||
|
||||
if (AudioOutputUnitStart(dev->dev) != noErr)
|
||||
|
@ -301,31 +334,35 @@ static void *coreaudio_init(const char *device,
|
|||
return dev;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[CoreAudio] Failed to initialize driver.\n");
|
||||
RARCH_ERR("[CoreAudio]: Failed to initialize driver ...\n");
|
||||
coreaudio_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t coreaudio_write(void *data, const void *buf_, size_t len)
|
||||
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t _len = 0;
|
||||
size_t written = 0;
|
||||
|
||||
while (!dev->is_paused && len > 0)
|
||||
#if TARGET_OS_IOS
|
||||
while (!g_interrupted && size > 0)
|
||||
#else
|
||||
while (size > 0)
|
||||
#endif
|
||||
{
|
||||
size_t write_avail;
|
||||
|
||||
slock_lock(dev->lock);
|
||||
|
||||
write_avail = FIFO_WRITE_AVAIL(dev->buffer);
|
||||
if (write_avail > len)
|
||||
write_avail = len;
|
||||
if (write_avail > size)
|
||||
write_avail = size;
|
||||
|
||||
fifo_write(dev->buffer, buf, write_avail);
|
||||
buf += write_avail;
|
||||
_len += write_avail;
|
||||
len -= write_avail;
|
||||
written += write_avail;
|
||||
size -= write_avail;
|
||||
|
||||
if (dev->nonblock)
|
||||
{
|
||||
|
@ -335,11 +372,8 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t len)
|
|||
|
||||
#if TARGET_OS_IOS
|
||||
if (write_avail == 0 && !scond_wait_timeout(
|
||||
dev->cond, dev->lock, 300000))
|
||||
{
|
||||
slock_unlock(dev->lock);
|
||||
break;
|
||||
}
|
||||
dev->cond, dev->lock, 3000000))
|
||||
g_interrupted = true;
|
||||
#else
|
||||
if (write_avail == 0)
|
||||
scond_wait(dev->cond, dev->lock);
|
||||
|
@ -347,7 +381,7 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t len)
|
|||
slock_unlock(dev->lock);
|
||||
}
|
||||
|
||||
return _len;
|
||||
return written;
|
||||
}
|
||||
|
||||
static void coreaudio_set_nonblock_state(void *data, bool state)
|
||||
|
@ -368,28 +402,26 @@ static bool coreaudio_alive(void *data)
|
|||
static bool coreaudio_stop(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (dev)
|
||||
{
|
||||
dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false;
|
||||
if (dev->is_paused)
|
||||
return true;
|
||||
}
|
||||
if (!dev)
|
||||
return false;
|
||||
dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false;
|
||||
return dev->is_paused ? true : false;
|
||||
}
|
||||
|
||||
static bool coreaudio_start(void *data, bool is_shutdown)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (dev)
|
||||
{
|
||||
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
|
||||
if (!dev->is_paused)
|
||||
return true;
|
||||
}
|
||||
if (!dev)
|
||||
return false;
|
||||
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
|
||||
return dev->is_paused ? false : true;
|
||||
}
|
||||
|
||||
static bool coreaudio_use_float(void *data) { return true; }
|
||||
static bool coreaudio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t coreaudio_write_avail(void *data)
|
||||
{
|
||||
|
@ -409,9 +441,16 @@ static size_t coreaudio_buffer_size(void *data)
|
|||
return dev->buffer_size;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - implement */
|
||||
static void *coreaudio_device_list_new(void *data) { return NULL; }
|
||||
static void coreaudio_device_list_free(void *data, void *array_list_data) { }
|
||||
static void *coreaudio_device_list_new(void *data)
|
||||
{
|
||||
/* TODO/FIXME */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void coreaudio_device_list_free(void *data, void *array_list_data)
|
||||
{
|
||||
/* TODO/FIXME */
|
||||
}
|
||||
|
||||
audio_driver_t audio_coreaudio = {
|
||||
coreaudio_init,
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
|
||||
#pragma mark - ringbuffer
|
||||
|
||||
#define UNLIKELY(x) __builtin_expect((x), 0)
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
|
||||
typedef struct ringbuffer
|
||||
{
|
||||
float *buffer;
|
||||
|
@ -96,6 +93,9 @@ static void rb_free(ringbuffer_h r)
|
|||
memset(r, 0, sizeof(*r));
|
||||
}
|
||||
|
||||
#define UNLIKELY(x) __builtin_expect((x), 0)
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
|
||||
static void rb_write_data(ringbuffer_h r, const float *data, size_t len)
|
||||
{
|
||||
size_t avail = rb_avail(r);
|
||||
|
@ -155,7 +155,7 @@ static void rb_read_data(ringbuffer_h r,
|
|||
|
||||
#pragma mark - CoreAudio3
|
||||
|
||||
static bool coreaudio3_g_interrupted;
|
||||
static bool g_interrupted;
|
||||
|
||||
@interface CoreAudio3 : NSObject {
|
||||
ringbuffer_t _rb;
|
||||
|
@ -204,7 +204,7 @@ static bool coreaudio3_g_interrupted;
|
|||
return nil;
|
||||
|
||||
format = au.outputBusses[0].format;
|
||||
if (format.channelCount < 2)
|
||||
if (format.channelCount != 2)
|
||||
return nil;
|
||||
|
||||
renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2];
|
||||
|
@ -227,7 +227,7 @@ static bool coreaudio3_g_interrupted;
|
|||
|
||||
_au = au;
|
||||
|
||||
RARCH_LOG("[CoreAudio3] Using buffer size of %u bytes: (latency = %u ms).\n", (unsigned)self.bufferSizeInBytes, latency);
|
||||
RARCH_LOG("[CoreAudio3]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)self.bufferSizeInBytes, latency);
|
||||
|
||||
[self start];
|
||||
}
|
||||
|
@ -260,8 +260,8 @@ static bool coreaudio3_g_interrupted;
|
|||
}
|
||||
|
||||
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
|
||||
size_t _len = 0;
|
||||
while (!coreaudio3_g_interrupted && samples > 0)
|
||||
size_t written = 0;
|
||||
while (!g_interrupted && samples > 0)
|
||||
{
|
||||
size_t write_avail = rb_avail(&_rb);
|
||||
if (write_avail > samples)
|
||||
|
@ -269,7 +269,7 @@ static bool coreaudio3_g_interrupted;
|
|||
|
||||
rb_write_data(&_rb, data, write_avail);
|
||||
data += write_avail;
|
||||
_len += write_avail;
|
||||
written += write_avail;
|
||||
samples -= write_avail;
|
||||
|
||||
if (_nonBlock)
|
||||
|
@ -279,7 +279,7 @@ static bool coreaudio3_g_interrupted;
|
|||
dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
|
||||
return _len;
|
||||
return written;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -307,11 +307,12 @@ static void *coreaudio3_init(const char *device,
|
|||
return (__bridge_retained void *)dev;
|
||||
}
|
||||
|
||||
static ssize_t coreaudio3_write(void *data, const void *buf_, size_t len)
|
||||
static ssize_t coreaudio3_write(void *data,
|
||||
const void *buf_, size_t size)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
return [dev writeFloat:(const float *)
|
||||
buf_ samples:len / sizeof(float)] * sizeof(float);
|
||||
buf_ samples:size/sizeof(float)] * sizeof(float);
|
||||
}
|
||||
|
||||
static void coreaudio3_set_nonblock_state(void *data, bool state)
|
||||
|
@ -327,7 +328,8 @@ static bool coreaudio3_alive(void *data)
|
|||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return false;
|
||||
return NO;
|
||||
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
|
@ -335,7 +337,8 @@ static bool coreaudio3_stop(void *data)
|
|||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return false;
|
||||
return NO;
|
||||
|
||||
[dev stop];
|
||||
return dev.paused;
|
||||
}
|
||||
|
@ -344,13 +347,16 @@ static bool coreaudio3_start(void *data, bool is_shutdown)
|
|||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return false;
|
||||
return NO;
|
||||
|
||||
[dev start];
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_use_float(void *data) { return true; }
|
||||
static bool coreaudio3_use_float(void *data)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
static size_t coreaudio3_write_avail(void *data)
|
||||
{
|
||||
|
|
|
@ -1,486 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2025 - Joseph Mattiello
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#include "audio/microphone_driver.h"
|
||||
#include "queues/fifo_queue.h"
|
||||
#include "verbosity.h"
|
||||
#include <memory.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "audio/audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct coreaudio_microphone
|
||||
{
|
||||
AudioUnit audio_unit; /* CoreAudio audio unit */
|
||||
AudioStreamBasicDescription format; /* Audio format */
|
||||
fifo_buffer_t *sample_buffer; /* Sample buffer */
|
||||
bool is_running; /* Whether the microphone is running */
|
||||
bool nonblock; /* Non-blocking mode flag */
|
||||
int sample_rate; /* Current sample rate */
|
||||
bool use_float; /* Whether to use float format */
|
||||
} coreaudio_microphone_t;
|
||||
|
||||
/* Callback for receiving audio samples */
|
||||
static OSStatus coreaudio_input_callback(
|
||||
void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData)
|
||||
{
|
||||
OSStatus status;
|
||||
AudioBufferList bufferList;
|
||||
void *tempBuffer = NULL;
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)inRefCon;
|
||||
/* Calculate required buffer size */
|
||||
size_t bufferSize = inNumberFrames * microphone->format.mBytesPerFrame;
|
||||
if (bufferSize == 0)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Invalid buffer size calculation.\n");
|
||||
return kAudio_ParamError;
|
||||
}
|
||||
|
||||
/* Allocate temporary buffer */
|
||||
tempBuffer = malloc(bufferSize);
|
||||
if (!tempBuffer)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to allocate temporary buffer.\n");
|
||||
return kAudio_MemFullError;
|
||||
}
|
||||
|
||||
/* Set up buffer list */
|
||||
bufferList.mNumberBuffers = 1;
|
||||
bufferList.mBuffers[0].mDataByteSize = (UInt32)bufferSize;
|
||||
bufferList.mBuffers[0].mData = tempBuffer;
|
||||
|
||||
/* Render audio data */
|
||||
status = AudioUnitRender(microphone->audio_unit,
|
||||
ioActionFlags,
|
||||
inTimeStamp,
|
||||
inBusNumber,
|
||||
inNumberFrames,
|
||||
&bufferList);
|
||||
|
||||
/* Write to FIFO buffer */
|
||||
if (status == noErr)
|
||||
fifo_write(microphone->sample_buffer,
|
||||
bufferList.mBuffers[0].mData,
|
||||
bufferList.mBuffers[0].mDataByteSize);
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to render audio: %d.\n", status);
|
||||
}
|
||||
|
||||
/* Clean up temporary buffer */
|
||||
free(tempBuffer);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Initialize CoreAudio microphone driver */
|
||||
static void *coreaudio_microphone_init(void)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)calloc(1, sizeof(*microphone));
|
||||
if (!microphone)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to allocate microphone driver.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Default sample rate will be set during open_mic */
|
||||
microphone->sample_rate = 0;
|
||||
microphone->nonblock = false;
|
||||
microphone->use_float = false;
|
||||
|
||||
return microphone;
|
||||
}
|
||||
|
||||
/* Free CoreAudio microphone driver */
|
||||
static void coreaudio_microphone_free(void *driver_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)driver_context;
|
||||
if (microphone)
|
||||
{
|
||||
if (microphone->audio_unit && microphone->is_running)
|
||||
{
|
||||
AudioOutputUnitStop(microphone->audio_unit);
|
||||
microphone->is_running = false;
|
||||
}
|
||||
|
||||
/* TODO: This crashes, though we protect calls around `audio_unit` nil! */
|
||||
#if 0
|
||||
if (microphone->audio_unit)
|
||||
{
|
||||
AudioComponentInstanceDispose(microphone->audio_unit);
|
||||
microphone->audio_unit = nil;
|
||||
}
|
||||
#endif
|
||||
if (microphone->sample_buffer)
|
||||
fifo_free(microphone->sample_buffer);
|
||||
free(microphone);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read samples from microphone */
|
||||
static int coreaudio_microphone_read(void *driver_context,
|
||||
void *microphone_context, void *buf, size_t size)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)driver_context;
|
||||
size_t avail, read_amt;
|
||||
|
||||
if (!microphone || !buf)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Invalid parameters in read.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
avail = FIFO_READ_AVAIL(microphone->sample_buffer);
|
||||
read_amt = MIN(avail, size);
|
||||
|
||||
if (microphone->nonblock && read_amt == 0)
|
||||
return 0; /* Return immediately in non-blocking mode */
|
||||
|
||||
if (read_amt > 0)
|
||||
{
|
||||
fifo_read(microphone->sample_buffer, buf, read_amt);
|
||||
#if DEBUG
|
||||
RARCH_LOG("[CoreAudio] Read %zu bytes from microphone.\n", read_amt);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (int)read_amt;
|
||||
}
|
||||
|
||||
/* Set non-blocking state */
|
||||
static void coreaudio_microphone_set_nonblock_state(void *driver_context, bool state)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)driver_context;
|
||||
if (microphone)
|
||||
microphone->nonblock = state;
|
||||
}
|
||||
|
||||
/* Helper method to set audio format */
|
||||
static void coreaudio_microphone_set_format(coreaudio_microphone_t *microphone, bool use_float)
|
||||
{
|
||||
microphone->use_float = use_float; /* Store the format choice */
|
||||
microphone->format.mSampleRate = microphone->sample_rate;
|
||||
microphone->format.mFormatID = kAudioFormatLinearPCM;
|
||||
microphone->format.mFormatFlags = use_float
|
||||
? (kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked)
|
||||
: (kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
|
||||
microphone->format.mFramesPerPacket = 1;
|
||||
microphone->format.mChannelsPerFrame = 1;
|
||||
microphone->format.mBitsPerChannel = use_float ? 32 : 16;
|
||||
microphone->format.mBytesPerFrame = microphone->format.mChannelsPerFrame * microphone->format.mBitsPerChannel / 8;
|
||||
microphone->format.mBytesPerPacket = microphone->format.mBytesPerFrame * microphone->format.mFramesPerPacket;
|
||||
|
||||
RARCH_LOG("[CoreAudio] Format setup: sample_rate=%d, bits=%d, bytes_per_frame=%d.\n",
|
||||
(int)microphone->format.mSampleRate,
|
||||
microphone->format.mBitsPerChannel,
|
||||
microphone->format.mBytesPerFrame);
|
||||
}
|
||||
|
||||
/* Open microphone device */
|
||||
static void *coreaudio_microphone_open_mic(void *driver_context,
|
||||
const char *device,
|
||||
unsigned rate,
|
||||
unsigned latency,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)driver_context;
|
||||
if (!microphone)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Invalid driver context.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize handle fields */
|
||||
microphone->sample_rate = rate;
|
||||
microphone->use_float = false; /* Default to integer format */
|
||||
|
||||
/* Validate requested sample rate */
|
||||
if (rate != 44100 && rate != 48000)
|
||||
{
|
||||
RARCH_WARN("[CoreAudio] Requested sample rate %u not supported, defaulting to 48000.\n", rate);
|
||||
rate = 48000;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
/* Configure audio session */
|
||||
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
||||
NSError *error = nil;
|
||||
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
|
||||
if (error)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to set audio session category: %s.\n", [[error localizedDescription] UTF8String]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*/ Set preferred sample rate */
|
||||
[audioSession setPreferredSampleRate:rate error:&error];
|
||||
if (error)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to set preferred sample rate: %s.\n", [[error localizedDescription] UTF8String]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get actual sample rate */
|
||||
Float64 actualRate = [audioSession sampleRate];
|
||||
if (new_rate)
|
||||
*new_rate = (unsigned)actualRate;
|
||||
microphone->sample_rate = (int)actualRate;
|
||||
|
||||
RARCH_LOG("[CoreAudio] Using sample rate: %d Hz.\n", microphone->sample_rate);
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
/* Set format using helper method */
|
||||
coreaudio_microphone_set_format(microphone, false); /* Default to 16-bit integer */
|
||||
|
||||
/* Calculate FIFO buffer size */
|
||||
size_t fifoBufferSize = (latency * microphone->sample_rate * microphone->format.mBytesPerFrame) / 1000;
|
||||
if (fifoBufferSize == 0)
|
||||
{
|
||||
RARCH_WARN("[CoreAudio] Calculated FIFO buffer size is 0 for latency: %u, sample_rate: %d, bytes_per_frame: %d.\n",
|
||||
latency, microphone->sample_rate, microphone->format.mBytesPerFrame);
|
||||
fifoBufferSize = 1024; /* Default to a reasonable buffer size */
|
||||
}
|
||||
|
||||
RARCH_LOG("[CoreAudio] FIFO buffer size: %zu bytes.\n", fifoBufferSize);
|
||||
|
||||
/* Create sample buffer */
|
||||
microphone->sample_buffer = fifo_new(fifoBufferSize);
|
||||
if (!microphone->sample_buffer)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to create sample buffer.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize audio unit */
|
||||
AudioComponentDescription desc = {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
#if TARGET_OS_IPHONE
|
||||
.componentSubType = kAudioUnitSubType_RemoteIO,
|
||||
#else
|
||||
.componentSubType = kAudioUnitSubType_HALOutput,
|
||||
#endif
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
.componentFlags = 0,
|
||||
.componentFlagsMask = 0
|
||||
};
|
||||
|
||||
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
|
||||
OSStatus status = AudioComponentInstanceNew(comp, µphone->audio_unit);
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to create audio unit.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Enable input */
|
||||
UInt32 flag = 1;
|
||||
status = AudioUnitSetProperty(microphone->audio_unit,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Input,
|
||||
1, /* Input bus */
|
||||
&flag,
|
||||
sizeof(flag));
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to enable input.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set format using helper method */
|
||||
coreaudio_microphone_set_format(microphone, false); /* Default to 16-bit integer */
|
||||
status = AudioUnitSetProperty(microphone->audio_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
1, /* Input bus */
|
||||
µphone->format,
|
||||
sizeof(microphone->format));
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to set format: %d.\n", status);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set callback */
|
||||
AURenderCallbackStruct callback = { coreaudio_input_callback, microphone };
|
||||
status = AudioUnitSetProperty(microphone->audio_unit,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
1, /* Input bus */
|
||||
&callback,
|
||||
sizeof(callback));
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to set callback.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Initialize audio unit */
|
||||
status = AudioUnitInitialize(microphone->audio_unit);
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to initialize audio unit: %d.\n", status);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Start audio unit */
|
||||
status = AudioOutputUnitStart(microphone->audio_unit);
|
||||
if (status != noErr)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to start audio unit: %d.\n", status);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return microphone;
|
||||
|
||||
error:
|
||||
if (microphone)
|
||||
{
|
||||
if (microphone->audio_unit)
|
||||
{
|
||||
AudioComponentInstanceDispose(microphone->audio_unit);
|
||||
microphone->audio_unit = nil;
|
||||
}
|
||||
free(microphone);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Close microphone */
|
||||
static void coreaudio_microphone_close_mic(void *driver_context, void *microphone_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)microphone_context;
|
||||
if (microphone)
|
||||
{
|
||||
if (microphone->is_running)
|
||||
AudioOutputUnitStop(microphone->audio_unit);
|
||||
|
||||
if (microphone->audio_unit)
|
||||
{
|
||||
AudioComponentInstanceDispose(microphone->audio_unit);
|
||||
microphone->audio_unit = nil;
|
||||
}
|
||||
if (microphone->sample_buffer)
|
||||
fifo_free(microphone->sample_buffer);
|
||||
free(microphone);
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to close microphone.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Start microphone */
|
||||
static bool coreaudio_microphone_start_mic(void *driver_context, void *microphone_context)
|
||||
{
|
||||
RARCH_LOG("[CoreAudio] Starting microphone.\n");
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)microphone_context;
|
||||
if (!microphone)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to start microphone.\n");
|
||||
return false;
|
||||
}
|
||||
RARCH_LOG("[CoreAudio] Starting audio unit...\n");
|
||||
|
||||
OSStatus status = AudioOutputUnitStart(microphone->audio_unit);
|
||||
if (status == noErr)
|
||||
{
|
||||
RARCH_LOG("[CoreAudio] Audio unit started successfully.\n");
|
||||
microphone->is_running = true;
|
||||
return true;
|
||||
}
|
||||
RARCH_ERR("[CoreAudio] Failed to start microphone: %d.\n", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Stop microphone */
|
||||
static bool coreaudio_microphone_stop_mic(void *driver_context, void *microphone_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)microphone_context;
|
||||
if (!microphone)
|
||||
{
|
||||
RARCH_ERR("[CoreAudio] Failed to stop microphone.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (microphone->is_running)
|
||||
{
|
||||
OSStatus status = AudioOutputUnitStop(microphone->audio_unit);
|
||||
if (status == noErr)
|
||||
{
|
||||
microphone->is_running = false;
|
||||
return true;
|
||||
}
|
||||
RARCH_ERR("[CoreAudio] Failed to stop microphone: %d.\n", status);
|
||||
}
|
||||
return true; /* Already stopped */
|
||||
}
|
||||
|
||||
/* Check if microphone is alive */
|
||||
static bool coreaudio_microphone_mic_alive(const void *driver_context, const void *microphone_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)microphone_context;
|
||||
return microphone && microphone->is_running;
|
||||
}
|
||||
|
||||
/* Check if microphone uses float samples */
|
||||
static bool coreaudio_microphone_mic_use_float(const void *driver_context, const void *microphone_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t*)microphone_context;
|
||||
return microphone && microphone->use_float;
|
||||
}
|
||||
|
||||
/* Get device list (not implemented for CoreAudio) */
|
||||
static struct string_list *coreaudio_microphone_device_list_new(const void *driver_context)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free device list (not implemented for CoreAudio) */
|
||||
static void coreaudio_microphone_device_list_free(const void *driver_context, struct string_list *devices)
|
||||
{
|
||||
}
|
||||
|
||||
/* Check if microphone is using float format */
|
||||
static bool coreaudio_microphone_use_float(const void *driver_context, const void *microphone_context)
|
||||
{
|
||||
coreaudio_microphone_t *microphone = (coreaudio_microphone_t *)microphone_context;
|
||||
if (!microphone)
|
||||
return false;
|
||||
|
||||
return microphone->use_float;
|
||||
}
|
||||
|
||||
/* CoreAudio microphone driver structure */
|
||||
microphone_driver_t microphone_coreaudio = {
|
||||
coreaudio_microphone_init,
|
||||
coreaudio_microphone_free,
|
||||
coreaudio_microphone_read,
|
||||
coreaudio_microphone_set_nonblock_state,
|
||||
"coreaudio",
|
||||
coreaudio_microphone_device_list_new,
|
||||
coreaudio_microphone_device_list_free,
|
||||
coreaudio_microphone_open_mic,
|
||||
coreaudio_microphone_close_mic,
|
||||
coreaudio_microphone_mic_alive,
|
||||
coreaudio_microphone_start_mic,
|
||||
coreaudio_microphone_stop_mic,
|
||||
coreaudio_microphone_mic_use_float
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue