Squashed 'deps/SPIRV-Cross/' changes from 8aa6731925..2820ab0b51

2820ab0b51 Merge pull request #1076 from KhronosGroup/bitcast-pre-330-glsl
63bcbd511e GLSL: Need extension to use bitcast on GLSL < 330.
9f3bebe3d0 Merge pull request #1075 from lifpan/master
b11c20fc1d Remove unreasonable assertion for OpTypeImage Sampled parameter.
1a592b7c0f Merge pull request #1067 from cdavis5e/msl-scalar-block-layout
28454facbb MSL: Handle packed matrices.
ea5c0ed82f MSL: Fix alignment of packed types.
44f688bf0b Merge pull request #1070 from KhronosGroup/fix-1066
25c74b324e Forget loop variable enables after emitting block chain.
6b010e0cbc Merge pull request #1069 from KhronosGroup/fix-1053
f6f849397e MSL: Re-roll array expressions in initializers.
e5fa7edfd6 MSL: Support scalar block layout.

git-subtree-dir: deps/SPIRV-Cross
git-subtree-split: 2820ab0b51bf5e4187435d904b34e762b988f48b
This commit is contained in:
twinaphex 2019-07-11 20:37:45 +02:00
parent 695837ef77
commit 420b7913d4
8261 changed files with 1353 additions and 2073539 deletions

View File

@ -1,20 +0,0 @@
# EditorConfig: http://EditorConfig.org
# Top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
# 3 space indentation
[*.{c,h,js,css,html}]
indent_style = space
indent_size = 3
# Tab indentation
[Makefile*]
indent_style = tab

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: libretro
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with a single custom sponsorship URL

View File

@ -1,35 +0,0 @@
# 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]

View File

@ -1,21 +0,0 @@
## Guidelines
1. Rebase before opening a pull request
2. If you are sending several unrelated fixes or features, use a branch and a separate pull request for each
3. If possible try squashing everything in a single commit. This is particularly beneficial in the case of feature merges since it allows easy bisecting when a problem arises
## Description
[Description of the pull request, detail any issues you are fixing or any features you are implementing]
## Related Issues
[Any issues this pull request may be addressing]
## Related Pull Requests
[Any other PRs from related repositories that might be needed for this pull request to work]
## Reviewers
[If possible @mention all the people that should review your pull request]

197
.gitignore vendored
View File

@ -1,187 +1,20 @@
*.o
*.bmpobj
*.binobj
*.so
*.dll
*.a
*.elf
*.dol
*.map
*.swp
.tmp
.tmp.c
.tmp.cxx
.moc.h
.moc.cpp
config.log
/.project
/.externalToolBuilders/
/retroarch
/retroarch.cfg
/retroarch.exe
/retroarch_debug.exe
/config.h
/config.mk
/tools/retroarch-joyconfig
/tools/retroarch-joyconfig.exe
*.ncb
*.d
*.txt
/test
/spirv-cross
/obj
/msvc/x64
/msvc/Debug
/msvc/Release
*.suo
*.sdf
*.opensdf
*.suo
Debug
Release
ipch
*.user
/bootstrap/gx/wii/app_booter/app_booter.bin
*.zip
RetroArch-w32/
RetroArch-w64/
.DS_Store
*/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.hmap
apple/tmp
apple/*.mobileprovision
apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
/Cg/
/GL/
/SDL/
/ffmpeg/
/freetype2/
/ft2build.h
/iconv.h
/phoenix/
/python/
/rsound.h
.pc
/media/shaders_glsl/
/obj-w32/
.cproject
.settings
libretro-super
run.sh
convert_rumble.awk
*~
assets
info
content_image_history.lpl
saves
screenshots
# Wii U
*.depend
*.rpx
*.last
wiiu/wut/elf2rpl/elf2rpl
/pkg/wiiu/retroarch
/pkg/wiiu/wiiu
/pkg/wiiu/rpx
/wiiu-devel.properties
# 3ds
/.lst
*.3dsx
*.cia
*.3ds
*.bnr
*.smdh
/retroarch_3ds.core
/retroarch_3ds.icn
/retroarch_3ds_salamander.icn
# Ctags
/tags
# CLion
/cmake-build-debug/
# Android
/pkg/android/phoenix/obj/
/pkg/android/phoenix/assets/
/pkg/android/phoenix/libs/
/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
# Cloned by libretro-fetch.sh
/media/assets/
/media/autoconfig/
/media/overlays/
/media/shaders_cg/
/media/libretrodb/
pkg/apple/iOS/build/
pkg/apple/build/
ui/drivers/qt/moc_*
ui/drivers/moc_*
obj-unix/
.vagrant/
/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
/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
# Emscripten artifacts
retroarch.js
retroarch.js.mem
*.shader
*.a
*.bc
*.wasm
/external
.vs/
*.vcxproj.user
# only ignore .js files in the repo root
/*.js
# Switch
*.d
exefs/*
retroarch_switch.pfs0
retroarch_switch.lst
retroarch_switch.nacp
retroarch_switch.nro
retroarch_switch.nso
# PS2
ps2/irx/*.c
ps2/libcdvd/lib/
# Wayland
gfx/common/wayland/idle-inhibit-unstable-v1.c
gfx/common/wayland/idle-inhibit-unstable-v1.h
gfx/common/wayland/xdg-shell-unstable-v6.c
gfx/common/wayland/xdg-shell-unstable-v6.h
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
!CMakeLists.txt

View File

@ -1,8 +0,0 @@
before_script:
- apt-get update -qq && apt-get install -y -qq git build-essential
- apt-get update -qq && apt-get build-dep -y retroarch
build:
script:
- ./configure
- make -j2

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RetroArch_</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -1,128 +1,72 @@
# Use 'generic' to be able to override CC/CXX for clang
language: generic
language:
- cpp
- python
# Use a release with a longer normal LTS
dist: xenial
python: 3.7
matrix:
include:
- compiler: mingw-x86
addons: true
env: CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: mingw-x86
addons: true
env: C89_BUILD=1 CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: mingw-x86
addons: true
env: CXX_BUILD=1 CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: mingw-x64
addons: true
env: CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: mingw-x64
addons: true
env: C89_BUILD=1 CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: mingw-x64
addons: true
env: CXX_BUILD=1 CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
- compiler: gcc
env: CC=gcc-8 CXX=g++-8
- compiler: gcc
env: C89_BUILD=1 CC=gcc-8 CXX=g++-8
- compiler: gcc
env: CXX_BUILD=1 CC=gcc-8 CXX=g++-8
- compiler: gcc
env: DISABLE_MENU=1 CC=gcc-8 CXX=g++-8
- compiler: gcc
env: ENABLE_GLES=1 CC=gcc-8 CXX=g++-8
- compiler: gcc
env: ENABLE_GLES=1 ENABLE_GLES3=1 CC=gcc-8 CXX=g++-8
- compiler: clang
env: CC=clang-6.0 CXX=clang++-6.0
- compiler: clang
env: C89_BUILD=1 CC=clang-6.0 CXX=clang++-6.0
- compiler: clang
env: CXX_BUILD=1 CC=clang-6.0 CXX=clang++-6.0
- os: linux
dist: trusty
compiler: gcc
env:
- GENERATOR="Unix Makefiles"
- ARTIFACT=gcc-trusty-64bit
- os: linux
dist: trusty
compiler: clang
env:
- GENERATOR="Unix Makefiles"
- ARTIFACT=clang-trusty-64bit
- os: osx
env: CC=clang CXX=clang++
- os: osx
osx_image: xcode8
script:
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
- os: osx
osx_image: xcode10.1
script:
- brew install --force-bottle qt5
- xcodebuild -target RetroArchQt -configuration Release -project pkg/apple/RetroArch_Metal.xcodeproj
deploy:
skip_cleanup: true
provider: script
script: bash travis_metal_deploy.sh
on:
branch: master
compiler: clang
osx_image: xcode10
env:
- GENERATOR="Unix Makefiles"
- ARTIFACT=clang-macos-64bit
- os: windows
before_install:
- choco install python3
- export PATH="/c/Python37:/c/Python37/Scripts:$PATH"
env:
- GENERATOR="Visual Studio 15 2017"
- ARTIFACT=vs2017-32bit
- os: windows
before_install:
- choco install python3
- export PATH="/c/Python37:/c/Python37/Scripts:$PATH"
env:
- GENERATOR="Visual Studio 15 2017 Win64"
- ARTIFACT=vs2017-64bit
before_install:
- |
if [ "$CC" = gcc-8 ]; then
# Install a more recent gcc than the default
sudo apt-get install -y g++-8
elif [ "$CC" = clang-6.0 ]; then
# Install a more recent clang than the default
sudo apt-get install -y clang-6.0
elif [ "$CROSS_COMPILE" = i686-w64-mingw32- ]; then
sudo update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
elif [ "$CROSS_COMPILE" = x86_64-w64-mingw32- ]; then
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
fi
before_script:
- "./checkout_glslang_spirv_tools.sh"
script:
- |
if [ -n "$CROSS_COMPILE" ]; then
ARGS="$ARGS --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12"
fi
- |
if [ -n "$DISABLE_MENU" ]; then
ARGS="$ARGS --disable-menu"
fi
- |
if [ -n "$ENABLE_GLES" ]; then
ARGS="$ARGS --enable-opengles"
fi
- |
if [ -n "$ENABLE_GLES3" ]; then
ARGS="$ARGS --enable-opengles3"
fi
- ./configure $ARGS
- |
if [ -n "$C89_BUILD" ]; then
make C89_BUILD=1
elif [ -n "$CXX_BUILD" ]; then
make CXX_BUILD=1
else
make
fi
- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then PYTHON3=$(which python); fi
- if [[ "$TRAVIS_OS_NAME" != "windows" ]]; then PYTHON3=$(which python3); fi
- "./build_glslang_spirv_tools.sh Release"
- mkdir build
- cd build
- cmake .. -DSPIRV_CROSS_SHARED=ON -DCMAKE_INSTALL_PREFIX=output -DCMAKE_BUILD_TYPE=Release -G "${GENERATOR}" -DPYTHON_EXECUTABLE:FILEPATH="${PYTHON3}" -DSPIRV_CROSS_ENABLE_TESTS=ON
- cmake --build . --config Release
- cmake --build . --config Release --target install
- ctest --verbose -C Release
- cd ..
env:
global:
- ARGS=""
- MAKEFLAGS="-j2"
- secure: "qc91ReC3OlzSh2gFaSH6TYzC2qIQvgA2AZff6J13eaH8xijAhuMzttZ0rMQJ0DWCIhPeUb0kIzVyaGoe4MwPALzpw1C1AznIWiZJ53HN+hWCOcS/af7YVPk6HPySnwqrS+Wv3AIIvIKFV2mxv21F/JbT/N+pArlRrp904Xj+KPo="
addons:
apt:
packages:
- libsdl2-dev
- libusb-1.0-0-dev
- qtbase5-dev
- qtdeclarative5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial
coverity_scan:
project:
name: "RetroArch"
description: "RetroArch is the official reference frontend for the libretro API."
notification_email: libretro@gmail.com
build_command_prepend: "./configure; make clean"
build_command: "make"
branch_pattern: coverity_scan
notifications:
email: false
before_deploy:
- REV=${ARTIFACT}-$(git rev-parse --short=10 HEAD)
- cd build/output
- tar cf spirv-cross-${REV}.tar *
- gzip spirv-cross-${REV}.tar
- cd ../..
- export FILE_TO_UPLOAD=build/output/spirv-cross-${REV}.tar.gz
deploy:
provider: releases
api_key:
secure: c7YEOyzhE19TFo76UnbLWk/kikRQxsHsOxzkOqN6Q2aL8joNRw5kmcG84rGd+Rf6isX62cykCzA6qHkyJCv9QTIzcyXnLju17rLvgib7cXDcseaq8x4mFvet2yUxCglthDpFY2M2LB0Aqws71lPeYIrKXa6hCFEh8jO3AWxnaor7O3RYfNZylM9d33HgH6KLT3sDx/cukwBstmKeg7EG9OUnrSvairkPW0W2+jlq3SXPlq/WeVhf8hQs3Yg0BluExGbmLOwe9EaeUpeGuJMyHRxXypnToQv1/KwoScKpap5tYxdNWiwRGZ4lYcmKrjAYVvilTioh654oX5LQpn34mE/oe8Ko9AaATkSaoiisRFp6meWtnB39oFBoL5Yn15DqLQpRXPr1AJsnBXSGAac3aDBO1j4MIqTHmYlYlfRw3n2ZsBaFaTZnv++438SNQ54nkivyoDTIWjoOmYa9+K4mQc3415RDdQmjZTJM+lu+GAlMmNBTVbfNvrbU55Usu9Lo6BZJKKdUMvdBB78kJ5FHvcBlL+eMgmk1pABQY0IZROCt7NztHcv1UmAxoWNxveSFs5glydPNNjNS8bogc4dzBGYG0KMmILbBHihVbY2toA1M9CMdDHdp+LucfDMmzECmYSEmlx0h8win+Jjb74/qpOhaXuUZ0NnzVgCOyeUYuMQ=
file: "${FILE_TO_UPLOAD}"
skip_cleanup: true
on:
tags: true

View File

@ -1,155 +0,0 @@
{
"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"
},
{
"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"
}
],
"version": 4
}

45
.vscode/launch.json vendored
View File

@ -1,45 +0,0 @@
{
// 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
}
]
},
]
}

72
.vscode/settings.json vendored
View File

@ -1,72 +0,0 @@
{
"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,
"files.associations": {
"frontend_driver.h": "c",
"*.in": "c",
"*.rh": "c",
"array": "c",
"file_stream.h": "c",
"driver.h": "c",
"iosfwd": "c",
"xlocbuf": "c",
"xmemory0": "c",
"ios": "c",
"list": "c",
"input_driver.h": "c",
"menu_driver.h": "c",
"file_path.h": "c",
"unordered_map": "c",
"unordered_set": "c",
"sstream": "cpp",
"hash_map": "c",
"hash_set": "c",
"initializer_list": "c",
"string_view": "c",
"utility": "c",
"menu_input.h": "c",
"tasks_internal.h": "c",
"ozone.h": "c",
"ozone_theme.h": "c",
"ozone_texture.h": "c",
"string_list.h": "c",
"core_info.h": "c",
"thread": "c",
"xlocale": "c",
"menu_widgets.h": "c",
"message_queue.h": "c",
"task_queue.h": "c",
"fifo_queue.h": "c",
"file_list.h": "c",
"strl.h": "c",
"configuration.h": "c",
"ozone_display.h": "c",
"verbosity.h": "c",
"retroarch.h": "c",
"menu_animation.h": "c",
"netplay.h": "c",
"scaler.h": "c",
"deque": "c",
"vector": "c",
"xhash": "c",
"xiosbase": "c",
"xstring": "c",
"xtree": "c",
"xutility": "c",
"menu_input_dialog.h": "c",
"menu_filebrowser.h": "c",
"ozone_sidebar.h": "c",
"menu_thumbnail_path.h": "c",
"badges.h": "c"
},
"C_Cpp.dimInactiveRegions": false,
}

128
.vscode/tasks.json vendored
View File

@ -1,128 +0,0 @@
{
// 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"
]
}
}
}
]
}

View File

@ -1,96 +0,0 @@
diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c
index b90a8e40c3..e57c4df194 100644
--- a/gfx/drivers_context/wgl_ctx.c
+++ b/gfx/drivers_context/wgl_ctx.c
@@ -78,6 +78,47 @@
#ifndef WGL_CONTEXT_DEBUG_BIT_ARB
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#endif
+
+#ifndef WGL_ACCELERATION_ARB
+#define WGL_ACCELERATION_ARB 0x2003
+#endif
+
+#ifndef WGL_FULL_ACCELERATION_ARB
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#endif
+
+#ifndef WGL_DRAW_TO_WINDOW_ARB
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#endif
+
+#ifndef WGL_DOUBLE_BUFFER_ARB
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#endif
+
+#ifndef WGL_RED_BITS_ARB
+#define WGL_RED_BITS_ARB 0x2015
+#endif
+
+#ifndef WGL_GREEN_BITS_ARB
+#define WGL_GREEN_BITS_ARB 0x2017
+#endif
+
+#ifndef WGL_BLUE_BITS_ARB
+#define WGL_BLUE_BITS_ARB 0x2019
+#endif
+
+#ifndef WGL_ALPHA_BITS_ARB
+#define WGL_ALPHA_BITS_ARB 0x201B
+#endif
+
+#ifndef WGL_PIXEL_TYPE_ARB
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#endif
+
+#ifndef WGL_TYPE_RGBA_ARB
+#define WGL_TYPE_RGBA_ARB 0x202B
+#endif
+
#endif
#if defined(HAVE_OPENGL)
@@ -313,6 +354,43 @@ static void create_gl_context(HWND hwnd, bool *quit)
RARCH_LOG("[WGL]: Adaptive VSync supported.\n");
wgl_adaptive_vsync = true;
}
+ if (wgl_has_extension("WGL_ARB_pixel_format", extensions))
+ {
+ BOOL (WINAPI * wglChoosePixelFormatARB)
+ (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats);
+ UINT nMatchingFormats;
+ int index = 0;
+ int attribsDesired[] = {
+ WGL_DRAW_TO_WINDOW_ARB, 1,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+ WGL_RED_BITS_ARB, 10,
+ WGL_GREEN_BITS_ARB, 10,
+ WGL_BLUE_BITS_ARB, 10,
+ WGL_ALPHA_BITS_ARB, 2,
+ WGL_DOUBLE_BUFFER_ARB, 1,
+ 0,0
+ };
+ wglChoosePixelFormatARB = (BOOL (WINAPI *) (HDC, const int *,
+ const FLOAT*, UINT, int*, UINT*))
+ gfx_ctx_wgl_get_proc_address("wglChoosePixelFormatARB");
+
+ RARCH_LOG("[WGL]: ARB pixel format supported.\n");
+
+ if (wglChoosePixelFormatARB(win32_hdc, attribsDesired,
+ NULL, 1, &index, &nMatchingFormats))
+ {
+ if (nMatchingFormats == 0)
+ {
+ RARCH_WARN("No 10bpc WGL_ARB_pixel_formats found!\n");
+ }
+ }
+ }
}
}
#endif

321
AUTHORS.h
View File

@ -1,321 +0,0 @@
static const char *retroarch_contributors_list = R"(
RetroArch and the libretro team would like to
acknowledge the following contributors:
1ch (L0sted)
Aaahh Ahh (Aaahh)
Aaron Oneal (aarononeal)
Adam Londero (alondero)
Adam Mechtley (amechtley)
AdrianoML
ajefr
Alberto Simon (asimonf)
Alcaro
Aleksey Samoilov (Sunderland93)
Alessandro Mangone (Vektor) (zevektor)
Alex Eckhart (alex34567)
Alex Folland (AlexFolland)
Alexander Spady (alkaseltzerspadt)
Alexandre Garcia (Alexandre-Garcia)
Alfredo Monclus (alfrix)
aliaspider
alphanu1
altiereslima
Alwin Garside (Yogarine)
Amiga1200Gamer (amigagamer)
Andre Leiradella (leiradel)
Andrés (fr500)
Anthony J. Bentley (bentley)
Antonio Jose Ramos Marquez (psxdev)
AridRayne
ArnaudFaucher
Arto Vainiolehto (arakerlu)
Ash (QuarkTheAwesome)
Ashura (CoalaJoe)
Autechre64
Avton1
ayssia
barbudreadmon
bearoso
benutzer193
blackgur
Boris Timofeev (btimofeev)
bparker06
Brandon Johnson (Denu8thell)
Brian Koropoff (bkoropoff)
Brian S. Stephan (bsstephan)
Brunnis
bubuleur
Casey Borders (CaseyB)
ceb33
celerizer
Chris Merrett (chrisfu)
Christian Murphy (grimpunch)
chu (9chu)
CidVonHighwind
clienthax
cold-brewed
CompCom
Conn O'Griofa (psyke83)
CozmoP
cpsw
Cray Elliott (MP2E)
Cristian Sandu (crazyquark)
ctult
cucholix
cudencuden
cxd4
dalter
Dan Weiss (Dwedit)
danieljg
Daniil Zhilin (LaserMoai)
dankcushions
Dave (freakdave)
Dave Leaver (danzel)
David Demelier (markand)
David Erickson (daviderickson)
David Shah (daveshah1)
David Walters (hiddenasbestos)
DEX357
diablodiab
dibas
Diego A. (SuperrSonic)
Diego Viola (diegoviola)
Diogo Barros (BlueKore)
DogParty
dor3k
driver1998
Dudu Akiva (duduke)
duganchen
dukemiller
duskgao
ekipan
Emmanuel Martin (daliaetnano)
endrift
erbridge
esoptron
Ethan Lee (flibitijibibo)
Exvat
Ezio-PS
Fabio (Oibaf66)
Fabio Ritrovato (Sephiroth87)
Fayne Aldan (FayneAldan)
FIX94
Flame Sage (chris062689)
flyinghead
Francisco Javier Trujillo Mata (fjtrujy)
Francisco José García García (frangarcj)
Gabriel (Ghabry)
GameDragon2k
Garrett Brown (garbear)
gblues
Geoffrey Plitt (GeoffreyPlitt)
Glenn Hevey (hevey)
Googer
gouchi
grant2258
Gregor Richards (GregorR)
Gui Andrade (archshift)
Gustavo Maciel Dias Vieira (gmdvieira)
gvbr
H. İbrahim Güngör (igungor)
hadess
Hans-Kristian Arntzen (Themaister)
Henri Gomez (hgomez)
Henri Gomez (hgomez-sonarsource)
Higor Eurípedes (heuripedes)
Hisman Yosika (dnjstlr555)
hizzlekizzle
Hugo B. (hug0b)
Hugo Hromic (hhromic)
hunterk
hyarsan
Hyllian
i30817
iAmGhost
Jack (jakcron)
Jacob (cubtekki)
James Le Cuirot (chewi)
James Sexton (Bezier89)
Jamiras
Jan Holthuis (Holzhaus)
Jay McCarthy (jeapostrophe)
jdgleaver
Jean-André Santoni (kivutar)
Jean-Paul Mari (djipi)
Jean-Sébastien Guay (Skylark13)
Jesse Bryan (winneon)
Joel (joel16)
Joerg Sonnenberger (jsonn)
Johannes Schickel (lordhoto)
John Regan (jprjr)
Jon Maddox (maddox)
Jonathan Relf (jonathanrelf)
Joohan Lee (losernator)
Jools Wills (joolswills)
Jose Lage Miguez (Joselagem)
Joseph Carter (iKarith)
Joseph Conan Montgomery (Grotke)
Josh Palmer (ShiftyAxel)
JuanVCS
Justin Jacobs (dorkster)
Justin Weiss (justinweiss)
Ken Rossato (rossato)
krzys_h (krzys-h)
kurumushi
kwyxz
l3iggs
lambolighting
lasers
Lawrence Kesteloot (lkesteloot)
lifajucejo
liffy (lifning)
Lionel Flandrin (simias)
littleguy77
Logan (loganmc10)
lordashram
Lothar Serra Mari (lotharsm)
Lubosz Sarnecki (lubosz)
lucianposton
lxerandrew
m4xw
Mahyar Koshkouei (deltabeard)
Manuel Alfayate Corchete (vanfanel)
Marcelo Munhoz Pélos (mpelos)
markwkidd
Maschell
Mat M. (lioncash)
Mats A. (Datamats)
Matt Sephton (gingerbeardman)
Matthew Wang (asakous)
Max K. (langerhans)
Maxime Gauduin (alucryd)
mcrisostomo
meancoot
meepingsnesroms
meleu
Michael K. (kuxii2016)
Michael Lelli (ToadKing)
Michał Durak (micechal)
mickski56
Mico Chopitea (micochops)
miguelpinheiro
Mike Swanson (chungy)
miqlas (extrowerk)
misson20000
Monroe88
mprobinson
MrHuu
MrJs (mrjschulte)
muzuiget
mwtremblay
myfreeweb
Nathan S. (natinusala)
NathanStrong-Tripwire
nattycleopatra
nayslayer
netux79
nfnty
nia (ensra)
Nicolas Adenis-Lamarre (nadenislamarre)
Nicolas Guillaumin (nguillaumin)
Nicolas Lopez Fernandez (pyroesp)
Nikita Vakhrushev (SwooodGa)
Nikola Kocić (nikola-kocic)
Niouby
nosh01
not6 (r-type)
notaz
nstCactus
nurupo
Oggom
Oleg Shevchenko (olsh)
opendata26
orbea
OV2
pamapa
Paolo Bonzini (bonzini)
Paul McCarty (notabeatle)
Pedro Ribeiro (pedrib)
pinumbernumber
pponso1
Ramiro Morales (ramiro)
Raphaël Zumer (rzumer)
retro-wertz
retrotails
reztek
Richard Howell (rmaz)
rlnilsen
Rob Loach (RobLoach)
Romain Gay (vikbez)
Romain Graillot (notnotme)
Romain TISSERAND (rtissera)
Roman Kalashnikov (lunixoid)
Royerson
rrooij
rsn8887
Ryunam
rz5
Saggi Mizrahi (ficoos)
SAKUJ0
Sam Pagenkopf (44100hertz)
Sam Stenvall (Jalle19)
Samuel P. (p-sam)
Scheiker
Sebastien Ronsse (sronsse)
Sergi Granell (xerpi)
Sergio Padrino (sergiou87)
sergio-br2 (sergiobenrocha2)
Seth Kingsley (sethk)
Shane Mouton (ismouton)
Shizeeg Unadequatov (shizeeg)
slotek
sparklewind
spec-chum
Stefan (gizmo98)
stefan-gr
stellarporter
Steven M. Vascellaro (stevoisiak)
Stuart Carnie (stuartcarnie)
Sunguk Lee (d3m3vilurr)
Supernature2k
Sven (RetroSven)
Swingflip
Swizzy
Sylvain Colinet (Skarsnik)
Tatsuya79
Terry Lewis (terry-au)
thedax
theheroGAC
TheMrIron2
TheOfficialFloW
thiolliere
Thomas Lorblanchès (Zlika)
Tobias Jakobi (tobiasjakobi)
Tomáš Kelemen (ToKe79)
Torsten Paul (t-paul)
TotalCaesar659
TroggleMonkey
Twinaphex
URBANsUNITED
vgmoose
Vicky C Lau (vickychenglau)
Vladimir Panteleev (CyberShadow)
Vladimir Serbinenko (phcoder)
Víctor "IlDucci" (IlDucci)
waitingmoon
Wang Vincent (susemm)
webgeek1234
Weedy Weed Smoker (WeedyWeedSmoker)
WerWolv
Wiimpathy
Wiktor Strzębała (wiktorek140)
xhp-creations
yesfish (huwpascoe)
Yongwoon Cho (ssangkong)
yoshisuga
zeromus
zlice
Zoran Vuckovic (casdevel)
Ömercan Kömür (fpscan)
)";

View File

@ -1,758 +0,0 @@
# 1.7.8 (future)
- BLISS-BOX: Add 4 new pad types from firmware 3.0.
- COMMON: Add optional 'on demand' thumbnail downloads.
- COMMON: Add new playlist-based thumbnail downloader. Hide the legacy thumbnail pack version by default.
- COMMON: Show license per core (if available) inside 'Load Core'.
- GAMECUBE: Add default video/audio filter directories.
- GL1: Ignore alpha in core video, fixes XRGB8888 rendering in some cores.
- GLCORE: Don't hardcode shader cross compilation target version but poll it. glcore would always only use the minimum target shader version, i.e. GLSL ES 3.00 for OpenGL ES 3.0+ or GLSL 1.50 for OpenGL 3.2+.
- D3D10/11/12/SLANG: Added "FrameDirection" slang semantic. Works fine with braid-rewind shader, not entirely perfect with D3D12 though.
- D3D10/11/12: Add option to select which GPU to render with.
- GLCORE/SLANG: Added "FrameDirection" slang semantic.
- INPUT: Menu toggle hotkey can now be bound to another keyboard key and it will toggle properly.
- IOS: Correctly centers screen on iPhone X landscape.
- LOCALIZATION: Update Korean translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Portuguese Brazilian Translation.
- LOCALIZATION: Update Polish translation.
- MENU/WIDGETS: All widgets are now properly cleaned up, fixing the frozen widgets bug when loading / closing content.
- MENU/WIDGETS: Widgets are now drawn above the overlay with OpenGL and Vulkan.
- MENU/WIDGETS: Fine tune progress bar colors.
- MENU: Fix longstanding menu display issues on Mali400 GPUs (on ARM hardware, SBCs and mobile phones/tablets).
- MENU/THUMBNAILS: Ensure that displayed thumbnails are always refreshed correctly after selecting 'Download Thumbnails' from Quick Menu.
- MENU/OZONE: Add it for PS3
- MENU/OZONE: Fix regression in 1.7.7 - OSX/macOS - was unable to start it.
- MENU/XMB: Add menu animation settings.
- MENU: Fix Record -> Streaming Quality, and Record -> Recording Threads settings.
- MENU/QT/WIMP: Path selector fixes.
- METAL/SLANG: Added "FrameDirection" slang semantic.
- NETBSD: Audioio is now the default audio driver.
- NETBSD: Fix a segfault when starting RetroArch with an empty configuration file and LANG unset in the environment.
- OSD: OSD is now drawn above the overlay with Vulkan.
- OSX: Fix regression with Cocoa GL - shader / preset loading was getting stuck in an infinite loop.
- RECORD: Fix Twitch streaming.
- SCALER: Fix SSE2 path for ARGB/BGRA -> BGR24 - should fix screenshots being taken for XRGB888 (viewport).
- SCANNER: Skip all databases with incompatible file extensions, whether content is inside an archive or not.
- VULKAN/SLANG: Added "FrameDirection" slang semantic.
- VULKAN: Add option to select which GPU to render with.
- WII: Add default video/audio filter directories.
- WII: Fix RGUI display corruption.
- WIIU/SLANG: Added "FrameDirection" slang semantic.
- X11: Add non-evdev keycodes to fix keyboard input on non-Linux systems with X11.
# 1.7.7
- 3DS: Add unique IDs to prevent cores overwriting each other.
- 3DS: Fix screen tearing when running 50Hz content.
- ANDROID: We now target API level 26 (minimum is still API level 9).
- ANDROID: Add option to vibrate on touch (works in menu or overlay).
- ANDROID: Add device vibration option for cores that support rumble.
- ANDROID: Add gamepad vibration support for cores that support rumble.
- ANDROID: Allow stylus/pen to move mouse without pressing down.
- AUDIO: Avoid deadlocks in certain audio drivers when toggling menu sounds on.
- BLISS-BOX: Support PSX Jogcon (requires firmware 3.0).
- CHEEVOS: Fix crash when reading memory that is out of range.
- CHEEVOS: New Cheevos implementation enabled by default.
- CHEEVOS: Pop-up badges when an achievement is triggered.
- CRT: Dynamic super resolution support.
- DISCORD: Fix potential crash when username is empty and discord is disabled.
- DISCORD: Ask to join support for Linux.
- INPUT/ANDROID: Add "Input Block Timeout" option.
- COMMON: For platforms without HAVE_THREADS, don't automatically resume content when saving/loading states
- COMMON: Make playlist sorting optional and consistent.
- COMMON: Fix sorting of playlists with blank labels.
- COMMON: Fix content scanner creating false positive playlist entries that also have wrong label and crc32.
- COMMON: Add some MMX-optimized pixel conversion routines.
- COMMON: Fix typo preventing some SSE2-optimized pixel conversions from being used.
- COMMON: Add option to track how long content has been running over time.
- COMMON: Fix buffer overflows in system information.
- COMMON: Add option to change screen orientation via the windowing system (Android, Windows, X11).
- COMMON: Show CPU model name in log.
- COMMON: Add "Help -> Send Debug Info" option (and F10 hotkey) to send diagnostic info to the RetroArch team for help with problems.
- COMMON: Show GPU device name/version in log.
- COMMON: Add menu option to write log info to a file.
- COMMON: Add subsystem support for playlists. Subsystem info is automatically saved to the history playlist for easy relaunching.
- GL: Add new "gl1" OpenGL 1.1 compliant video driver for legacy GPUs and software renderers
- GL: Add a new "glcore" driver with slang support (requires GL 3.2+ or GLES3).
- GL: Draw OSD on top of overlay.
- GONG: Add savestate support.
- GONG: Add video refresh rate core options.
- GONG: Two player support via core option.
- GUI: Fix text alignment when using stb_unicode.
- GUI: Fix text display issues when using Japanese (and other unicode-dependent language) text with stb_unicode.
- GUI: Set language on first startup to the user's preferred OS language (Windows, *nix and Android).
- INPUT: Add (scaled radial) analog deadzone and sensitivity options.
- LIBRETRO: Add Turkish language support.
- LIBRETRO: Allow non-accelerated video to rotate the display.
- LOCALIZATION: Update Chinese (Simplified) translation.
- LOCALIZATION: Update Chinese (Traditional) translation.
- LOCALIZATION: Update Dutch translation.
- LOCALIZATION: Update French translation.
- LOCALIZATION: Update German translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Polish translation.
- LOCALIZATION: Update Russian translation.
- LOCALIZATION: Update Spanish translation.
- LOCALIZATION: Add new Turkish translation.
- MIDI: Fix startup crash in midi driver.
- MENU: Bugfix - you can no longer get stuck in Online Updater -> Update Core screen when toggling between ingame and menu.
- MENU: Selectively hide 'Take Screenshot' for video drivers that don't support taking screenshots.
- MENU: Framerate independent menu rendering. MaterialUI/Ozone/XMB/RGUI can now run at higher framerates.
- MENU: Thumbnails work in history list.
- MENU: Menu widgets.
- MENU: Add memory statistics support to more context drivers.
- MENU: Enable ozone driver for UWP builds.
- MENU: Add optional "looping" menu text ticker with configurable speed.
- MENU: Fix core video rendering when using ozone with GL cores that implement the scissor test.
- MENU: Add optional playlist sublabels (associated core + play time, where available).
- MENU: Dropdown list settings now apply immediately.
- MENU: Add setting to require pressing the "Exit RetroArch" hotkey twice to confirm.
- MENU: Now able to run at higher refresh rates than 60Hz.
- MENU: Enable "Add to Favorites" without loading a core.
- MENU: Allow core name to be hidden on history/favorites playlists.
- MENU: Populate crc32 and db_name fields when adding history/favourites playlist entries.
- MENU: Fix TTF files not showing in OSD/menu font selection screen.
- MENU: Fix audio/video filters not showing in file browser.
- MENU/MaterialUI: Add subsystem support.
- MENU/MaterialUI: Add currently selected entry in dropdown menus.
- MENU/OZONE: Add mouse support on entries (no sidebar yet).
- MENU/OZONE: Allow collapsing the sidebar.
- MENU/OZONE: Add thumbnail support.
- MENU/OZONE: Battery notifications.
- MENU/OZONE: Add wifi icon for network entries.
- MENU/QT/WIMP: Add git version and build date to Help->About window.
- MENU/QT/WIMP: Fix content loading via the file browser.
- MENU/QT/WIMP: Add new settings window to control all RetroArch settings.
- MENU/RGUI: Improve playlist titles.
- MENU/RGUI: Add option to hide associated cores in playlists.
- MENU/RGUI: Add internal upscaling option.
- MENU/RGUI: Add subsystem support.
- MENU/RGUI: Add menu sublabel support.
- MENU/RGUI: Re-enable "Load Core" option when content is loaded.
- MENU/RGUI: Add optional "Collections" entry to main menu.
- MENU/RGUI: Add "Lock Menu Aspect Ratio" option.
- MENU/RGUI: Add "full width" layout option.
- MENU/RGUI: Ensure menu color theme is applied immediately.
- MENU/RGUI: Fix "Lock Menu Aspect Ratio" option when using custom viewports.
- MENU/RGUI: Add widescreen support.
- MENU/RGUI: Allow text to be centred when selecting widescreen layouts.
- MENU/RGUI: Add inline playlist thumbnail support.
- MENU/RGUI: Add optional shadow effects.
- MENU/RGUI: Performance optimizations.
- MENU/RGUI: Add optional extended ASCII support.
- MENU/RGUI: Add optional delay when loading thumbnails.
- MENU/RGUI: Add on-screen keyboard.
- MENU/RGUI: Battery notifications.
- MENU/XMB: Prevent crashes when resizing to a tiny window.
- MENU/XMB: XMB honors the 'show menu sublabels' setting now - was previously RGUI only
- NETPLAY: Fix stall-out causing total disconnection with >2 players.
- NETPLAY: Different (more intuitive?) default netplay share policy.
- NETPLAY: Add hotkey option to toggle hosting on/off.
- NETWORKING: Encode URLs to allow for spaces in directory names.
- OSX: Prevent crash on exit.
- OSX: Metal is now the default video driver for the RetroArch Metal build.
- OSX: Enable CoreAudio v3 driver for Metal.
- OSX/MACOS/IOS: Now uses the STB Unicode font driver.
- PS2: CDFS support.
- PS2: Implemented analog support for ps2 controllers.
- PS2: Fix audio freeze after restarting core.
- PS2: Fix issues with load state and the font driver.
- PS2: File I/O now works for USB and network host.
- PS2: Support cores with extra padding in their frame buffers.
- SCANNER: New option 'Scan without core match'. When this is enabled,
supported extensions by all installed cores are not checked, and instead
it will add all content it finds to a playlist. This way, you can install the core you need later on after scanning. Not enabled by default.
- SHADERS: Don't alphabetize shader presets.
- SWITCH: Add rumble support.
- SWITCH: Add USB keyboard support.
- VITA: Add bluetooth mouse and keyboard support.
- VULKAN: Fix color issues with RGBA8888 swapchains in readback (screenshots).
- WII: Don't init overlay when RAM is beyond 72MB.
- WII: Skip CRC calculation on content load, can improve load times of larger games by several seconds.
- WINDOWS: Fall back to gl1 driver if accelerated GPU driver is unavailable.
- WINDOWS: Allow winraw and xinput to work without dinput (needed for WinRT).
- WINDOWS: Add MSVC2017 ARM desktop support.
- UWP: Fix rewind by opting for slower codepath.
- UWP: Fix relative path name issues when loading shaders.
- UWP: Optimizations for VFS system.
# 1.7.6
- ANDROID: Fix Xperia Play input binding.
- CHEEVOS: Reset when hardcore mode is toggled.
- CHEEVOS: Update the hashing methods to identify NES, SNES and Lynx games (more accurate and accepting headerless ROMs).
- COMMON: Add new JSON playlist format.
- COMMON: Fix playlist corruption when deleting items.
- COMMON: Fix archive progress display calculation.
- COMMON: Fix playlist entries appearing with previously used names.
- COMMON: Fix screenshot filename with no core or content.
- COMMON: Allow compiling without menu support.
- CORE UPDATER: Allow sideloading cores from the menu.
- CPU FILTERS: Add Normal2x filter.
- CRT/LINUX: New Linux switching method partially implemented.
- CRT/LINUX: Linux restore desktop resolution fixed.
- CRT/LINUX: Monitor index switching and auto enumerate for output detection in Linux (still working on the windows method).
- CRT/RASPBERRY PI: Initial support.
- DATE: Add Date / Time style options.
- DEBUGGING: Add an integrated crash handler for debug builds (see https://docs.libretro.com/tech/debugging)
- DISCORD: Register the application name properly.
- DISK CONTROL: Remember the last used folder / current active folder to make disk-swapping faster.
- INPUT: Add new menu toggle (hold start button for 2 seconds)
- INPUT: Fix arrow keys being incorrectly bound as numpad keys
- INPUT/SDL: Flush the joypad events. Decreases cpu usage over time with the SDL joypad driver.
- LOCALIZATION: Add Greek translation.
- LOCALIZATION: Update German translation.
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Simplified Chinese translation.
- LOCALIZATION: Update Spanish translation.
- MENU: New "ozone" menu driver.
- MENU: Only show CRT SwitchRes if video display server is implemented (Windows/Linux for now)
- MENU: User Interface -> Appearance -> 'Menu Font Green/Blue Color' settings now work properly.
- MENU: Add option to enable in-menu sound effects.
- MENU/D3D: Scissoring support (will be used for Ozone and menu widgets).
- MENU/QT/WIMP: Allow building with MSVC2017.
- MENU/QT/WIMP: Add detailed file browser table.
- MENU/QT/WIMP: New grid view implementation that is faster and loads thumbnails on-demand.
- MENU/QT/WIMP: Thumbnail drag and drop support.
- MENU/RGUI: Overhaul custom theme interface + add wallpaper support.
- MENU/RGUI: Thumbnail support and thumbnail downscaling.
- MENU: Hide password values.
- MENU/SOUNDS: Implement in-menu sound effects (not enabled by default for now, still experimental).
- MIDI: Add a Linux ALSA driver for MIDI.
- NETPLAY: Force fast-save-states when netplay is enabled.
- NETPLAY: Allow quick joining subsystem lobbies.
- OSX: Initial CoreAudio V3 audio driver (not yet used in release builds).
- OSX: OpenGL 3.2 Core support for cores.
- PS2: Initial PlayStation2 port.
- PS4: Initial PlayStation4 port.
- RECORDING: Implement recording options in the menu complete with quality profiles, streaming, and proper file naming
- SCANNER: Fix GDI disc scanning.
- SHADERS: Fix auto shader preset loading on D3D10, D3D11, D3D12
- SUBSYSTEM: Allow more than 10 subsystems
- SUBSYSTEM: Cores that use subsystem for complex scenarios can now load content without starting a regular content first
- SUBSYSTEM: Remember the last used folder to make loading subsystem type content faster
- SWITCH/LIBNX: Improve touch scaling calculation.
- SWITCH: Proper button labels.
- TVOS: Initial tvOS port.
- VULKAN: Fix RGUI crashing at startup.
- VULKAN/RGUI: Enable 'Menu Linear Filter' option.
- VULKAN: Fix secondary screens in overlays not working.
- WAYLAND: Implement idle-inhibit support (needed for screensaver suspend).
- WAYLAND: Fix fullscreen toggle.
- WIIU: Initial netplay peer-to-peer support. Network information working.
- WINDOWS/WSA: Network Information info is blank until first network operation.
- WINDOWS: Fix an ancient bug that caused wrong mappings for keyboard arrows.
- WINDOWS: Remember window size and position if so desired.
- WINDOWS: SSL/TLS connections now work properly.
- WINDOWS: Fall back to GDI driver if no accelerated graphics driver is found.
- UWP: Initial UWP port.
- VFS: Update to version 3.
- XBONE: Initial Xbox One port.
- XMB/OZONE: Add more icons
- XMB: Add Automatic Inverted theme
- ???: Easter Egg
# 1.7.5
- CAMERA: Fix Video4Linux2 driver that broke years ago.
- CONFIG: Add 'Reset To Defaults' setting in Configurations. Thi will reset your config file to defaults.
- CHEATS: Add support for Rumble when increase or decrease by the rumble value.
- CHEATS: Add cheat variables to allow for updating large portions of memory.
- CHEEVOS: Prevent loading states before achievements are fully loaded.
- CRT: New porches and interlaced bug fix.
- CRT: New functionality, ability to switch between 15KHz and 31KHz, etc.
- COMMON: Support for "OEM-102" key (usually '\' on Euro keyboards).
- DISCORD: Add 'Ask To Join' Feature.
- EMSCRIPTEN: Add stb_font support.
- INPUT: Add new menu toggle combos 'L3 + R' and 'L + R' (useful for Switch).
- IOS: Use safe area to account for notch for iPhone X and adjust main view.
- LOCALIZATION: Update Portuguese / Brazilian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Polish translation.
- LOCALIZATION: Update Spanish translation.
- MENU: Add dropdown lists for many settings.
- MENU: Fix crash that could happen when changing core's options on Android.
- MENU/QT/WIMP: Add option to rename playlists.
- MENU/QT/WIMP: Add option to filter extensions inside archives when adding to a playlist.
- MENU/QT/WIMP: Rename playlist entries with 2 single clicks.
- MENU/QT/WIMP: Fix shader parameter checkboxes not working
- METAL: Add screenshot support.
- NETPLAY: Save lobby details received back from server after first announcement.
- OPENGL/GLX: Implement Adaptive VSync - GLX_EXT_swap_control_tear.
- OPENGL/WGL: Implement Adaptive VSync - WGL_EXT_swap_control_tear.
- RUNAHEAD: Fix performance degradation that could happen over time (after approx. 30 mins). Fixed input IDs outside of range 0-35 causing slow performance in runahead.
- SWITCH: Add stb_font support.
- SWITCH: Add Retro Achievements support.
- SWITCH: Add networking support.
- SWITCH: Add touchscreen support.
- SWITCH: Add OpenGL support.
- SWITCH: Merging of RetroNX Nintendo Switch port, based on libnx SDK.
- VULKAN: Fix race condition in threaded mailbox emulation.
- VULKAN: Maintenance fixes.
- WIIU: Fix menu lag when built with DevKitPro r32.
# 1.7.4
- ANDROID: Add sustained performance mode, can be turned on/off in Power Management settings menu.
- ANDROID: Powerstate/battery level support.
- CHEEVOS: Fix crash when scrolling Achievement List while Unofficial Achievements enabled (#6732).
- CHEEVOS: Added hitcounts support for PauseIf/ResetIf (#6817).
- COMMON: Automatically hide "Configuration Override options" in Quick Menu.
- COMMON: Small Bugfix to not trigger savestate code when pressing Reset.
- COMMON: Added libsixel video driver.
- EMSCRIPTEN: Fix Game Focus Toggle.
- HID/OSX: Fix to set hid device registration deterministic (#6497), to address issue #6640 re-adding dynamic device registration.
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Polish translation.
- LOCALIZATION: Update Portuguese / Brazilian translation.
- LOCALIZATION: Update Russian translation.
- LOCALIZATION: Update Spanish translation.
- MIDI: Add MIDI support to the libretro API. Dosbox is the first proof of concept core implementing libretro MIDI.
- MIDI: Add a Windows driver for MIDI, based on winmm.
- MENU/QT/WIMP: Qt QSlider styling for Dark Theme.
- MENU/QT/WIMP: Remove button ghostly inside highlighting.
- MENU/QT/WIMP: Initial grid view.
- MENU/QT/WIMP: Drag&drop to add new playlist items, add option to add/edit/delete playlists.
- MENU/QT/WIMP: Add menu option to update RetroArch (Windows only for now).
- MENU/QT/WIMP: Add menu option to manage shaders.
- MENU/QT/WIMP: Add menu option to manage core options.
- MENU/XMB: Add new icons for the settings
- MENU/XMB: Add an option to show the desktop ui
- METAL: Initial work-in-progress video driver for Metal. macOS-only right now, and currently requires macOS 10.13.
- METAL: Supports XMB/MaterialUI, has a menu display driver. Has a font rendering driver.
- METAL/SLANG: Slang shaders should be compatible with Metal video driver.
- NETWORK: Enable SSL/TLS support by default for desktop platforms.
- QNX: Fix Game Focus Toggle.
- PS3: Add audio mixer support for FLAC and MP3.
- PSP: Use proper button labels, fix inverted R-Stick Y axis.
- REMAPS: Fix the way offsets are calculated for keyboard remapping.
- RUNAHEAD: Fix full-screen mode change breaking Secondary Core's environment variables.
- VITA: Use proper button labels, fix inverted R-Stick Y axis.
- VITA: Add imc0: mount.
- VITA: Use sceCtrlIsMultiControllerSupported to detect.
- VULKAN: Fix two validation errors.
- VULKAN: Try to avoid creating swapchains redundantly. Should fix black screen and having to alt tab out of window again to get display working on Nvidia GPUs (Windows).
- VULKAN/OSX: Initial MoltenVK support. Not enabled yet, several MoltenVK bugs should be fixed first before we can have it fully working.
- WINDOWS/DINPUT: Add rumble support.
- WINDOWS/DINPUT: Fix Game Focus Toggle.
- WINDOWS/RAWINPUT: Fix Game Focus Toggle.
- X11: Fix Game Focus Toggle.
- WII: Change deflicker setting to work in 480p or higher, and always enables vfilter so that the user can easily change brightness.
- WIIU: Fix out-of-bounds rendering bug
- WIIU: Implement UDP broadcast network logging on Wii U.
- WIIU: Audio should no longer clip.
# 1.7.3
- AUDIO: Audio mixer supports FLAC/MP3 file types now!
- COMMON: Fixed bug 'crashing in cores that don't range check retro_set_controller_type'. Some people were having crashes when device is set to RETRO_DEVICE_NONE and the cores don't check the number of ports, in VBAM's case it was overflowing and crashing. QuickNES was crashing too.
- COMMON: Fixed buffer overflow in url encoding (affecting MSVC2010/2013).
- COMMON: (QuickMenu) Added Configuration Override submenu.
- HID: Merge new HID subsystem.
- HID: Fix WaveBird support for the Wii U GCA.
- HID/OSX: Fix regression with IODHIDManager - gamepads which are connected later would not be autoconfigured.
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Portuguese translation.
- MENU: New WIMP Qt GUI!
- MENU: Audio mixer now works in the menu without any cores loaded. You have to enable the setting 'Enable menu audio' for this to work.
- REMAPPING/OVERLAYS: Fix regression - overlays could no longer be remapped.
- SCANNER: Add Wii Backup File WBFS support.
- X11: CRT SwitchRes support for X11/Linux.
# 1.7.2
- ANDROID/OPENSL: Prevent crashes when setting audio latency too low (buffer count can never be lower than 2 now).
- CRT: Added CRT SwitchRes.
- COMMON: Hide the 'Core delete' option if the 'Core updater' is also hidden.
- COMMON: Add way to reset core association for playlist entry.
- COMMON: Fix invalid long command line options causing infinite loop on Windows
- COMMON: Add OSD statistics for video/audio/core.
- COMMON: Added runahead system; allows you to drive down latency even further.
- COMMON: Fix buggy behavior that could happen with ZIP file reading on some platforms as a result of not initializing struct.
- CHEEVOS: Support Atari 2600, Virtual Boy, and Arcade (only Neo Geo, CPS-1, CPS-2 and CPS-3 and only with fbalpha core).
- CHEEVOS: Add option to automatically take a screenshot when an achievement is triggered.
- CHEEVOS: Fixed incompatibilities with Neo Geo Pocket achievement sets.
- CHEEVOS: Store only login token, not password.
- D3D10: Added D3D10 driver to release build. Has working shaders (Slang), overlay, and menu display driver support. Should be on par capabilities wise
with D3D11 driver except for there being no hardware rendering right now.
- D3D11: Experimental hardware renderer. Allows for libretro cores to use D3D11 for hardware rendering. First core to use this is PPSSPP.
- D3D11: Increase backwards compatibility, shaders compile with Shader Model 4.0 now, added support for more feature levels.
- D3D10/D3D11/D3D12: Fix crashes with completely black or white thumbnail textures in XMB.
- GUI: Support disabling window decorations on Windows and Linux.
- LIBRETRO: Addition - Functions to enable and disable audio and video, and an environment function to query status of audio and video enables.
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Polish translation.
- MENU: Add Rewind/Latency/Overlay settings to Quick Menu, add options to show/hide them (User Interface -> Views -> Quick Menu)
- MENU/RGUI: Only show Menu Linear Filter for RGUI and only show it for
video drivers that implement it (D3D8/9/10/11/12/GL)
- MENU/RGUI: Add User Interface -> Appearance options.
- MENU/RGUI: D3D8/D3D9: Hookup Menu Linear Filter
- MENU/XMB: Disable XMB shadow icons by default for PowerPC and ARM for performance reasons.
- MENU/XMB: Left/right thumbnails are now automatically scaled according to layout.
- MENU/XMB: Add Left Thumbnails (additional to the right).
- MENU/XMB: Fixed left/right tab regression.
- MENU/XMB: Fix scaling of tall images that were cut on bottom previously.
- MENU/XMB: Menu scale factor setting now changes texts length, image scaling and margins.
- MENU/XMB: Mouse cursor scales correctly now.
- MENU/XMB: Add toggle to show/hide Playlist tabs.
- MENU/XMB: Add menu layout - can switch between Desktop, Handheld and Auto.
- MENU/XMB: Don't load menu pipeline shaders unless XMB is selected (D3D10/D3D11/D3D12/GL/Vulkan)
- MENU/VIDEO: Only show black frame insertion for the video drivers/context drivers
that support it (so far this includes - D3D8/D3D9, OpenGL, Vulkan)
- MENU/VIDEO: Only show max swapchain images if supported by video driver and/or context driver (so far this includes - DRM EGL context driver, VideoCore EGL context driver, Vulkan)
- MENU/MaterialUI: Automatic DPI Scaling should be much improved now, now scales as expected at 1440p and 4K resolutions.
- MENU/MaterialUI: Fix wrong calculation of an entry height causing long playlists to end up outside of screen range. This also could cause crashes on low DPI screens.
- IOS: Fixed crash when opening downloaded roms from Safari or using the "Open in.." functionality. Added the compiler flag to support keyboard remapping to controls.
- IOS: Fixed buffer overlap that caused a crash while trying to download GLSL shaders from the buildbot.
- PS3: fix URLS
- REMAPS: Mapping keyboard keys from more than one gamepad (works with dosbox)
- REMAPS: Mapping more than one button to the same action
- REMAPS: Unmapping buttons
- REMAPS: Unmapping analogs
- REMAPS: Mapping a button to trigger an analog response (tested with mupen, can run on SM64 with the d-pad now, triggers a full analog tilt)
- REMAPS: Mapping an analog to another analog (having more than one analog mapped to the same output causes issues)
- REMAPS: Mapping an analog to produce a button response
- SCANNER: Should be able to scan dual-layer Wii disc images now, filestream code now supports files larger than 4GB.
- SHADERS/SLANG: Slang shaders should work again on Android version and MSVC versions (basically all the Griffin-based versions).
- SHADERS: If GL context is GLES2/3/Core context, Cg shaders are unavailable. Applies to shader list too.
- SHADERS: Hide cg/glsl shaders from being able to be selected if D3D8/9/10/11/Vulkan video drivers are selected.
- SHADERS: Hide slang shaders from being able to be selected if D3D8/9/OpenGL video drivers are selected.
- SHADERS: Prevent crashes from occurring if we have the GL video driver in use and we try to skip to a slang shader through next/previous hotkeys
- SHADERS: Fix shader parameter increase / decrease functions
- SUBSYSTEM: handle savestates properly (cart1 + cart2.state0)
- VULKAN/X11: Fix X11 Vulkan bug from Wayland driver.
- VULKAN: Fix multi-line text spacing in menus with Vulkan driver.
- WINDOWS XP: Add Cheevos support.
- WINDOWS/MSVC 2003/2005/2010/2013/2015/2017: Add Cheevos support.
- VITA: Bugfix for 'PS Vita takes many time to start to accept input' issue.
- X11: Allow compositor disabling on X11 fullscreen through _NET_WM_BYPASS_COMPOSITOR
- X11: Prioritize _NET_WM_STATE_FULLSCREEN_ in true fullscreen mode
- WIIU: Fix OOB read/write in keyboard driver.
# 1.7.1
- 3DS: Now correctly reports amount of CPU cores.
- 3DS: Frontend rating is now correctly implemented for both New 3DS/2DS and Old 3DS/2DS.
- 3DS: Initial networking support, HTTP requests won't work yet.
- 3DS: Now reports memory and battery state.
- AUDIO: Added 'Audio Resampler Quality' setting to Audio Settings. Setting this higher will increase sound quality at the expense of sound latency and/or performance. Setting this value lower will improve sound latency/performance at the expense of sound quality. Only has an effect if the Sinc resampler is used, and you have to restart the game for changes to take effect.
- CHEEVOS: Fix unofficial achievements not being loaded.
- CHEEVOS: Show savestate menu entries when no achievements are found even if hardcore mode is enabled.
- CHEEVOS: Support Neo Geo Pocket.
- COMMON: Bugfix for issue related to 'Windows mouse pointer visible when running MESS or MAME cores'.
- COMMON: Fix bug 'Last item in a Playlist is ignored'.
- COMMON: New LED API. Driver implemented for Raspberry Pi, proof of concept implemented for core MAME 2003.
- COMMON: Add quick menu option to watch shader files for changes and recompile them automatically (Linux only for now).
- D3D8: Direct3D 8 can now work on systems that have Direct3D 8 installed.
- D3D9: Add menu support for MaterialUI/XMB.
- D3D10: Initial video driver implementation.
- D3D11: Initial video driver implementation.
- D3D11: SPIRV-Cross/slang shader support for D3D11.
- D3D12: Initial video driver implementation.
- DINPUT: don't reinitialize input driver on network events / media insertion / network drive connection
- INPUT: show friendly names when available under input binds and system information
- INPUT: show the config name when available under system information
- GUI: Allow changing menu font color.
- GUI: Menu visibility options for RGUI and MaterialUI.
- GUI/MaterialUI: Works now with D3D8, D3D9 Cg, D3D11 and D3D12 drivers.
- GUI/XMB: Add Monochrome Inverted icon theme.
- GUI/XMB: Allow changing menu scale to 200%.
- GUI/XMB: Works now with D3D8, D3D9 Cg, D3D11 and D3D12 drivers. Menu shader effects currently don't work on D3D8/D3D9 Cg.
- HAIKU: Restored port.
- KEYMAPPER: prevent a condition that caused input_menu_toggle to stop working when a RETRO_DEVICE_KEYBOARD type device is enabled
- GL: ignore hard gpu sync when fast-forwarding
- IOS10/11: Handle hardware keyboards and iCade controllers
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Portuguese-Brazilian translation.
- LOCALIZATION: Update Spanish translation.
- NETPLAY: Add menu option to select different MITM (relay) server locations.
- OSX: Modify HID buttons detection algorithm.
- QB: Added --datarootdir, --sysconfdir, --bindir, --docdir and --mandir.
- QB: Deprecated --global-config-dir, --with-bin_dir and --with-man_dir.
- SHADERS: Allow saving of shader presets based on the parent directory (Saving one for */foo/bar/mario.sfc* would result in *shaders/presets/corename/bar.ext*). We decided it's safer to still isolate the presets to a single core because different cores may treat video output differently.
- SHADERS: Don't save the path to the current preset to the main config. This was causing weird behavior, instead it will try to load *currentconfig.ext* and it will save a preset with that name when select *apply shader preset*. The resulting shader will restore properly after restarting and even after core/parent/game specific presets are loaded
- SOLARIS: Initial port.
- SWITCH: Initial Nintendo Switch port, based on libtransistor SDK.
- PS3: Enable Cheevos.
- PSP: Enable threading support through pthreads.
- SHADERS: SPIRV-Cross/slang shader support for D3D11.
- SHIELD ATV: Allow the remote / gamepad takeover hack to work with the 2017 gamepad
- SUBSYSTEM: Subsystem saves now respect the save directory
- SUBSYSTEM: You can now load subsystem games from the menu (see https://github.com/libretro/RetroArch/pull/6282 for caveats)
- VULKAN: Fix swapchain recreation bug on Nvidia GPUs with Windows 10 (resolved in Windows Nvidia driver version 390.77).
- WINDOWS: Improved Unicode support (for cores/directory creation and 7zip archives).
- WINDOWS: Show progress meter on taskbar for downloads (Windows 7 and up).
- WINDOWS: WS_EX_LAYERED drastically decreases performance, so only set it when needed (transparency in windowed mode).
- WIIU: Overlay support.
- WIIU: Transparency support in menu + overlays.
- WIIU: Increased stability during core switching.
- WIIU: Shader support.
- WIIU: Menu shader effects added (shaders).
- WIIU: Add missing time/clock support. (also fixes RTC [Real Time Clock] in Gambatte)
- XBOX OG: Restored port.
# 1.7.0
- CHEEVOS: Add badges for achievements, shows thumbnail images of achievements.
- CHEEVOS: Leaderboard support.
- CHEEVOS: Only disable savestates on hardcore mode if achievements are not available.
- COMMANDLINE: Fix fullscreen toggle switch.
- COMMON: Add 'Automatically Load Content To Playlist' feature, enabled by default.
- COMMON: Fix slowmotion ratio always being reset back to 1.
- COMMON: Optimized NBIO implementations now for Apple, Windows, and Linux. Uses mmap for Linux/Windows/BSD if/when available. File I/O should now be much faster for loading images inside the menu.
- COMMON: Native Blissbox support now for latest firmware as of writing (2.0). Implementation through libusb and/or native Windows HID.
- COMMON: New lightgun API.
- COMMON: New VFS (Virtual File System) API.
- COMMON: Fixed some playlist bugs.
- COMMON: New snow shader.
- COMMON: Fix Quick Menu title, no longer shows 'Select File'.
- COMMON: Fix loading cores that require no content one after another.
- COMMON: Map Delete key to Y button for non-unified menu keyboard controls.
- COMMON: Fix for relative paths being normalised and generating a duplicate history entry.
- EMSCRIPTEN: Fix references to browserfs.
- FREEBSD: Support libusb HID input driver.
- HAIKU: Buildfix.
- INPUT: Map clear button to DEL key.
- LINUX/X11: Add RetroArch logo to window title bar.
- LINUX/X11: Input driver now supports new lightgun code.
- LINUX/X11: Support window transparency (requires a compositing window manager).
- LOBBIES: Fix for crash on join netplay rooms via touch / glui.
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Portuguese-Brazilian translation.
- LOCALIZATION: Update Polish translation.
- LOCALIZATION: Update Russian translation.
- MENU: Snowflake menu shader effect.
- OSX/PPC: Fix the GL2 renderchain, had to use EXT versions of framebuffer/renderbuffer functions.
- PS3: HTTP requests / downloads should now work.
- PS3: Core Updater now works.
- PS3: Improved font rendering, enable STB Unicode font renderer.
- PSP: Make it work with Vita's Adrenaline.
- PSP: Fix audio sync.
- PSP: Fix content loading, port should be functional again.
- PSP: Use 64MB when available.
- SCANNER: Fix crash from Windows-incompatible format string.
- VITA: Improve packaging, installation times.
- WIIU: Disabled the controller patcher for now since it was the source of many stability issues.
- VULKAN: Various stability fixes for WSI.
- WINDOWS: Add MSVC 2017 solution.
- WINDOWS: Get rid of the empty console window in MSVC 2010 builds.
- WINDOWS: Raw input driver now supports new lightgun code.
- WINDOWS: Use configured OSD/text message color on GDI driver.
- WINDOWS/XINPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names
- WINDOWS/XINPUT: Fix crash that occurs in some situations with Steam running and a Steam Controller plugged in.
- WINDOWS: Improve version reporting under System Information.
- WINDOWS: Support window transparency.
- WINDOWS: Correct usage of GetWindowPlacement per MS docs, fixes game window position on Win95/98.
- WINDOWS: Added Visual Studio 2017 support.
# 1.6.9
- COMMON: Small memory leak.
- NETPLAY: Fix network command only working once.
# 1.6.8
- Audio: Fix the Audio DSP picker
- CHEEVOS: Add support for Atari Lynx cheevos.
- CHEEVOS: Add support for RetroAchievements Leaderboards.
- GUI: (MaterialUI) Fix crash that happened on context reset with Vulkan.
- GUI: (MaterialUI) Skip querying and drawing items that are not visible; Cache content height and bbox calculation.
- GUI: (MaterialUI) Fix entry box highlight calculation.
- GUI: (XMB) Skip drawing the fading list when it is already transparent. Optimization.
- GUI: (XMB) Comment out visible item calculation in xmb_draw_items().
- GUI: (RGUI) Prevent crashes when using a non-English language reliant on UTF8.
- GUI: Add menu option for OSD background color.
- GUI: Add menu option for OSD text color.
- GUI: Add menu option to remove frame count from OSD.
- GUI: Allow wraparound of int/float settings when pressing the left key
- INPUT/LIBRETRO: Add support for more mouse buttons (buttons 4/5)
- INPUT/LIBRETRO: Add support for analog buttons
- INPUT: Always show the controls menu even if descriptors are not set
- INPUT: Fix input descriptors not being set on cores that don't implement the controllers interface
- INPUT: Apply descriptors only for the amount of cores the core supports
- INPUT: Implement keyboard to gamepad input remapping (limited to one gamepad device for now)
- INPUT: Fix absolute mouse move handling on the winraw driver
- INPUT: Ignore keyboard input if window is not active on udev driver
- INPUT: Sanitize the filenames of autoconfig profiles before saving
- LOBBIES: Fix crash on navigating left / right from the lobby menu
- LOCALIZATION: Update Dutch translation
- LOCALIZATION: Update Italian translation.
- LOCALIZATION: Update Japanese translation.
- LOCALIZATION: Update Portuguese-Brazilian translation.
- LOCALIZATION: Update Russian translation.
- LINUX/ARMHF: Set buildbot updater URL to armhf location instead of blank string
- LINUX/PI: Broadcom VC4: Add Videocore config option
- LINUX/UDEV: Fix - RetroArch reads keyboard input when not focused with the udev input driver.
- NETPLAY: Fix disconnection not fully deinitializing Netplay.
- NETPLAY: Fix lan rooms when there is more than one room
- NETPLAY: Fix lan rooms on systems where all addresses are treated as IPv6
- COMMON: Fix clear/free loop conditionals in playlists.
- WINDOWS/GDI: Fix flickering of text.
- WINDOWS/GDI: Fix graphics corruption on Windows 98
- WINDOWS/GDI: Allow compiling without DirectInput8 for NT support
- WINDOWS/WGL: Try to use wglSwapLayerBuffers instead of SwapBuffers if possible (for more optimal performance).
- WINDOWS: Fix menubar text corruption on Japanese locale systems
- WINDOWS: Support Unicode file I/O (can now display CJK characters in file browser for example).
- WINDOWS: Support Windows 95, NT3.51, NT4
- WINDOWS: add Makefile.griffin targets for msvc6,2003,2005,2010,2012,2013
- WII: Use custom, embedded libogc SDK.
- WIIU: Initial touchscreen support for WiiU gamepad.
- WIIU: Add Cheevos support.
- SCANNER: Fix archive scanning.
- SCANNER: Support CHD files.
- SCANNER: Support Gamecube ISO scanning.
- SCANNER: Use primary data track of disc images for CRC lookups rather than cue files. This is slower but finds matches more reliably, and is necessary for CHD files to work at all. Update your databases!
- SCANNER: Fall back on looking inside archives when matching MAME/FBA content (most recent cores only). If you had difficulty with content being detected before, you may have better luck now. Update your databases and core info!
# 1.6.7
- SCANNER: Fix directory scanning.
- SCANNER: Fix file scanning.
- COMMON: Fix 'Disk Image Append' option.
- FREEBSD: Compatibility fixes for Video4Linux2 camera driver.
- GUI: (MaterialUI) Add disk image append icons.
- GUI: (MaterialUI) Improve word wrapping when menu icons are enabled.
- GUI: (MaterialUI) Add User Interface -> Appearance -> Menu Icons Enable. You can turn on/off the icons on the lefthand side of the menu entries.
- GUI: Performance optimizations for XMB menu driver - only calculates visible items.
- LOCALIZATION: Update Italian translation.
# 1.6.6
- 3DS: Fixes serious performance regression that affected every core; rewind was always implicitly enabled.
- AUDIO: MOD/S3M/XM sound should now be properly mixed in with the core's sound.
- GUI: Visual makeover of MaterialUI.
- GUI: Added 'Music', 'Images' and 'Video' collection options to RGUI/MaterialUI.
- GUI: Allow the user to add 'Favorites'.
- GUI: Allow the user to rename entries.
- GUI: Performance optimizations for XMB menu driver.
- LOCALIZATION: Update Italian translation
- INPUT: Overlay controller response - when we press buttons on the gamepad or keyboard, the corresponding buttons on the overlay will be highlighted as well.
- NETBSD: Silence some compilation warnings.
- COMMON: Fixed bug 'Deleting an entry from a playlist would not update the list view inside XMB'.
- COMMON: Fix inet_ntop_compat on Unix
- LOBBY: Add skeleton to add help descriptions to lobbies
# 1.6.5
Skipped this one.
# 1.6.4
- ANDROID: Fire Stick & Fire TV remote overrides gamepad port 0 on button press and viceversa like SHIELD devices
- ANDROID: Provide default save / system / state / screenshot locations
- AUDIO: Audio mixer supports MOD/S3M/XM file types now!
- INPUT: input swap override flag (for remotes) is cleared correctly
- INPUT: allow specifying libretro device in remap files
- INPUT: allow specifying analog dpad mode in remap files
- INPUT: allow saving libretro device to remap files
- INPUT: allow saving analog dpad mode to remap files
- INPUT: allow removing core and game remap files from the menu
- COMMON: Cores can now request to set a 'shared context'. You no longer need to explicitly enable 'Shared Hardware Context' for Citra/OpenLara/Dolphin.
- COMMON: Add 'Delete Core' option to Core Information menu.
- COMMON: Allow Max Timing Skew to be set to 0.
- COMMON: Change the "content dir" behavior so it works on either a flag or an empty directory setting, now platform drivers can provide defaults for save / system / state / screenshot dirs and still allow the content dir functionality, these settings are under settings / saving and flagged as advanced
- GUI: You can turn on/off 'Horizontal Animation' now for the XMB menu. Turning animations off can result in a performance boost.
- GUI: Fix sublabel word-wrapping in XMB where multi-byte languages were cut off too soon
- LOCALIZATION: Update Dutch translation
- LOCALIZATION: Update Traditional Chinese translation
- LOCALIZATION: Update Italian translation
- LOCALIZATION: Update Russian translation
- WINDOWS: Provide default save / system / state / screenshot locations
- LOBBIES: Show what country the host is in
- MENU: Enable OSD text rendering for gdi and libcaca drivers
- WINDOWS 98/ME/2K: Set default directory for MSVC 2005 RetroArch version.
- WII: Better V-Sync handling, backported from SuperrSonic.
- WIIU: Exception handler rewritten.
# 1.6.3
- IOS: Fix GL regression - 32bit color format cores were no longer rendering
- CHEEVOS: Add support for N64 cheevos and other small fixes.
- CHEEVOS: Add 'Achievements -> Achievements Verbose Mode'. Ability to display cheevos related messages in OSD, useful for RetroAchievements users.
- AUDIO: Audio mixer's volume can now be independently increased/decreased, and muted.
- AUDIO: Mute now no longer disables/enables audio but instead properly mutes the audio volume. Mute is also independent from the audio mixer volume.
- INPUT: Add mouse index selection; ability now to select between different mice
- INPUT: Fix 'All Users Control Menu' setting
- LINUX: Add a tinyalsa audio driver. Doesn't require asoundlib, should be self-contained and lower-level.
- LOBBIES: Announce the RetroArch version too
- LOCALIZATION: Add Traditional Chinese translation
- LOCALIZATION: Update French translation
- LOCALIZATION: Update Italian translation
- LOCALIZATION: Update Japanese translation
- LOCALIZATION: Update Russian translation
- MENU: Add 'User Interface -> Views'. Ability to display/hide online updater and core updater options.
- NETPLAY: Disconnecting one client shouldn't cause everyone to disconnect anymore
- NETWORK: SSL/TLS support, disabled by default
- SCANNER: Fix PS1 game scanning
- SCANNER: Move content list builder into scanner task with progress, fixes menu freeze with large playlists
- SDL2: Fix 'SDL2 driver does not see the hat on wired Xbox 360 controller"
- SETTINGS: Fix regression 'Custom Viewport is no longer overridable per-core or per-game'
- VITA: Add cheevos support
- VITA: Add support for external USB if mounted
- WAYLAND: Fix menu mouse input
- WII: Add support for single-port 'PS1/PS2 to USB controller adapter
# 1.6.0
- ANDROID: Allow remotes to retain OK/Cancel position when menu_swap_ok_cancel is enabled
- ANDROID: Improve autoconf fallback
- ANDROID: Improve shield portable/gamepad device grouping workaround
- ANDROID: Runtime permission checking
- AUDIO: Audio mixer support. Mix up to 8 streams with the game's audio.
- AUTOSAVE/SRAM - Fix bug #3829 / #4820 (https://github.com/libretro/RetroArch/issues/3829)
- ENDIANNESS: Fixed database scanning. Should fix scanning on PS3/WiiU/Wii, etc.
- LOBBIES: Fallback to filename based matching if no CRC matches are found (for people making playlists by hand)
- LOBBIES: GUI refinement, show stop hosting when a host has been started, show disconnect when playing as client
- LOBBIES: if the game is already loaded it will try to connect directly instead of re-loading content (non-fullpath cores only)
- LOBBIES: unify both netplay menus
- LOCALIZATION/GUI: Korean font should display properly now with XMB/MaterialUI's default font
- LOCALIZATION: Update German translation
- LOCALIZATION: Update Japanese translation
- LOCALIZATION: Update Russian translation
- LOCALIZATION: Update/finish French translation
- MENU: Improved rendering for XMB ribbon; using additive blending (Vulkan/GL)
- MISC: Various frontend optimizations.
- NET: Fix bug #4703 (https://github.com/libretro/RetroArch/issues/4703)
- OSX/MACOS: Fixes serious memory leak
- THUMBNAILS: Thumbnails show up now in Load Content -> Collection, Information -> Database
- VIDEO: Fix threaded video regression; tickering of menu entries would no longer work.
- VITA: Fix 30fps menu (poke into input now instead of reading the entire input buffer which apparently is slow)
- VITA: Fix frame throttle
- VITA: Fix slow I/O
- VULKAN: Fix some crashes on loading some thumbnails
- VULKAN: Unicode font rendering support. Should fix bad character encoding for French characters, etc.
- WII: Fix crashing issues which could occur with the dummy core
- WIIU: HID Controller support
- WIIU: Initial network/netplay support
- WIIU: XMB/MaterialUI menu driver support
- WINDOWS: Added RawInput input driver for low-latency, low-level input.
- WINDOWS: Added WASAPI audio driver for low-latency audio. Both shared and exclusive mode.
- WINDOWS: Core mouse input should be relative again in cores
# 1.5.0
- ANDROID: Autoconf fallback
- ANDROID: Mouse support / Emulated mouse support
- AUTOCONF: Fix partial matches for pad name
- CHEEVOS: Fix crashes in the cheevos description menu
- CHEEVOS: WIP leaderboards support
- COMMON: 9-slice texture drawing support
- COMMON: Threading fixes
- CORETEXT/APPLE: Ability to load menu display font drivers and loading of custom font.
- DOS: Add keyboard driver
- DOS: Improve color accuracy and scaling
- GUI: Add a symbol page in the OSK
- GUI: Allow changing icon theme on the fly
- GUI: Better dialogs for XMB
- GUI: Various settings are now only visible when advanced settings is enabled
- LOCALIZATION: Add/update Korean translation
- LOCALIZATION: Rewrite German translation
- LOCALIZATION: Update several English sublabels
- LOCALIZATION: Update several Japanese labels
- MOBILE: Long-tap a setting to reset to default
- MOBILE: Single-tap for menu entry selection
- NET: Allow manual netplay content loading
- NET: Announcing network games to the public lobby is optional now
- NET: Bake in miniupnpc
- NET: Fix netplay join for contentless cores
- NET: Fix netplay rooms being pushed on the wrong tab
- NET: Lan games show next to lobbies with (lan) and connect via the private IP address
- NET: Use new lobby system with MITM support
- NUKLEAR: Update to current version
- SCANNER: Always add 7z & zip to supported extensions
- VULKAN: Add snow/bokeh shader pipeline effects - at parity with GL now
- VULKAN: Find supported composite alpha in swapchain
- WIIU: Keyboard support
- WINDOWS: Fix loading of core/content via file menu
- WINDOWS: Logging to file no longer spawns an empty window
# 1.4.1

View File

@ -1,58 +0,0 @@
# Contributing to RetroArch
If you are a developer and want to contribute to the development of RetroArch, please read this.
If you have found a bug and want to submit a minor patch or a bug report, please read this as well.
# Submitting a bug report
When submitting a bug report, make sure that the bug is local to RetroArch.
A bug in a libretro core or something deemed to be external is likely to be closed very fast.
If you still suspect a bug in RetroArch, make sure to test with several cores to make sure.
If you have troubles building RetroArch on Linux/BSD/OSX, make sure to paste shell output of ./configure,
as well as config.log and shell output of make. If building on Windows, just paste shell output of make.
If the issue occurs during runtime, make sure to paste RetroArch's verbose log.
If using Phoenix frontend, you can find log in (File -> Show Log) after running.
In console, make sure to run with verbose (-v) flag.
# Pull Requests
Outside contributions are generally only accepted in the form of a pull request. The process is very simple.
Fork RetroArch, make your changes, and issue a pull request on GitHub. This can all be done within the browser.
The changes are reviewed, and might be merged in. If the pull request isn't acceptable at the time,
note that it's possible to continue pushing up commits to your branch.
If you want to develop a larger feature,
we'd like to discuss this first (ideally on IRC) so that you don't risk developing something
that won't be merged. A pull request with a proof-of-concept is fine, but please indicate so.
## libretro API
If you wish to add functionality to libretro's API, it can take some time to merge in, because changes
to libretro API will affect other projects as well, and we highly value API/ABI stability.
Features will only be added when deemed *necessary* for a concrete libretro core to function properly.
Features will not be added on basis of hypothetical libretro implementations.
# Coding style
Having a consistent code style throughout the code base is highly valued.
Please look through the code to get a feel for the coding style.
A pull request may be asked to fix the coding style before submission.
In other cases, a pull request may be followed up with a "style nit commit".
## Non-obvious things:
- Code should be both ISO C99 and ISO C++ compatible. This dual requirement is for XBox360 and MSVC in general. Think of it as a C++ compatible subset of C99.
- Warnings are not allowed (-Wall). Make sure your code is warning-free. Note that warning sensitivity differs a bit across compiler versions.
- Using deprecated APIs is discouraged.
# Copyright Headers and AUTHORS
If you have contributed to a part of a source file (a chunk of code that's written by you),
you should add yourself to the copyright header in that file.
If you have contributed significantly
(a feature, a contribution you can "name", e.g. "Added audio driver foo"), you should add yourself to AUTHORS file.
We'd like your full name and email, and which features you have been part of.
# IRC
Active development happens on IRC. (#retroarch @ irc.freenode.org)
We value discussing things in "real-time".
# Commit Access
Contributors who show a track record of making good pull requests over time will eventually get commit access to the repo.
This typically happens when the "overhead" of looking through pull requests over time becomes a burden.

674
COPYING
View File

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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 Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

2482
Doxyfile

File diff suppressed because it is too large Load Diff

296
Makefile
View File

@ -1,293 +1,41 @@
HAVE_FILE_LOGGER=1
HAVE_CC_RESAMPLER=1
NEED_CXX_LINKER=0
MISSING_DECLS =0
TARGET := spirv-cross
ifneq ($(C90_BUILD),)
C89_BUILD=1
endif
SOURCES := $(wildcard spirv_*.cpp)
CLI_SOURCES := main.cpp
include config.mk
OBJECTS := $(SOURCES:.cpp=.o)
CLI_OBJECTS := $(CLI_SOURCES:.cpp=.o)
# Put your favorite compile flags in this file, if you want different defaults than upstream.
# Do not attempt to create that file upstream.
# (It'd be better to put this comment in that file, but .gitignore doesn't work on files that exist in the repo.)
-include Makefile.local
STATIC_LIB := lib$(TARGET).a
TARGET = retroarch
DEPS := $(OBJECTS:.o=.d) $(CLI_OBJECTS:.o=.d)
OBJ :=
LIBS :=
DEF_FLAGS :=
ASFLAGS :=
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
OBJDIR_BASE := obj-unix
CXXFLAGS += -std=c++11 -Wall -Wextra -Wshadow
ifeq ($(DEBUG), 1)
OBJDIR := $(OBJDIR_BASE)/debug
CFLAGS ?= -O0 -g
CXXFLAGS ?= -O0 -g
DEFINES += -DDEBUG -D_DEBUG
CXXFLAGS += -O0 -g
else
OBJDIR := $(OBJDIR_BASE)/release
CFLAGS ?= -O3
CXXFLAGS ?= -O3
DEF_FLAGS += -ffast-math
CXXFLAGS += -O2 -DNDEBUG
endif
ifneq ($(findstring BSD,$(OS)),)
DEF_FLAGS += -DBSD
LDFLAGS += -L/usr/local/lib
UDEV_CFLAGS += -I/usr/local/include/libepoll-shim
UDEV_LIBS += -lepoll-shim
ifeq ($(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS), 1)
CXXFLAGS += -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -fno-exceptions
endif
ifneq ($(findstring DOS,$(OS)),)
DEF_FLAGS += -march=i386
LDFLAGS += -lemu
endif
all: $(TARGET)
ifneq ($(findstring Win32,$(OS)),)
LDFLAGS += -static-libgcc -lwinmm
endif
-include $(DEPS)
include Makefile.common
$(TARGET): $(CLI_OBJECTS) $(STATIC_LIB)
$(CXX) -o $@ $(CLI_OBJECTS) $(STATIC_LIB) $(LDFLAGS)
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang"),1)
DEFINES += -Wno-invalid-source-encoding -Wno-incompatible-ms-struct
endif
$(STATIC_LIB): $(OBJECTS)
$(AR) rcs $@ $(OBJECTS)
ifeq ($(shell $(CC) -v 2>&1 | grep -c "tcc"),1)
MD = -MD
else
MD = -MMD
endif
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
ifeq ($(MISSING_DECLS), 1)
DEFINES += -Werror=missing-declarations
endif
ifeq ($(HAVE_DYLIB), 1)
LIBS += $(DYLIB_LIB)
endif
ifeq ($(HAVE_DYNAMIC), 1)
LIBS += $(DYLIB_LIB)
else
LIBS += $(libretro)
endif
ifneq ($(V),1)
Q := @
endif
ifeq ($(HAVE_DRMINGW), 1)
DEF_FLAGS += -DHAVE_DRMINGW
LDFLAGS += $(DRMINGW_LIBS)
endif
ifneq ($(findstring Win32,$(OS)),)
LDFLAGS += -mwindows
endif
DEF_FLAGS += -Wall $(INCLUDE_DIRS) -I. -Ideps -Ideps/stb
CFLAGS += $(DEF_FLAGS)
CXXFLAGS += $(DEF_FLAGS) -std=c++11 -D__STDC_CONSTANT_MACROS
OBJCFLAGS := $(CFLAGS) -D__STDC_CONSTANT_MACROS
ifeq ($(HAVE_CXX), 1)
ifeq ($(CXX_BUILD), 1)
LINK = $(CXX)
CFLAGS := $(CXXFLAGS) -xc++
CFLAGS += -DCXX_BUILD
CXXFLAGS += -DCXX_BUILD
else ifeq ($(NEED_CXX_LINKER),1)
LINK = $(CXX)
else
LINK = $(CC)
endif
else
LINK = $(CC)
endif
ifneq ($(CXX_BUILD), 1)
ifneq ($(GNU90_BUILD), 1)
ifneq ($(findstring icc,$(CC)),)
CFLAGS += -std=c99 -D_GNU_SOURCE
else
CFLAGS += -std=gnu99 -D_GNU_SOURCE
endif
endif
ifneq ($(C89_BUILD),)
CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long
endif
endif
ifeq ($(NOUNUSED), yes)
CFLAGS += -Wno-unused-result
CXXFLAGS += -Wno-unused-result
endif
ifeq ($(NOUNUSED_VARIABLE), yes)
CFLAGS += -Wno-unused-variable
CXXFLAGS += -Wno-unused-variable
endif
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
ifneq ($(X86),)
CFLAGS += -m32
CXXFLAGS += -m32
LDFLAGS += -m32
endif
ifneq ($(SANITIZER),)
CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS)
CXXFLAGS := -fsanitize=$(SANITIZER) $(CXXFLAGS)
LDFLAGS := -fsanitize=$(SANITIZER) $(LDFLAGS)
endif
ifneq ($(findstring $(GPERFTOOLS),profiler),)
LIBS += -lprofiler
endif
ifneq ($(findstring $(GPERFTOOLS),tcmalloc),)
LIBS += -ltcmalloc
endif
# Qt MOC generation, required for QObject-derived classes
ifneq ($(MOC_HEADERS),)
# prefix moc_ to base filename of paths and change extension from h to cpp, so a/b/foo.h becomes a/b/moc_foo.cpp
MOC_SRC := $(join $(addsuffix moc_,$(addprefix $(OBJDIR)/,$(dir $(MOC_HEADERS)))), $(notdir $(MOC_HEADERS:.h=.cpp)))
MOC_OBJ := $(patsubst %.cpp,%.o,$(MOC_SRC))
RARCH_OBJ += $(MOC_OBJ)
endif
all: $(TARGET) config.mk
$(MOC_SRC):
@$(if $(Q), $(shell echo echo MOC $<),)
$(eval MOC_TMP := $(patsubst %.h,%_moc.cpp,$@))
$(Q)QT_SELECT=$(QT_VERSION) $(MOC) -o $(MOC_TMP) $<
$(foreach x,$(join $(addsuffix :,$(MOC_SRC)),$(MOC_HEADERS)),$(eval $x))
$(MOC_OBJ):
@$(if $(Q), $(shell echo echo CXX $<),)
$(Q)$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
$(foreach x,$(join $(addsuffix :,$(MOC_OBJ)),$(MOC_SRC)),$(eval $x))
ifeq ($(MAKECMDGOALS),clean)
config.mk:
else
-include $(RARCH_OBJ:.o=.d)
ifeq ($(HAVE_CONFIG_MK),)
config.mk: configure qb/*
@echo "config.mk is outdated or non-existing. Run ./configure again."
@exit 1
endif
endif
retroarch: $(RARCH_OBJ)
@$(if $(Q), $(shell echo echo LD $@),)
$(Q)$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
$(OBJDIR)/%.o: %.c config.h config.mk
@mkdir -p $(dir $@)
@$(if $(Q), $(shell echo echo CC $<),)
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) $(MD) -c -o $@ $<
$(OBJDIR)/%.o: %.cpp config.h config.mk
@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 $@ $<
.FORCE:
$(OBJDIR)/git_version.o: git_version.c .FORCE
@mkdir -p $(dir $@)
@$(if $(Q), $(shell echo echo CC $<),)
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -c -o $@ $<
$(OBJDIR)/%.o: %.S config.h config.mk $(HEADERS)
@mkdir -p $(dir $@)
@$(if $(Q), $(shell echo echo AS $<),)
$(Q)$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
$(OBJDIR)/%.o: %.rc $(HEADERS)
@mkdir -p $(dir $@)
@$(if $(Q), $(shell echo echo WINDRES $<),)
$(Q)$(WINDRES) -o $@ $<
install: $(TARGET)
rm -f $(OBJDIR)/git_version.o
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)$(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 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/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/retroarch.desktop
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch.6
chmod 644 $(DESTDIR)$(MAN_DIR)/man6/retroarch-cg2glsl.6
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; \
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
uninstall:
rm -f $(DESTDIR)$(BIN_DIR)/retroarch
rm -f $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
rm -f $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
rm -f $(DESTDIR)$(DATA_DIR)/applications/retroarch.desktop
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
rm -f $(DESTDIR)$(MAN_DIR)/man6/retroarch.6
rm -f $(DESTDIR)$(MAN_DIR)/man6/retroarch-cg2glsl.6
rm -rf $(DESTDIR)$(ASSETS_DIR)
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) -MMD
clean:
rm -rf $(OBJDIR_BASE)
rm -f $(TARGET)
rm -f *.d
rm -f $(TARGET) $(OBJECTS) $(CLI_OBJECTS) $(STATIC_LIB) $(DEPS)
.PHONY: all install uninstall clean
print-%:
@echo '$*=$($*)'
.PHONY: clean

View File

@ -1,24 +0,0 @@
include Makefile.common
# Qt MOC generation, required for QObject-derived classes
ifneq ($(MOC_HEADERS),)
# prefix moc_ to base filename of paths and change extension from h to cpp, so a/b/foo.h becomes a/b/moc_foo.cpp
MOC_SRC := $(join $(addsuffix moc_,$(dir $(MOC_HEADERS))), $(notdir $(MOC_HEADERS:.h=.cpp)))
endif
MOC ?= $(error missing moc path)
.PHONY: generate
$(MOC_SRC):
@$(if $(Q), $(shell echo echo MOC $<),)
$(eval MOC_TMP := $(patsubst %.h,%_moc.cpp,$@))
$(MOC) -o $(MOC_TMP) $<
$(foreach x,$(join $(addsuffix :,$(MOC_SRC)),$(MOC_HEADERS)),$(eval $x))
generate: $(MOC_SRC)
@echo $(MOC_SRC)
print-%:
@echo '$*=$($*)'

View File

@ -1,93 +0,0 @@
# This build was put together and is maintained by ModMyClassic.com for Libretro.
# The purpose is to give Libretro a proper "official" build platform for classic consoles.
# If you need any help in building for the classics or have any questions then please visit
# https://modmyclassic.com/comp and we will help in any way possible!
# Building Prerequisites ##############
# arm-linux-gnueabihf-strip
# patchelf
# bc
include version.all
# Classic Readme Variables ############
CLASSIC_ALT_VER := $(shell echo $(RARCH_VERSION) | tr . _)
CLASSIC_MODS_VER := Official_Retroarch_v$(CLASSIC_ALT_VER)
CLASSIC_MODS_NAME := RetroArch v$(RARCH_VERSION) (Official Optimised)
CLASSIC_VERSION := $(RARCH_VERSION)
MOD_CREATOR := Libretro + ModMyClassic
MOD_CATEGORY := RetroArch
GIT_COMMIT := $(shell echo "`git rev-parse --short HEAD``git diff-index --quiet HEAD -- || echo '-dirty'`")
# Platform dependant Variables ########
HAKCHI_DIR := RA_Platform-Hakchi
HAKCHI_GIT := https://github.com/Classicmods/RA_Platform-Hakchi
# General Shared Variables ############
TARGET := retroarch
# Libretro Defines ####################
#HAVE_CLASSIC = Classic Hook, disable some features
#HAVE_C_A7A7 = Classic Armv7 Cortex A7 optimisation override
#HAVE_HAKCHI = Hakchi Hook, change default configurations etc (TODO)
all: $(TARGET)
retroarch:
#Build the RetroArch Binary for cross platform classics (ARMv7 Cortex A7)
patchelf --version #Check if you have patchelf installed... (sudo apt-get install patchelf)
CFLAGS="-marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" ./configure --host=arm-linux-gnueabihf --enable-mali_fbdev --disable-freetype --enable-opengles --enable-udev --enable-alsa --enable-neon --enable-floathard --disable-discord
make HAVE_CLASSIC=1 HAVE_C_A7A7=1 HAVE_HAKCHI=1 -j #Cook it
arm-linux-gnueabihf-strip -v retroarch
patchelf --replace-needed libSDL2-2.0.so.0 libSDL2.so retroarch #libSDL2-2.0.so.0 sym link doesn't exist on native build. Just patch the binary...
#HAKCHI BUILD (NESC, SNESC)
#FYI this build was originally known as RetroArch 'Neo' for Hakchi.
@echo "** BUILDING CLASSIC_MODS HAKCHI - $(CLASSIC_MODS_VER) HMOD PACKAGE **"
rm -fr /tmp/$(HAKCHI_DIR)
cd /tmp/; git clone $(HAKCHI_GIT)
cp retroarch /tmp/$(HAKCHI_DIR)/bin/retroarch
echo $$(echo "Built by: " $$USER @ $$(date) \\\\\\ Git Commit: $(GIT_COMMIT)) > /tmp/$(HAKCHI_DIR)/etc/libretro/retroarch_version
cp /tmp/$(HAKCHI_DIR)/readme.md /tmp/$(HAKCHI_DIR)/readme_COPY.md
printf "%s\n" \
"---" \
"Name: $(CLASSIC_MODS_NAME)" \
"Creator: $(MOD_CREATOR)" \
"Category: $(MOD_CATEGORY)" \
"Version: $(CLASSIC_MODS_VER)" \
"Built on: $(shell date)" \
"Git commit: $(GIT_COMMIT)" \
"---" > /tmp/$(HAKCHI_DIR)/readme.md
cat /tmp/$(HAKCHI_DIR)/readme_COPY.md >> /tmp/$(HAKCHI_DIR)/readme.md
rm /tmp/$(HAKCHI_DIR)/readme_COPY.md
@echo "** COMPRESSING $(CLASSIC_MODS_VER) HMOD PACKAGE **"
cd /tmp/$(HAKCHI_DIR)/; tar -czvf "$(CLASSIC_MODS_VER).hmod" *
mv /tmp/$(HAKCHI_DIR)/$(CLASSIC_MODS_VER).hmod .
@echo "** BUILT CLASSIC_MODS HAKCHI - $(CLASSIC_MODS_VER) HMOD PACKAGE **"
rm -fr /tmp/$(HAKCHI_DIR) #clean up tmp
@echo "*********************************************************************"
@echo "*** Classic ARM7 Cortex A7 build and packages built successfully! ***"
@echo "****************** Winner, Winner, Chicken Dinner! ******************"
@echo "*********************************************************************"
clean:
rm -rf obj-unix
rm -f *.d
rm -f *.o
rm -f audio/*.o
rm -f conf/*.o
rm -f gfx/*.o
rm -f gfx/drivers_font/*.o
rm -f gfx/drivers_font_renderer/*.o
rm -f gfx/drivers_context/*.o
rm -f gfx/py_state/*.o
rm -f compat/*.o
rm -f record/*.o
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
rm -f $(CLASSIC_MODS_VER).hmod

File diff suppressed because it is too large Load Diff

View File

@ -1,281 +0,0 @@
TARGET := retroarch_3ds
LIBRETRO =
DEBUG = 0
GRIFFIN_BUILD = 1
WHOLE_ARCHIVE_LINK = 0
BUILD_3DSX = 1
BUILD_3DS = 0
BUILD_CIA = 1
LIBCTRU_NO_DEPRECATION = 1
APP_TITLE = RetroArch 3DS
APP_DESCRIPTION = RetroArch 3DS
APP_AUTHOR = Team Libretro
APP_PRODUCT_CODE = RETROARCH-3DS
APP_UNIQUE_ID = 0xBAC00
APP_ICON = pkg/ctr/assets/default.png
APP_BANNER = pkg/ctr/assets/libretro_banner.png
APP_AUDIO = pkg/ctr/assets/silent.wav
APP_RSF = pkg/ctr/tools/template.rsf
APP_SYSTEM_MODE = 64MB
APP_SYSTEM_MODE_EXT = 124MB
APP_BIG_TEXT_SECTION = 0
APP_USE_SVCHAX = 0
include pkg/ctr/Makefile.cores
OBJ :=
OBJ += gfx/drivers/ctr_shaders/ctr_sprite.o
OBJ += ctr/ctr_system.o
OBJ += ctr/ctr_memory.o
OBJ += ctr/ctr_linear.o
OBJ += ctr/gpu_old.o
OBJ += ctr/exec-3dsx/exec_cia.o \
ctr/exec-3dsx/exec_3dsx.o \
ctr/exec-3dsx/mini-hb-menu/launch.o \
ctr/exec-3dsx/mini-hb-menu/loaders/rosalina.o \
ctr/exec-3dsx/mini-hb-menu/loaders/hax2.o \
ctr/exec-3dsx/mini-hb-menu/loaders/ninjhax1.o
ifeq ($(APP_BIG_TEXT_SECTION), 1)
APP_USE_SVCHAX = 1
LDFLAGS += -Wl,--defsym,__ctr_patch_services=__service_ptr
endif
ifeq ($(APP_USE_SVCHAX), 1)
OBJ += ctr/ctr_svchax.o
endif
DEFINES :=
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_RGUI -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB
#DEFINES += -DHAVE_NETWORKING -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_SOCKET_LEGACY -DHAVE_THREADS
#-DHAVE_SSL -DHAVE_BUILTINMBEDTLS -DMBEDTLS_SSL_DEBUG_ALL
#ssl is currently incompatible with griffin due to use of the "static" flag on repeating functions that will conflict when included in one file
else
HAVE_CC_RESAMPLER = 1
HAVE_MENU_COMMON = 1
HAVE_RTGA = 1
HAVE_RPNG = 1
HAVE_RJPEG = 1
HAVE_RBMP = 1
HAVE_MENU = 1
HAVE_RGUI = 1
HAVE_ZLIB = 1
HAVE_7ZIP = 1
HAVE_BUILTINZLIB = 1
HAVE_LIBRETRODB = 1
HAVE_MATERIALUI = 1
HAVE_XMB = 1
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
#HAVE_NETWORKING = 1
#HAVE_CHEEVOS = 1
#HAVE_SOCKET_LEGACY = 1
#HAVE_THREADS = 1
#HAVE_SSL = 1
#HAVE_BUILTINMBEDTLS = 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)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitpro")
endif
ifeq ($(strip $(CTRULIB)),)
CTRULIB = $(DEVKITPRO)/libctru
endif
APP_TITLE := $(shell echo "$(APP_TITLE)" | cut -c1-128)
APP_DESCRIPTION := $(shell echo "$(APP_DESCRIPTION)" | cut -c1-256)
APP_AUTHOR := $(shell echo "$(APP_AUTHOR)" | cut -c1-128)
APP_PRODUCT_CODE := $(shell echo $(APP_PRODUCT_CODE) | cut -c1-16)
APP_UNIQUE_ID := $(shell echo $(APP_UNIQUE_ID) | cut -c1-7)
MAKEROM_ARGS_COMMON = -rsf $(APP_RSF) -exefslogo -elf $(TARGET).elf -icon $(TARGET).icn -banner $(TARGET).bnr -DAPP_TITLE="$(APP_TITLE)" -DAPP_PRODUCT_CODE="$(APP_PRODUCT_CODE)" -DAPP_UNIQUE_ID=$(APP_UNIQUE_ID) -DAPP_SYSTEM_MODE=$(APP_SYSTEM_MODE) -DAPP_SYSTEM_MODE_EXT=$(APP_SYSTEM_MODE_EXT)
INCDIRS := -I$(CTRULIB)/include
LIBDIRS := -L. -L$(CTRULIB)/lib
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
CFLAGS += -mword-relocations \
-fomit-frame-pointer -ffast-math \
-Werror=implicit-function-declaration \
$(ARCH)
#CFLAGS += -Wall
CFLAGS += -DARM11 -D_3DS
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
ifeq ($(LIBCTRU_NO_DEPRECATION), 1)
CFLAGS += -DLIBCTRU_NO_DEPRECATION
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
CFLAGS += -I. \
-Ideps \
-Ideps/libz \
-Ideps/7zip \
-Ideps/stb \
-Ilibretro-common/include \
-Ilibretro-common/include/compat/zlib
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) -O3
LDFLAGS += -specs=ctr/3dsx_custom.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
CFLAGS += -std=gnu99 -ffast-math
LIBS := $(WHOLE_START) -lretro_ctr $(WHOLE_END) -lm
ifeq ($(DEBUG), 1)
LIBS += -lctrud
else
LIBS += -lctru
endif
ifeq ($(BUILD_3DSX), 1)
TARGET_3DSX := $(TARGET).3dsx $(TARGET).smdh
endif
ifeq ($(BUILD_3DS), 1)
TARGET_3DS := $(TARGET).3ds
endif
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) libretro_ctr.a
PREFIX := $(DEVKITARM)/bin/arm-none-eabi-
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
AS := $(PREFIX)as
AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
ifeq ($(strip $(CTRBANNERTOOL)),)
ifneq ($(findstring Linux,$(shell uname)),)
BANNERTOOL = pkg/ctr/tools/bannertool-linux
else ifneq ($(findstring Darwin,$(shell uname)),)
BANNERTOOL = pkg/ctr/tools/bannertool-mac
else
BANNERTOOL = pkg/ctr/tools/bannertool.exe
endif
else
BANNERTOOL = $(CTRBANNERTOOL)
endif
ifeq ($(strip $(CTRMAKEROM)),)
ifneq ($(findstring Linux,$(shell uname)),)
MAKEROM = pkg/ctr/tools/makerom-linux
else ifneq ($(findstring Darwin,$(shell uname)),)
MAKEROM = pkg/ctr/tools/makerom-mac
else
MAKEROM = pkg/ctr/tools/makerom.exe
endif
else
MAKEROM = $(CTRMAKEROM)
endif
%.o: %.vsh %.gsh
$(DEVKITARM)/bin/picasso $^ -o $*.shbin
$(DEVKITARM)/bin/bin2s $*.shbin | $(PREFIX)as -o $@
rm $*.shbin
%.o: %.vsh
$(DEVKITARM)/bin/picasso $^ -o $*.shbin
$(DEVKITARM)/bin/bin2s $*.shbin | $(PREFIX)as -o $@
rm $*.shbin
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
%.o: %.s
$(CC) -c -o $@ $< $(ASFLAGS)
%.o: %.S
$(CC) -c -o $@ $< $(ASFLAGS)
%.a:
$(AR) -rc $@ $^
%.vsh:
$(TARGET).smdh: $(APP_ICON)
$(DEVKITARM)/bin/smdhtool --create "$(APP_TITLE)" "$(APP_DESCRIPTION)" "$(APP_AUTHOR)" $(APP_ICON) $@
$(TARGET).3dsx: $(TARGET).elf
ifeq ($(APP_BIG_TEXT_SECTION), 1)
cp pkg/ctr/big_text_section.xml $(TARGET).xml
else
rm -f $(TARGET).xml
endif
$(DEVKITARM)/bin/3dsxtool $< $@ $(_3DSXFLAGS)
$(TARGET).elf: ctr/3dsx_custom_crt0.o
$(LD) $(LDFLAGS) $(OBJ) $(LIBDIRS) $(LIBS) -o $@
$(NM) -CSn $@ > $(notdir $*.lst)
$(TARGET).bnr: $(APP_BANNER) $(APP_AUDIO)
$(BANNERTOOL) makebanner -i "$(APP_BANNER)" -a "$(APP_AUDIO)" -o $@
$(TARGET).icn: $(APP_ICON)
$(BANNERTOOL) makesmdh -s "$(APP_TITLE)" -l "$(APP_TITLE)" -p "$(APP_AUTHOR)" -i $(APP_ICON) -o $@
$(TARGET).3ds: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
$(MAKEROM) -f cci -o $@ $(MAKEROM_ARGS_COMMON) -DAPP_ENCRYPTED=true
$(TARGET).cia: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
$(MAKEROM) -f cia -o $@ $(MAKEROM_ARGS_COMMON) -DAPP_ENCRYPTED=false
clean:
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

View File

@ -1,221 +0,0 @@
TARGET := retroarch_3ds_salamander
LIBRETRO =
DEBUG = 0
BUILD_3DSX = 1
BUILD_3DS = 0
BUILD_CIA = 1
APP_TITLE = RetroArch 3DS
APP_DESCRIPTION = RetroArch 3DS
APP_AUTHOR = Team Libretro
APP_PRODUCT_CODE = RETROARCH-3DS
APP_UNIQUE_ID = 0xBAC00
APP_ICON = pkg/ctr/assets/default.png
APP_BANNER = pkg/ctr/assets/libretro_banner.png
APP_AUDIO = pkg/ctr/assets/silent.wav
APP_RSF = pkg/ctr/tools/template.rsf
APP_SYSTEM_MODE = 64MB
APP_SYSTEM_MODE_EXT = 124MB
OBJ := ctr/ctr_system.o \
ctr/ctr_memory.o \
ctr/ctr_linear.o \
frontend/frontend_salamander.o \
frontend/frontend_driver.o \
frontend/drivers/platform_ctr.o \
frontend/drivers/platform_null.o \
libretro-common/encodings/encoding_utf.o \
libretro-common/compat/compat_strcasestr.o \
libretro-common/compat/fopen_utf8.o \
libretro-common/file/file_path.o \
libretro-common/string/stdstring.o \
libretro-common/lists/string_list.o \
libretro-common/lists/dir_list.o \
libretro-common/file/retro_dirent.o \
libretro-common/compat/compat_strl.o \
libretro-common/file/config_file.o \
libretro-common/streams/file_stream.o \
libretro-common/vfs/vfs_implementation.o \
libretro-common/hash/rhash.o \
file_path_str.o \
verbosity.o
OBJ += ctr/exec-3dsx/exec_cia.o \
ctr/exec-3dsx/exec_3dsx.o \
ctr/exec-3dsx/mini-hb-menu/launch.o \
ctr/exec-3dsx/mini-hb-menu/loaders/rosalina.o \
ctr/exec-3dsx/mini-hb-menu/loaders/hax2.o \
ctr/exec-3dsx/mini-hb-menu/loaders/ninjhax1.o
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitpro")
endif
ifeq ($(strip $(CTRULIB)),)
CTRULIB = $(DEVKITPRO)/libctru
endif
APP_TITLE := $(shell echo "$(APP_TITLE)" | cut -c1-128)
APP_DESCRIPTION := $(shell echo "$(APP_DESCRIPTION)" | cut -c1-256)
APP_AUTHOR := $(shell echo "$(APP_AUTHOR)" | cut -c1-128)
APP_PRODUCT_CODE := $(shell echo $(APP_PRODUCT_CODE) | cut -c1-16)
APP_UNIQUE_ID := $(shell echo $(APP_UNIQUE_ID) | cut -c1-7)
MAKEROM_ARGS_COMMON = -rsf $(APP_RSF) -exefslogo -elf $(TARGET).elf -icon $(TARGET).icn -banner $(TARGET).bnr -DAPP_TITLE="$(APP_TITLE)" -DAPP_PRODUCT_CODE="$(APP_PRODUCT_CODE)" -DAPP_UNIQUE_ID=$(APP_UNIQUE_ID) -DAPP_SYSTEM_MODE=$(APP_SYSTEM_MODE) -DAPP_SYSTEM_MODE_EXT=$(APP_SYSTEM_MODE_EXT)
INCDIRS := -I$(CTRULIB)/include
LIBDIRS := -L. -L$(CTRULIB)/lib
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
CFLAGS += -mword-relocations \
-fomit-frame-pointer -ffast-math \
-Werror=implicit-function-declaration \
$(ARCH)
#CFLAGS += -Wall
CFLAGS += -DARM11 -D_3DS
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
CFLAGS += -I. -Ideps/libz -Ideps/7zip -Ideps/stb -Ilibretro-common/include
#CFLAGS += -DRARCH_INTERNAL
CFLAGS += -DRARCH_CONSOLE -DIS_SALAMANDER
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) -O3
LDFLAGS += -specs=ctr/3dsx_custom.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
CFLAGS += -std=gnu99 -ffast-math
LIBS := -lctru -lm
ifeq ($(BUILD_3DSX), 1)
TARGET_3DSX := $(TARGET).3dsx $(TARGET).smdh
endif
ifeq ($(BUILD_3DS), 1)
TARGET_3DS := $(TARGET).3ds
endif
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)
PREFIX := $(DEVKITARM)/bin/arm-none-eabi-
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
AS := $(PREFIX)as
AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
ifeq ($(strip $(CTRBANNERTOOL)),)
ifneq ($(findstring Linux,$(shell uname)),)
BANNERTOOL = pkg/ctr/tools/bannertool-linux
else ifneq ($(findstring Darwin,$(shell uname)),)
BANNERTOOL = pkg/ctr/tools/bannertool-mac
else
BANNERTOOL = pkg/ctr/tools/bannertool.exe
endif
else
BANNERTOOL = $(CTRBANNERTOOL)
endif
ifeq ($(strip $(CTRMAKEROM)),)
ifneq ($(findstring Linux,$(shell uname)),)
MAKEROM = pkg/ctr/tools/makerom-linux
else ifneq ($(findstring Darwin,$(shell uname)),)
MAKEROM = pkg/ctr/tools/makerom-mac
else
MAKEROM = pkg/ctr/tools/makerom.exe
endif
else
MAKEROM = $(CTRMAKEROM)
endif
%.o: %.vsh %.gsh
$(DEVKITARM)/bin/picasso $^ -o $*.shbin
$(DEVKITARM)/bin/bin2s $*.shbin | $(PREFIX)as -o $@
rm $*.shbin
%.o: %.vsh
$(DEVKITARM)/bin/picasso $^ -o $*.shbin
$(DEVKITARM)/bin/bin2s $*.shbin | $(PREFIX)as -o $@
rm $*.shbin
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
%.o: %.s
$(CC) -c -o $@ $< $(ASFLAGS)
%.o: %.S
$(CC) -c -o $@ $< $(ASFLAGS)
%.a:
$(AR) -rc $@ $^
%.vsh:
$(TARGET).smdh: $(APP_ICON)
$(DEVKITARM)/bin/smdhtool --create "$(APP_TITLE)" "$(APP_DESCRIPTION)" "$(APP_AUTHOR)" $(APP_ICON) $@
$(TARGET).3dsx: $(TARGET).elf
ifeq ($(APP_BIG_TEXT_SECTION), 1)
cp pkg/ctr/big_text_section.xml $(TARGET).xml
else
rm -f $(TARGET).xml
endif
$(DEVKITARM)/bin/3dsxtool $< $@ $(_3DSXFLAGS)
$(TARGET).elf: ctr/3dsx_custom_crt0.o
$(LD) $(LDFLAGS) $(OBJ) $(LIBDIRS) $(LIBS) -o $@
$(NM) -CSn $@ > $(notdir $*.lst)
$(TARGET).bnr: $(APP_BANNER) $(APP_AUDIO)
$(BANNERTOOL) makebanner -i "$(APP_BANNER)" -a "$(APP_AUDIO)" -o $@
$(TARGET).icn: $(APP_ICON)
$(BANNERTOOL) makesmdh -s "$(APP_TITLE)" -l "$(APP_TITLE)" -p "$(APP_AUTHOR)" -i $(APP_ICON) -o $@
$(TARGET).3ds: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
$(MAKEROM) -f cci -o $@ $(MAKEROM_ARGS_COMMON) -DAPP_ENCRYPTED=true
$(TARGET).cia: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
$(MAKEROM) -f cia -o $@ $(MAKEROM_ARGS_COMMON) -DAPP_ENCRYPTED=false
clean:
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

View File

@ -1,108 +0,0 @@
TARGET := retroarch.js
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 -s USE_PTHREADS=$(PTHREAD)
DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_GLSL -DHAVE_FILTERS_BUILTIN -DHAVE_STB_FONT
HAVE_OVERLAY = 1
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_WIDGETS = 1
HAVE_RGUI = 1
HAVE_SDL = 0
HAVE_SDL2 = 0
HAVE_ZLIB = 1
WANT_ZLIB = 0
HAVE_SHADERPIPELINE = 1
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
MEMORY = 536870912
HAVE_STB_FONT = 1
PRECISE_F32 = 1
OBJDIR := obj-emscripten
ifneq ($(NATIVE_ZLIB),)
WANT_ZLIB = 0
endif
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
LIBS := -s USE_ZLIB=1
LDFLAGS := -L. --no-heap-copy -s USE_ZLIB=1 -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s BINARYEN_TRAP_MODE=\"clamp\" \
-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
ifneq ($(PTHREAD), 0)
LDFLAGS += -s USE_PTHREADS=$(PTHREAD) -s PTHREAD_POOL_SIZE=2
endif
ifeq ($(ASYNC), 1)
LDFLAGS += -s ASYNCIFY=$(ASYNC)
endif
ifeq ($(HAVE_SDL2), 1)
LIBS += -s USE_SDL=2
DEFINES += -DHAVE_SDL2
endif
include Makefile.common
CFLAGS += $(DEF_FLAGS) -Ideps/libz -Ideps -Ideps/stb
libretro = libretro_emscripten.bc
ifneq ($(V), 1)
Q := @
endif
ifeq ($(DEBUG), 1)
LDFLAGS += -O0 -g
CFLAGS += -O0 -g
else
LDFLAGS += -O2 -s WASM=1
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
LDFLAGS += -s PRECISE_F32=$(PRECISE_F32)
ifeq ($(LTO), 1)
LDFLAGS += --llvm-lto 3
endif
CFLAGS += -O2
endif
CFLAGS += -DHAVE_RPNG -Wall -I. -Ilibretro-common/include -std=gnu99 -s USE_ZLIB=1 \
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
all: $(TARGET)
$(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) $(EOPTS) -c -o $@ $<
$(OBJDIR)/%.o: %.cpp
@mkdir -p $(dir $@)
@$(if $(Q), $(shell echo echo CXX $<),)
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) $(EOPTS) -c -o $@ $<
clean:
rm -rf $(OBJDIR)
rm -f $(TARGET)
.PHONY: all clean

File diff suppressed because it is too large Load Diff

View File

@ -1,254 +0,0 @@
include version.all
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
TARGET := retroarch_switch
DEBUG ?= 0
WHOLE_ARCHIVE_LINK = 0
GRIFFIN_BUILD = 0
OBJ :=
DEFINES := -D__SWITCH__=1 -U__linux__ -U__linux -DGLM_FORCE_PURE=1 -DRARCH_CONSOLE -DRARCH_INTERNAL -DGLOBAL_CONFIG_DIR='"/switch"' -DHAVE_STB_VORBIS
HAVE_CC_RESAMPLER = 1
HAVE_MENU_COMMON = 1
HAVE_RTGA = 1
HAVE_RPNG = 1
HAVE_RJPEG = 1
HAVE_RBMP = 1
HAVE_ZLIB = 1
HAVE_BUILTINZLIB = 1
HAVE_LIBRETRODB = 1
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
HAVE_MENU = 1
HAVE_RUNAHEAD = 1
HAVE_NETWORKING = 1
HAVE_NETPLAYDISCOVERY = 1
HAVE_STB_FONT = 1
HAVE_CHEEVOS = 1
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
HAVE_STB_VORBIS = 1
# RetroArch libnx useful flags
HAVE_THREADS = 1
HAVE_PTHREADS = 1
HAVE_FREETYPE = 0
HAVE_SWITCH = 1
HAVE_LIBNX = 1
HAVE_OPENGL = 1
HAVE_LANGEXTRA = 1
HAVE_MENU_WIDGETS = 1
ifeq ($(HAVE_OPENGL), 1)
HAVE_EGL = 1
HAVE_SHADERPIPELINE = 1
HAVE_RGUI = 1
HAVE_MATERIALUI = 1
HAVE_XMB = 1
HAVE_OZONE = 1
HAVE_OVERLAY = 1
HAVE_VIDEO_LAYOUT = 0
else
HAVE_RGUI = 1
HAVE_MATERIALUI = 0
HAVE_XMB = 0
HAVE_OZONE = 0
HAVE_STRIPES = 0
endif
include Makefile.common
BLACKLIST :=
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
#
# NO_ICON: if set to anything, do not use icon.
# NO_NACP: if set to anything, no .nacp file is generated.
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
# ICON is the filename of the icon (.jpg), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.jpg
# - icon.jpg
# - <libnx folder>/default_icon.jpg
#---------------------------------------------------------------------------------
BUILD := build
SOURCES := $(CURDIR)/source
DATA := data
INCLUDES := include
EXEFS_SRC := exefs_src
#ROMFS := switch/romfs
APP_TITLE := RetroArch
APP_VERSION := $(RARCH_VERSION)
APP_AUTHOR := libretro Team
APP_ICON := pkg/libnx/retroarch.jpg
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -mcpu=cortex-a57+crc+fp+simd
CFLAGS := -g -Wall -O3 -ffast-math -ffunction-sections \
$(ARCH) $(DEFINES) -Ideps -Ideps/libz -Ilibretro-common/include -Ilibretro-common/include/compat/zlib -Ideps/stb -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_UPDATE_ASSETS -DHAVE_STB_FONT #-DHAVE_FREETYPE
ifeq ($(strip $(HAVE_STATIC_DUMMY)),1)
CFLAGS += -DHAVE_STATIC_DUMMY=1
endif
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs $(ARCH) -Wl,--allow-multiple-definition -Wl,-Map,$(notdir $*.map)
LIBS := -lswresample -lavformat -lavcodec -lavutil -lswscale -lstdc++ -lbz2 -lpng -lz -lnx -lm
ifeq ($(HAVE_OPENGL), 1)
LIBS := -lEGL -lglapi -ldrm_nouveau $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(OBJ)
ifeq ($(strip $(HAVE_STATIC_DUMMY)),)
OFILES += libretro_libnx.a
endif
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.jpg)
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
else
ifneq (,$(findstring icon.jpg,$(icons)))
export APP_ICON := $(TOPDIR)/icon.jpg
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif
ifeq ($(strip $(NO_ICON)),)
export NROFLAGS += --icon=$(APP_ICON)
endif
ifeq ($(strip $(NO_NACP)),)
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
endif
ifneq ($(APP_TITLEID),)
export NACPFLAGS += --titleid=$(APP_TITLEID)
endif
ifneq ($(ROMFS),)
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
endif
DEPENDS_TMP := $(OFILES:.o=.d)
DEPENDS := $(filter-out libretro_libnx.a,$(DEPENDS_TMP))
.PHONY: clean all
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT).pfs0 $(OUTPUT).nro
$(OUTPUT).pfs0 : $(OUTPUT).nso
$(OUTPUT).nso : $(OUTPUT).elf
ifeq ($(strip $(NO_NACP)),)
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
else
$(OUTPUT).nro : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OBJ)
clean:
rm -f $(DEPENDS) $(OBJ) $(OUTPUT).pfs0 $(OUTPUT).nro $(OUTPUT).elf
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -1,354 +0,0 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro")
endif
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
export PATH := $(DEVKITPPC)/bin:$(PATH)
ifeq ($(PLATFORM),)
PLATFORM=wii
endif
#---------------------------------------------------------------------------------
# change shell on Snow Leopard
#---------------------------------------------------------------------------------
UNAME_S := $(shell uname -s)
UNAME_R := $(shell uname -r)
ifneq (,$(findstring Darwin,$(UNAME_S)))
ifneq (,$(findstring 10.8.0,$(UNAME_R)))
export SHELL=/bin/bash
endif
endif
#---------------------------------------------------------------------------------
# path to tools
#---------------------------------------------------------------------------------
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
#---------------------------------------------------------------------------------
# the prefix on the compiler executables
#---------------------------------------------------------------------------------
PREFIX := powerpc-eabi-
export AS := $(PREFIX)as
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
ISVC=$(or $(VCBUILDHELPER_COMMAND),$(MSBUILDEXTENSIONSPATH32),$(MSBUILDEXTENSIONSPATH))
#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
@rm -f $@
$(AR) -rc $@ $^
#---------------------------------------------------------------------------------
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
%.o: %.m
$(CC) $(OBJCFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
%.o: %.s
$(CC) -x assembler-with-cpp $(ASFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
%.o: %.S
$(CC) -x assembler-with-cpp $(ASFLAGS) -c $< -o $@
#---------------------------------------------------------------------------------
# canned command sequence for binary data
#---------------------------------------------------------------------------------
define bin2o
bin2s -a 32 $< | $(AS) -o $(@)
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(<F) | tr . _)`.h
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(<F) | tr . _)`.h
endef
BUILD := build
BUILD_LITE = 1
CURDIR = .
export BASEDIR := $(CURDIR)
export DEPSDIR := $(BASEDIR)/wii/libogc/deps
export LWIPDIR := $(BASEDIR)/wii/libogc/lwip
export OGCDIR := $(BASEDIR)/wii/libogc/libogc
export DBDIR := $(BASEDIR)/wii/libogc/libdb
export BTEDIR := $(BASEDIR)/wii/libogc/lwbt
export WIIUSEDIR := $(BASEDIR)/wii/libogc/wiiuse
export LIBWIIKEYB := $(BASEDIR)/wii/libogc/libwiikeyboard
export STUBSDIR := $(BASEDIR)/wii/libogc/lockstubs
export LIBS := $(BASEDIR)/wii/libogc/libs
export INCDIR := $(BASEDIR)/wii/libogc/include
export LIBDIR := $(LIBS)/$(PLATFORM)
#---------------------------------------------------------------------------------
BBALIB := $(LIBDIR)/libbba
OGCLIB := $(LIBDIR)/libogc
DBLIB := $(LIBDIR)/libdb
BTELIB := $(LIBDIR)/libbte
WIIUSELIB := $(LIBDIR)/libwiiuse
WIIKEYBLIB := $(LIBDIR)/libwiikeyboard
STUBSLIB := $(LIBDIR)/libgclibstubs
#---------------------------------------------------------------------------------
DEFAULTINCDIR := $(BASEDIR)/wii/libogc/include
DEFINCS := -I$(DEFAULTINCDIR)
INCLUDES := $(DEFINCS) \
-I$(BASEDIR)/wii/libogc \
-I$(DEFAULTINCDIR)/netif \
-I$(DEFAULTINCDIR)/ipv4 \
-I$(DEFAULTINCDIR)/sdcard \
-I$(DEFAULTINCDIR)/ogc \
-I$(DEFAULTINCDIR)/ogc/machine \
-I$(DEFAULTINCDIR)/bte \
-I$(DEFAULTINCDIR)/sdcard \
-I$(DEFAULTINCDIR)/wiikeyboard \
-I$(DEFAULTINCDIR)/wiiuse \
-I$(DEFAULTINCDIR)/di
MACHDEP := -DBIGENDIAN -DGEKKO -mcpu=750 -meabi -msdata=eabi -mhard-float -ffunction-sections -fdata-sections
ifeq ($(PLATFORM),wii)
MACHDEP += -DHW_RVL
endif
ifeq ($(PLATFORM),cube)
MACHDEP += -DHW_DOL
endif
CFLAGS := -DLIBOGC_INTERNAL -DNDEBUG -O2 -fno-strict-aliasing -mregnames -Wall $(MACHDEP) $(INCLUDES)
ASFLAGS := $(MACHDEP) -mregnames -D_LANGUAGE_ASSEMBLY $(INCLUDES)
#---------------------------------------------------------------------------------
VPATH := $(LWIPDIR) \
$(LWIPDIR)/arch/gc \
$(LWIPDIR)/arch/gc/netif \
$(LWIPDIR)/core \
$(LWIPDIR)/core/ipv4 \
$(LWIPDIR)/netif \
$(OGCDIR) \
$(DBDIR) \
$(DBDIR)/uIP \
$(BTEDIR) \
$(WIIUSEDIR) \
$(SDCARDDIR) \
$(LIBWIIKEYB) \
$(STUBSDIR)
#---------------------------------------------------------------------------------
SOURCES_LWIP := $(LWIPDIR)/network.c \
$(LWIPDIR)/netio.c \
$(LWIPDIR)/arch/gc/netif/gcif.c \
$(LWIPDIR)/core/inet.c \
$(LWIPDIR)/core/mem.c \
$(LWIPDIR)/core/dhcp.c \
$(LWIPDIR)/core/raw.c \
$(LWIPDIR)/core/memp.c \
$(LWIPDIR)/core/netif.c \
$(LWIPDIR)/core/pbuf.c \
$(LWIPDIR)/core/stats.c \
$(LWIPDIR)/core/sys.c \
$(LWIPDIR)/core/tcp.c \
$(LWIPDIR)/core/tcp_in.c \
$(LWIPDIR)/core/tcp_out.c \
$(LWIPDIR)/core/udp.c \
$(LWIPDIR)/core/ipv4/icmp.c \
$(LWIPDIR)/core/ipv4/ip.c \
$(LWIPDIR)/core/ipv4/ip_frag.c \
$(LWIPDIR)/core/ipv4/ip_addr.c \
$(LWIPDIR)/netif/etharp.c \
$(LWIPDIR)/netif/loopif.c
LWIPOBJ := $(SOURCES_LWIP:.c=.o)
#---------------------------------------------------------------------------------
SOURCES_OGC := \
$(OGCDIR)/console.c \
$(OGCDIR)/lwp_priority.c \
$(OGCDIR)/lwp_queue.c \
$(OGCDIR)/lwp_threadq.c \
$(OGCDIR)/lwp_threads.c \
$(OGCDIR)/lwp_sema.c \
$(OGCDIR)/lwp_messages.c \
$(OGCDIR)/lwp.c \
$(OGCDIR)/lwp_stack.c \
$(OGCDIR)/lwp_mutex.c \
$(OGCDIR)/lwp_watchdog.c \
$(OGCDIR)/lwp_wkspace.c \
$(OGCDIR)/lwp_objmgr.c \
$(OGCDIR)/lwp_heap.c \
$(OGCDIR)/sys_state.c \
$(OGCDIR)/exception.c \
$(OGCDIR)/irq.c \
$(OGCDIR)/semaphore.c \
$(OGCDIR)/video.c \
$(OGCDIR)/pad.c \
$(OGCDIR)/exi.c \
$(OGCDIR)/mutex.c \
$(OGCDIR)/arqueue.c \
$(OGCDIR)/arqmgr.c \
$(OGCDIR)/system.c \
$(OGCDIR)/cond.c \
$(OGCDIR)/gx.c \
$(OGCDIR)/gu.c \
$(OGCDIR)/audio.c \
$(OGCDIR)/cache.c \
$(OGCDIR)/decrementer.c \
$(OGCDIR)/message.c \
$(OGCDIR)/card.c \
$(OGCDIR)/aram.c \
$(OGCDIR)/depackrnc1.c \
$(OGCDIR)/dsp.c \
$(OGCDIR)/si.c \
$(OGCDIR)/tpl.c \
$(OGCDIR)/ipc.c \
$(OGCDIR)/console_font_8x16.c \
$(OGCDIR)/timesupp.c \
$(OGCDIR)/lock_supp.c \
$(OGCDIR)/newlibc.c \
$(OGCDIR)/usbgecko.c \
$(OGCDIR)/usbmouse.c \
$(OGCDIR)/sbrk.c \
$(OGCDIR)/malloc_lock.c \
$(OGCDIR)/kprintf.c \
$(OGCDIR)/stm.c \
$(OGCDIR)/ios.c \
$(OGCDIR)/es.c \
$(OGCDIR)/isfs.c \
$(OGCDIR)/usb.c \
$(OGCDIR)/network_common.c \
$(OGCDIR)/sdgecko_io.c \
$(OGCDIR)/sdgecko_buf.c \
$(OGCDIR)/gcsd.c \
$(OGCDIR)/argv.c \
$(OGCDIR)/network_wii.c \
$(OGCDIR)/wiisd.c \
$(OGCDIR)/conf.c \
$(OGCDIR)/usbstorage.c \
$(OGCDIR)/texconv.c \
$(OGCDIR)/wiilaunch.c
SOURCES_OGC_ASM := $(OGCDIR)/cache_asm.S \
$(OGCDIR)/decrementer_handler.S \
$(OGCDIR)/depackrnc.S \
$(OGCDIR)/exception_handler.S \
$(OGCDIR)/gu_psasm.S \
$(OGCDIR)/irq_handler.S \
$(OGCDIR)/lwp_handler.S \
$(OGCDIR)/ogc_crt0.S \
$(OGCDIR)/system_asm.S \
$(OGCDIR)/video_asm.S
ifneq ($(BUILD_LITE), 1)
SOURCES_OGC += $(OGCDIR)/dvd.c
endif
OGCOBJ := $(SOURCES_OGC:.c=.o) $(SOURCES_OGC_ASM:.S=.o)
#---------------------------------------------------------------------------------
SOURCES_DB := \
$(DBDIR)/uIP/uip_ip.c \
$(DBDIR)/uIP/uip_tcp.c \
$(DBDIR)/uIP/uip_pbuf.c \
$(DBDIR)/uIP/uip_netif.c \
$(DBDIR)/uIP/uip_arp.c \
$(DBDIR)/uIP/uip_arch.c \
$(DBDIR)/uIP/uip_icmp.c \
$(DBDIR)/uIP/memb.c \
$(DBDIR)/uIP/memr.c \
$(DBDIR)/uIP/bba.c \
$(DBDIR)/tcpip.c \
$(DBDIR)/debug.c \
$(DBDIR)/debug_handler.c \
$(DBDIR)/debug_supp.c \
$(DBDIR)/geckousb.c
DBOBJ := $(SOURCES_DB:.c=.o)
#---------------------------------------------------------------------------------
SOURCES_BTE := \
$(BTEDIR)/bte.c \
$(BTEDIR)/hci.c \
$(BTEDIR)/l2cap.c \
$(BTEDIR)/btmemb.c \
$(BTEDIR)/btmemr.c \
$(BTEDIR)/btpbuf.c \
$(BTEDIR)/physbusif.c
BTEOBJ := $(SOURCES_BTE:.c=.o)
#---------------------------------------------------------------------------------
SOURCES_WIIUSE := \
$(WIIUSEDIR)/classic.c \
$(WIIUSEDIR)/dynamics.c \
$(WIIUSEDIR)/events.c \
$(WIIUSEDIR)/io.c \
$(WIIUSEDIR)/io_wii.c \
$(WIIUSEDIR)/ir.c \
$(WIIUSEDIR)/nunchuk.c \
$(WIIUSEDIR)/wiiuse.c \
$(WIIUSEDIR)/speaker.c \
$(WIIUSEDIR)/wpad.c \
$(WIIUSEDIR)/motion_plus.c
WIIUSEOBJ := $(SOURCES_WIIUSE:.c=.o)
#---------------------------------------------------------------------------------
SOURCES_WIIKEYB = $(LIBWIIKEYB)/usbkeyboard.c \
$(LIBWIIKEYB)/keyboard.c \
$(LIBWIIKEYB)/ukbdmap.c \
$(LIBWIIKEYB)/wskbdutil.c
WIIKEYBLIBOBJ := $(SOURCES_WIIKEYB:.c=.o)
LIBRARIES := $(OGCLIB).a $(DBLIB).a
ifeq ($(PLATFORM),cube)
LIBRARIES += $(BBALIB).a
endif
ifeq ($(PLATFORM),wii)
LIBRARIES += $(BTELIB).a $(WIIUSELIB).a $(WIIKEYBLIB).a
endif
all: $(LIBRARIES)
#---------------------------------------------------------------------------------
$(BBALIB).a: $(LWIPOBJ)
#---------------------------------------------------------------------------------
$(OGCLIB).a: $(OGCOBJ)
#---------------------------------------------------------------------------------
$(DBLIB).a: $(DBOBJ)
#---------------------------------------------------------------------------------
$(WIIKEYBLIB).a: $(WIIKEYBLIBOBJ)
#---------------------------------------------------------------------------------
$(BTELIB).a: $(BTEOBJ)
#---------------------------------------------------------------------------------
$(WIIUSELIB).a: $(WIIUSEOBJ)
#---------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
clean:
#---------------------------------------------------------------------------------
rm -fr $(LWIPOBJ) $(OGCOBJ) $(DBOBJ) $(BTEOBJ) $(WIIUSEOBJ) $(WIIKEYBLIBOBJ)
rm -f *.map

View File

@ -1,281 +0,0 @@
TARGET := retroarch.exe
DEBUG = 0
GRIFFIN_BUILD = 0
OS = Win32
ARCH = amd64
#TARGET_ARCH = x86
BUILD_DIR = objs/msvc
CXX_BUILD = 0
WindowsSdkDir = C:\Program Files (x86)\Windows Kits\10\$(NOTHING)
WindowsSDKVersion := 10.0.14393.0\$(NOTHING)
VCINSTALLDIR := C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\$(NOTHING)
HAVE_D3DX := 1
HAVE_D3D8 := 0
HAVE_D3D9 := 1
HAVE_D3D10 := 1
HAVE_D3D11 := 1
HAVE_D3D12 := 1
HAVE_CG := 1
HAVE_OPENGL := 1
HAVE_OPENGL1 := 1
HAVE_MENU_WIDGETS := 1
HAVE_VULKAN := 1
HAVE_XAUDIO := 1
HAVE_XINPUT := 1
HAVE_WASAPI := 0
HAVE_THREAD_STORAGE := 1
HAVE_WINMM := 1
HAVE_RPNG := 1
HAVE_ZLIB := 1
WANT_ZLIB := 1
HAVE_MENU := 1
HAVE_RGUI := 1
HAVE_XMB := 1
HAVE_MATERIALUI := 1
HAVE_STB_FONT := 1
HAVE_THREADS := 1
HAVE_LIBRETRODB := 1
HAVE_COMMAND := 1
HAVE_STDIN_CMD := 1
HAVE_CMD := 1
HAVE_DYLIB := 1
HAVE_DYNAMIC := 1
HAVE_DINPUT := 1
HAVE_MENU_COMMON := 1
HAVE_BUILTINZLIB := 1
HAVE_RJPEG := 1
HAVE_RBMP := 1
HAVE_RTGA := 1
HAVE_7ZIP := 1
HAVE_NETWORKING := 1
HAVE_NETWORK_CMD := 1
HAVE_OVERLAY := 1
HAVE_VIDEO_LAYOUT := 0
HAVE_LANGEXTRA := 1
HAVE_CHEEVOS := 1
HAVE_SHADERPIPELINE := 1
HAVE_IMAGEVIEWER := 1
ifeq ($(HAVE_D3D8), 1)
D3D8_LIBS := -ld3d8
ifeq ($(HAVE_D3DX), 1)
D3DX8_LIBS := -ld3dx8
endif
endif
ifeq ($(HAVE_D3D9), 1)
D3D9_LIBS := -ld3d9
ifeq ($(HAVE_D3DX), 1)
D3DX9_LIBS := -ld3dx9
endif
endif
include Makefile.common
INCLUDE_DIRS := $(patsubst -isystem%,-I%,$(INCLUDE_DIRS))
CFLAGS := $(filter-out -Wno-unknown-pragmas,$(DEF_FLAGS))
CXXFLAGS := $(filter-out -fpermissive -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses,$(CXXFLAGS))
LIBS := $(filter-out -lstdc++,$(LIBS))
ifeq ($(ARCH),x64)
ARCH := amd64
endif
ARCH2 := $(ARCH)
ifeq ($(ARCH),amd64)
ARCH2 := x64
endif
ifeq ($(TARGET_ARCH),)
TARGET_ARCH = $(ARCH)
endif
ifeq ($(TARGET_ARCH),x64)
TARGET_ARCH = amd64
endif
TARGET_ARCH2 = $(TARGET_ARCH)
ifeq ($(TARGET_ARCH2),amd64)
TARGET_ARCH2 = x64
endif
CROSS = $(ARCH)
ifeq ($(ARCH),x86)
CROSS =
endif
INCLUDE := $(VCINSTALLDIR)include;$(VCINSTALLDIR)atlmfc\include;$(WindowsSdkDir)include\$(WindowsSDKVersion)ucrt;$(WindowsSdkDir)include\$(WindowsSDKVersion)shared;$(WindowsSdkDir)include\$(WindowsSDKVersion)um;
LIB := $(VCINSTALLDIR)LIB\$(CROSS);$(VCINSTALLDIR)atlmfc\lib\$(CROSS);$(WindowsSdkDir)lib\$(WindowsSDKVersion)ucrt\$(TARGET_ARCH2);$(WindowsSdkDir)lib\$(WindowsSDKVersion)um\$(TARGET_ARCH2);C:\Program Files (x86)\NVIDIA Corporation\Cg\lib.$(TARGET_ARCH2);C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Lib\$(TARGET_ARCH2);
LIBPATH := $(VCINSTALLDIR)LIB\$(CROSS);$(VCINSTALLDIR)atlmfc\lib\$(CROSS);
PATH := $(shell IFS=$$'\n'; cygpath "$(VCINSTALLDIR)bin\\$(CROSS)"):$(shell IFS=$$'\n'; cygpath "$(WindowsSdkDir)\bin\\$(ARCH2)"):$(PATH)
export INCLUDE := $(INCLUDE)
export LIB := $(LIB)
export LIBPATH := $(LIBPATH)
export PATH := $(PATH)
#$(info WindowsSdkDir : $(WindowsSdkDir))
#$(info WindowsSDKVersion : $(WindowsSDKVersion))
#$(info VCINSTALLDIR : $(VCINSTALLDIR))
#$(info INCLUDE : $(INCLUDE))
#$(info LIB : $(LIB))
#$(info LIBPATH : $(LIBPATH))
#$(info PATH : $(PATH))
#$(error end)
DEFINES += -D__SSE__ -D__SSE2__
ifeq ($(TARGET_ARCH2),x64)
DEFINES += -D__x86_64__
else
#DEFINES += -D__i686__
endif
FLAGS += -nologo -MP
FLAGS += -Gm- -Zc:inline -fp:precise -Zc:forScope -GR- -Gd -Oi -volatile:iso
#FLAGS += -Zc:wchar_t -Zp16 -Z7
FLAGS += -utf-8
#FLAGS += -source-charset:utf-8
CXXFLAGS += $(CFLAGS) -TP -EHsc
ifeq ($(CXX_BUILD),1)
CFLAGS := $(CXXFLAGS)
DEFINES += -DCXX_BUILD
else
CFLAGS += -TC
endif
WARNINGS += -WX -W3
WARNINGS += -wd4101 -wd4996 -wd4244 -wd4267 -wd4090 -wd4305 -wd4146 -wd4334 -wd4018 -wd4800 -wd4838
CC = cl.exe
CXX = cl.exe
LD = link.exe
RC = rc.exe
LIBS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib
LDFLAGS += -nologo -wx -nxcompat -machine:$(TARGET_ARCH2)
ifeq ($(DEBUG),1)
FLAGS += -GS -Gy -Od -RTC1 -D_SECURE_SCL=1 -Zi
FLAGS += -MDd
LDFLAGS += -DEBUG
DEFINES += -DDEBUG -D_DEBUG
else
FLAGS += -GS- -Gy- -O2 -Ob2 -GF -GT -Oy -Ot -D_SECURE_SCL=0
FLAGS += -MD
endif
ifeq ($(DEBUG),1)
BUILD_DIR := $(BUILD_DIR)-debug
endif
ifeq ($(GRIFFIN_BUILD),1)
BUILD_DIR := $(BUILD_DIR)-griffin
endif
BUILD_DIR := $(BUILD_DIR)-$(TARGET_ARCH2)
ifneq ($(V), 1)
Q := @
endif
ifeq ($(GRIFFIN_BUILD), 1)
OBJ := griffin/griffin.o griffin/griffin_cpp.o
DEFINES += -DHAVE_GRIFFIN -DUSE_MATH_DEFINES
else
BLACKLIST :=
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
endif
DEFINES += -DRARCH_INTERNAL -DHAVE_DYNAMIC -DJSON_STATIC
INCLUDE_DIRS += -I. -Igfx/include
#OBJ := version_git.o
OBJ := $(patsubst %rarch.o,%rarch.res,$(OBJ))
OBJ := $(addprefix $(BUILD_DIR)/,$(OBJ))
OBJ := $(OBJ:.o=.obj)
LDFLAGS += -WX -SUBSYSTEM:WINDOWS -ENTRY:mainCRTStartup
DEFINES := $(patsubst -f%,,$(DEFINES))
LDFLAGS := $(patsubst -l%,%.lib,$(LDFLAGS))
LIBS := $(filter-out -lm,$(LIBS))
LIBS := $(patsubst -l%,%.lib,$(LIBS))
#$(info INCLUDE_DIRS : $(INCLUDE_DIRS))
#$(info DEFINES : $(DEFINES))
#$(info CFLAGS : $(CFLAGS))
#$(info CXXFLAGS : $(CXXFLAGS))
#$(info LDFLAGS : $(LDFLAGS))
#$(info LIBS : $(LIBS))
#$(info OBJ : $(OBJ))
#$(info target : $(TARGET))
#$(info flags : $(FLAGS))
#$(info INCLUDE : $(INCLUDE))
#$(info LIB : $(LIB))
#$(info LIBPATH : $(LIBPATH))
#$(error end)
$(info os : $(OS))
$(info host : $(ARCH))
$(info target : $(TARGET_ARCH))
all: $(TARGET)
%: $(BUILD_DIR)/%
cp $< $@
ifeq ($(DEBUG),1)
%.exe: $(BUILD_DIR)/%.exe
cp $< $@
cp $(BUILD_DIR)/$*.pdb $*.pbd
endif
SHELL:=$(SHELL) -o pipefail
DEPFLAGS = -showIncludes | tee $(BUILD_DIR)/$*.dtemp | sed /'Note: including file:'/d
MAKEDEPS = echo $@: $< \\ > $(BUILD_DIR)/$*.depend && \
grep 'Note: including file:' $(BUILD_DIR)/$*.dtemp \
| sed '/$(subst \,\\,$(WindowsSdkDir))/Id; /$(subst \,\\,$(VCINSTALLDIR))/Id; s/Note: including file:[ ]*//g; s/\\/\//g; s/ /\\ /g; s/.*/ & \\/g' \
>> $(BUILD_DIR)/$*.depend && \
rm -f $(BUILD_DIR)/$*.dtemp
#DEPFLAGS :=
#MAKEDEPS :=
$(BUILD_DIR)/%.obj: %.cpp
@mkdir -p $(dir $@)
$(Q)$(CXX) -c -Fo:$@ $< $(FLAGS) $(CXXFLAGS) $(DEFINES) $(INCLUDE_DIRS) $(WARNINGS) $(DEPFLAGS)
@$(MAKEDEPS)
$(BUILD_DIR)/%.obj: %.c
@mkdir -p $(dir $@)
$(Q)$(CC) -c -Fo:$@ $< $(FLAGS) $(CFLAGS) $(DEFINES) $(INCLUDE_DIRS) $(WARNINGS) $(DEPFLAGS)
@$(MAKEDEPS)
$(BUILD_DIR)/%.res: %.rc
@mkdir -p $(dir $@)
$(Q)$(RC) $<
$(Q)mv $*.res $@
$(BUILD_DIR)/$(TARGET): $(OBJ) .$(TARGET).last
@touch .$(TARGET).last
$(Q)$(LD) $(OBJ) $(LDFLAGS) $(LIBS) -out:$(BUILD_DIR)/$(TARGET)
%.h %.hpp %.depend %.last: ;
clean:
rm -f $(OBJ) $(TARGET)
rm -f $(BUILD_DIR)/$(TARGET)
rm -f .$(TARGET).last
rm -f $(OBJ:.obj=.depend)
.PHONY: clean all
.PRECIOUS: %.depend %.last
-include $(patsubst %.obj,%.depend,$(filter %.obj,$(OBJ)))

View File

@ -1,46 +0,0 @@
include version.all
DEBUG = 0
CC = $(PNDSDK)/bin/arm-none-linux-gnueabi-gcc
LD = $(PNDSDK)/bin/arm-none-linux-gnueabi-gcc -o
TARGET := retroarch-pandora
LDDIRS = -L. -L$(PNDSDK)/usr/lib
INCDIRS = -I. -I$(PNDSDK)/usr/include
OBJ = griffin/griffin.o audio/resamplers/sinc_resampler_neon.o libretro-common/conversion/s16_to_float_neon.o libretro-common/conversion/float_to_s16_neon.o
LDFLAGS = -L$(PNDSDK)/usr/lib -Wl,-rpath,$(PNDSDK)/usr/lib
LIBS = -lGLESv2 -lEGL -ldl -lm -lpthread -lrt -lasound
DEFINES = -std=gnu99 -DHAVE_THREADS -DHAVE_GETOPT_LONG=1 -DHAVE_GRIFFIN -DRARCH_INTERNAL
DEFINES += -D__ARM_ARCH_6__ -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_GLSL -DHAVE_DYNAMIC -DHAVE_RPNG -DHAVE_RJPEG -DWANT_ZLIB -DHAVE_OVERLAY -DHAVE_VIDEO_LAYOUT -DHAVE_ALSA -DHAVE_ZLIB -D__linux__
DEFINES += $(INCDIRS)
DEFINES += -D__OPENPANDORA__ -DPANDORA
DEFINES += -marm -march=armv7-a -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize
ifeq ($(DEBUG), 1)
OPTIMIZE_LV := -O0 -g
else
OPTIMIZE_LV := -O3
endif
all: $(TARGET)
CFLAGS := $(OPTIMIZE_LV) $(DEFINES)
$(TARGET): $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LDDIRS) $(LIBS)
%.o: %.S
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.c config.h
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(TARGET)
rm -f $(OBJ)
.PHONY: clean

View File

@ -1,168 +0,0 @@
TARGET := retroarch_orbis
DEBUG ?= 0
GRIFFIN_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
PS4_TITLE_ID := RETROARCH
PS4_TITLE_NAME := RetroArch
PC_DEVELOPMENT_IP_ADDRESS =
PC_DEVELOPMENT_UDP_PORT =
OBJ :=
DEFINES :=
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1
DEFINES += -DHAVE_MENU -DHAVE_LIBRETRODB
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB -DHAVE_CC_RESAMPLER
ifeq ($(DEBUG), 1)
DEFINES += -DHAVE_NETLOGGER
endif
else
HAVE_FILTERS_BUILTIN := 1
HAVE_LANGEXTRA := 0
HAVE_RPNG := 1
HAVE_RJPEG := 1
HAVE_RBMP := 1
HAVE_RTGA := 1
HAVE_ZLIB := 1
HAVE_OVERLAY := 1
HAVE_VIDEO_LAYOUT := 0
HAVE_7ZIP := 1
HAVE_EGL := 1
HAVE_MENU_WIDGETS := 1
HAVE_OPENGLES := 1
HAVE_NETWORKING := 0
HAVE_SOCKET_LEGACY := 0
HAVE_MENU := 1
HAVE_MENU_COMMON := 1
HAVE_RGUI := 0
HAVE_MATERIALUI := 0
HAVE_XMB := 1
HAVE_THREADS := 1
HAVE_LIBRETRODB := 1
HAVE_CC_RESAMPLER := 1
HAVE_CHEEVOS := 1
RARCH_CONSOLE := 1
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
ifeq ($(DEBUG), 1)
HAVE_NETLOGGER = 1
endif
include Makefile.common
CFLAGS += $(DEF_FLAGS)
BLACKLIST :=
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
OBJ += input/drivers/ps4_input.o
OBJ += input/drivers_joypad/ps4_joypad.o
OBJ += audio/drivers/psp_audio.o
#OBJ += frontend/drivers/platform_orbis.o
endif
ifeq ($(strip $(PS4SDK)),)
$(error "Please set PS4SDK in your environment. export PS4SDK=<path to>ps4sdk")
endif
export PATH := $(PATH):$(PS4SDK)/bin
PREFIX :=
CC := $(PREFIX)clang
CXX := $(PREFIX)clang
AS := $(PREFIX)clang
AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
INCDIRS := -I. -Ideps/libz -Ideps/7zip -Ilibretro-common/include -Ideps/stb -Ilibretro-common/include/compat/zlib
LIBDIRS := -L.
ARCHFLAGS := -m64 -DORBIS
CFLAGS += $(ARCHFLAGS) -std=c11 -mcmodel=large -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector
ifeq ($(DEBUG), 1)
CFLAGS += -O2 -g
else
CFLAGS += -O3
endif
ASFLAGS := $(ARCHFLAGS) -I$(PS4SDK)/include -target x86_64-scei-ps4-elf -fPIE
LDFLAGS := -O3 -Wall -m64 -nostartfiles -nostdlib -L$(PS4SDK)/lib -pie
ARFLAGS := rcs
CRTFILE ?= $(PS4SDK)/crt0.s
CFLAGS += -Wall -pedantic -Wno-zero-length-array -Wno-format-pedantic
CFLAGS += -D__PS4__ -I$(PS4SDK)/include -I $(PS4SDK)/include/sce
CFLAGS += -target x86_64-scei-ps4-elf -fPIE
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
ifneq ($(PC_DEVELOPMENT_IP_ADDRESS),)
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS='"$(PC_DEVELOPMENT_IP_ADDRESS)"'
endif
ifneq ($(PC_DEVELOPMENT_UDP_PORT),)
CFLAGS += -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
CXXFLAGS := $(CFLAGS)
PS4_LIBS := -lps4link -ldebugnet -lorbisFile -lelfloader -lorbisKeyboard -lorbis2d -lpng -lz -lorbisGl -lorbisPad -lorbisAudio -lmod -lorbisFileBrowser -lorbisXbmFont -lSceNet_stub -lScePigletv2VSH_stub -lSceSystemService_stub -lSceUserService_stub -lScePad_stub -lSceAudioOut_stub -lSceIme_stub -lSceSysmodule_stub \
-lPs4_extension_kernel_call_standard -lPs4_extension_kernel_execute_dynlib_prepare_dlclose -lPs4_common_kernel -lPs4_common_user -lPs4_common_generic -lPs4LibCInternalAdaptive_stub -lPs4LibKernelAdaptive_stub -lSceLibcInternal_stub -lkernel_stub -lps4Kernel_stub -lPs4_base_stub_resolve_minimal -lPs4_base_kernel_dlsym_standard -lPs4_base_kernel_seek_elf_address_standard -lPs4_base_assembler_register_parameter_standard -lPs4_base_assembler_system_call_standard
LIBS := $(WHOLE_START) -lretro_orbis $(WHOLE_END) $(PS4_LIBS)
TARGETS := $(TARGET).elf
DEPFLAGS = -MT $@ -MMD -MP -MF $*.Tdepend
POSTCOMPILE = mv -f $*.Tdepend $*.depend
all: $(TARGETS)
%.o: %.cpp
%.o: %.cpp %.depend
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.c
%.o: %.c %.depend
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.S
%.o: %.S %.depend
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.s
%.o: %.s %.depend
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.depend: ;
$(TARGET).elf: $(OBJ) libretro_orbis.a
$(LD) $(CRTFILE) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
clean:
rm -f $(OBJ) $(TARGET).elf
rm -f $(OBJ:.o=.depend)
.PHONY: clean all
.PRECIOUS: %.depend
-include $(OBJ:.o=.depend)

View File

@ -1,54 +0,0 @@
# Before using this Makefile, be sure to do:
# $ source /usr/local/angstrom/arm/environment-setup
# $ setprj retroarch
PNDDIR=./pkg/pandora
BINDIR=$(PNDDIR)/bin
all: $(BINDIR)/retroarch
mkdir -p $(PNDDIR)/lib
@echo "Put libretro-*.so files in $(PNDDIR)/lib/ before making pnd!"
pnd: retroarch.pnd
install: all $(BINDIR)/retroarch-joyconfig $(BINDIR)/retroarch-zip $(PNDDIR)/readme.html
retroarch:
./configure --prefix=$PND_BASEDIR/$PRJ --disable-ffmpeg --disable-cg --disable-python --disable-libpng --disable-pulse --disable-jack --enable-gles --enable-xml
make -f Makefile
$(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
$(PNDDIR)/readme.html: README.md
markdown README.md > $(PNDDIR)/readme.html
retroarch.pnd: install
pnd_make -c -p retroarch.pnd -d $(PNDDIR)/ -x $(PNDDIR)/PXML.xml -i $(PNDDIR)/icon.png
clean:
rm -f *.o
rm -f audio/*.o
rm -f conf/*.o
rm -f gfx/*.o
rm -f gfx/drivers_font/*.o
rm -f gfx/drivers_font_renderer/*.o
rm -f gfx/drivers_context/*.o
rm -f gfx/py_state/*.o
rm -f compat/*.o
rm -f record/*.o
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

View File

@ -1,120 +0,0 @@
BUILD_PRX = 0
DEBUG = 0
HAVE_KERNEL_PRX = 0
HAVE_LOGGER = 0
HAVE_FILE_LOGGER = 0
HAVE_THREADS = 0
BIG_STACK = 0
MUTE_WARNINGS = 1
PS2_IP = 192.168.1.150
TARGET = retroarchps2.elf
TARGET_RELEASE = retroarchps2-release.elf
# Lib CDVD
CDVD_DIR = ps2/libcdvd
# Compile the IRXs first
IRX_DIR = ps2/irx
IRX_FILES = $(wildcard ps2/irx/*.c)
ifeq ($(DEBUG), 1)
OPTIMIZE_LV := -O0 -g
RARCH_DEFINES += -DDEBUG
else
OPTIMIZE_LV := -O2
LDFLAGS := -s
endif
ifeq ($(MUTE_WARNINGS), 1)
DISABLE_WARNINGS := -Wno-sign-compare -Wno-unused -Wno-parentheses
endif
INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include -I$(CDVD_DIR)/ee
INCDIR += -Ips2 -Ips2/include -Ilibretro-common/include -Ilibretro-common/include/compat/zlib
INCDIR += -Ideps -Ideps/stb -Ideps/libz -Ideps/7zip -Ideps/pthreads -Ideps/pthreads/platform/ps2 -Ideps/pthreads/platform/helper
GPVAL = -G0
CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) -ffast-math -fsingle-precision-constant
ASFLAGS = $(CFLAGS)
RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG
RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
LIBDIR =
LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L$(CDVD_DIR)/lib -L.
LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lz
LIBS += -lcdvdfs -lpatches -lpoweroff
ifeq ($(HAVE_THREADS), 1)
RARCH_DEFINES += -DHAVE_THREADS
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
ifeq ($(HAVE_KERNEL_PRX), 1)
CFLAGS += -DHAVE_KERNEL_PRX
endif
ifeq ($(BIG_STACK), 1)
CFLAGS += -DBIG_STACK
endif
CFLAGS += $(RARCH_DEFINES)
# All the IRX objects
EE_OBJS += $(IRX_DIR)/freemtap_irx.o $(IRX_DIR)/freepad_irx.o $(IRX_DIR)/freesio2_irx.o $(IRX_DIR)/iomanX_irx.o
EE_OBJS += $(IRX_DIR)/fileXio_irx.o $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o
EE_OBJS += $(IRX_DIR)/usbhdfsd_irx.o $(IRX_DIR)/freesd_irx.o $(IRX_DIR)/audsrv_irx.o $(IRX_DIR)/poweroff_irx.o
EE_OBJS += $(IRX_DIR)/cdvd_irx.o
# Missing objecst on the PS2SDK
EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o
EE_OBJS += ps2/compat_files/fileXio_cdvd.o ps2/compat_files/ps2_descriptor.o
#EE_OBJS = griffin/griffin.o bootstrap/ps2/kernel_functions.o
EE_OBJS += griffin/griffin.o
EE_CFLAGS = $(CFLAGS)
EE_CXXFLAGS = $(CFLAGS)
EE_LDFLAGS = $(LDFLAGS)
EE_LIBS = $(LIBS)
EE_ASFLAGS = $(ASFLAGS)
EE_INCS = $(INCDIR)
EE_BIN = $(TARGET)
EE_GPVAL = $(GPVAL)
all: irxdir $(EE_BIN)
irxdir:
$(MAKE) -C $(IRX_DIR)
clean:
rm -f $(EE_BIN) $(EE_OBJS)
$(MAKE) -C $(IRX_DIR) clean
prepare:
ps2client -h $(PS2_IP) reset
ps2client -h $(PS2_IP) netdump
run:
ps2client -h $(PS2_IP) execee host:$(EE_BIN)
debug: clean prepare all run
package:
ps2-packer $(EE_BIN) $(TARGET_RELEASE)
release: clean all package
#Include preferences
include $(PS2SDK)/samples/Makefile.pref
include $(PS2SDK)/samples/Makefile.eeglobal
#Linking with C++
$(EE_BIN): $(EE_OBJS) $(PS2SDK)/ee/startup/crt0.o
$(EE_CXX) $(EE_NO_CRT) -T$(PS2SDK)/ee/startup/linkfile $(EE_CXXFLAGS) \
-o $(EE_BIN) $(PS2SDK)/ee/startup/crt0.o $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(EE_OBJS) $(CRTEND_OBJ) $(CRTN_OBJ) $(EE_LDFLAGS) $(EE_LIBS)

View File

@ -1,210 +0,0 @@
include version.all
#which compiler to build with - GCC or SNC
#set to GCC for debug builds for use with debugger
CELL_BUILD_TOOLS = SNC
CELL_GPU_TYPE = RSX
CELL_PSGL_VERSION = opt
ASSETS_DIR := media/assets
# options
DOWNLOAD_SHADERS = 1
STRIPPING_ENABLE = 0
DEBUG = 0
HAVE_GCMGL = 0
HAVE_LOGGER = 0
HAVE_FREETYPE = 0
WHOLE_ARCHIVE_LINK = 0
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
CONTENT_ID = SSNE10000
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
PC_DEVELOPMENT_UDP_PORT = 3490
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
include $(CELL_MK_DIR)/sdk.makedef.mk
PPU_TARGET = retroarch_ps3.elf
SALAMANDER_TARGET = retroarch-salamander_ps3.elf
EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN
CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF
LDDIRS = -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt
INCDIRS = -I. \
-Idefines \
-Ideps \
-Ideps/libz \
-Ideps/stb \
-Ideps/rcheevos/include \
-Ilibretro-common/include \
-Ilibretro-common/include/compat/zlib
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
MAKE_SELF = make_self_npdrm
PYTHON2 = python2
GIT = git
else
PKG_FINALIZE = package_finalize.exe
MAKE_SELF_WC = make_self_wc.exe
MAKE_SELF = make_self_npdrm.exe
PYTHON2 = python2.exe
GIT = git.exe
endif
PPU_SRCS = griffin/griffin.c
#DEFINES += -DHAVE_VIDEO_LAYOUT
DEFINES += -DHAVE_MENU -DHAVE_MENU_WIDGETS -DHAVE_RGUI -DHAVE_XMB -DHAVE_OZONE -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT -DHAVE_RUNAHEAD -DHAVE_DR_MP3 -DHAVE_DR_FLAC
ifeq ($(DEX_BUILD), 1)
DEFINES += -DDEX_BUILD
endif
ifeq ($(CEX_BUILD), 1)
DEFINES += -DCEX_BUILD
endif
ifeq ($(ODE_BUILD), 1)
DEFINES += -DODE_BUILD
endif
ifeq ($(HAVE_GCMGL), 1)
DEFINES += -DHAVE_GCMGL
GL_LIBS := -L. -lrgl_ps3
else
GL_LIBS := -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt -lPSGL -lPSGLcgc
endif
ifeq ($(HAVE_FREETYPE), 1)
DEFINES += -DHAVE_FREETYPE
FONT_LIBS := -lfontFT_stub -lfreetype_stub
else
#DEFINES += -DHAVE_LIBDBGFONT
#FONT_LIBS := -ldbgfont
endif
ifeq ($(CELL_BUILD_TOOLS), SNC)
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
else ifneq ($(system_platform), win)
PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
PPU_CCLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl, --whole-archive
WHOLE_END := -Wl, --no-whole-archive
endif
PPU_LDLIBS = $(FONT_LIBS) $(GL_LIBS) $(WHOLE_START) -lretro_ps3 $(WHOLE_END) -lcgc -lgcm_cmdasm -lgcm_sys_stub -lresc_stub -lm -lio_stub -lfs_stub -lsysutil_stub -lsysutil_game_stub -lsysutil_screenshot_stub -lsysutil_np_stub -lpngdec_stub -lsysmodule_stub -laudio_stub -lnet_stub -lnetctl_stub -lpthread
PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe
DEFINES += -DHAVE_THREADS -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_HEADSET -DHAVE_LANGEXTRA -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RSOUND -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_7Z -DWANT_ZLIB -D__CELLOS_LV2__ -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_MOUSE -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -DHAVE_FILTERS_BUILTIN -DHAVE_CHEEVOS -DRC_DISABLE_LUA
#DEFINES += -DHAVE_IMAGEVIEWER
ifeq ($(DEBUG), 1)
PPU_OPTIMIZE_LV := -O0 -g
else
PPU_OPTIMIZE_LV := -O2 -g
endif
ifeq ($(HAVE_LOGGER), 1)
DEFINES += -DHAVE_LOGGER
endif
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
PPU_CXXFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
EXIST_EBOOT_WILDCARD := $(wildcard $(EBOOT_PATH))
EXIST_CORE_WILDCARD := $(wildcard $(CORE_PATH))
EBOOT_EXISTS = 1
CORE_EXISTS = 1
ifneq ($(strip $(EXIST_EBOOT_WILDCARD)),)
EBOOT_EXISTS = 0
endif
ifneq ($(strip $(EXIST_CORE_WILDCARD)),)
CORE_EXISTS = 0
endif
include $(CELL_MK_DIR)/sdk.target.mk
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe
MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe
.PHONY: create-npdrm-core create-core create-npdrm-salamander create-shaders clean-selfs create-salamander
create-npdrm-core:
$(MAKE_FSELF_NPDRM) $(PPU_TARGET) $(CORE_PATH)
create-core:
$(MAKE_SELF_WC) $(PPU_TARGET) $(CORE_PATH)
create-npdrm-salamander:
$(MAKE_FSELF_NPDRM) $(SALAMANDER_TARGET) $(EBOOT_PATH)
create-salamander:
$(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL)
copy-media-files:
@cp -r $(ASSETS_DIR)/glui pkg/ps3/USRDIR/cores/assets
@cp -r $(ASSETS_DIR)/xmb pkg/ps3/USRDIR/cores/assets
create-shaders:
make -f Makefile.griffin platform=ps3 shaders-deploy
pkg: $(PPU_TARGET) create-shaders copy-media-files create-npdrm-salamander create-npdrm-core
$(MAKE_PACKAGE_NPDRM) pkg/ps3/package.conf pkg/ps3
pkg-signed: $(PPU_TARGET) create-shaders copy-media-files create-salamander create-core
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
pkg-signed-standalone: $(PPU_TARGET) create-shaders copy-media-files create-core
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
pkg-signed-cfw: $(PPU_TARGET) create-shaders copy-media-files create-salamander create-core
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
$(PKG_FINALIZE) retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
pkg-signed-cfw-standalone: $(PPU_TARGET) create-shaders copy-media-files create-core
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
$(PKG_FINALIZE) retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
clean-selfs:
ifeq ($(EBOOT_EXISTS),1)
@echo "WARNING: Couldn't find file to delete: [$(EBOOT_PATH)], skipping this step."
else
rm $(EBOOT_PATH)
endif
ifeq ($(CORE_EXISTS),1)
@echo "WARNING: Couldn't find file to delete: [$(CORE_PATH)], skipping this step."
else
rm $(CORE_PATH)
endif

View File

@ -1,199 +0,0 @@
include version.all
#which compiler to build with - GCC or SNC
#set to GCC for debug builds for use with debugger
CELL_BUILD_TOOLS = GCC
CELL_GPU_TYPE = RSX
CELL_PSGL_VERSION = ultra-opt
# options
DOWNLOAD_SHADERS = 1
STRIPPING_ENABLE = 0
DEBUG = 0
HAVE_GCMGL = 1
HAVE_LOGGER = 0
HAVE_FREETYPE = 0
WHOLE_ARCHIVE_LINK = 0
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
CONTENT_ID = SSNE10000
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
PC_DEVELOPMENT_UDP_PORT = 3490
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
include $(CELL_MK_DIR)/sdk.makedef.mk
PPU_TARGET = retroarch_ps3.elf
SALAMANDER_TARGET = retroarch-salamander_ps3.elf
EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN
CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF
LDDIRS = -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt
INCDIRS = -I. -Idefines -Ideps -Ideps/stb
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
MAKE_SELF = make_self_npdrm
PYTHON2 = python2
GIT = git
else
PKG_FINALIZE = package_finalize.exe
MAKE_SELF_WC = make_self_wc.exe
MAKE_SELF = make_self_npdrm.exe
PYTHON2 = python2.exe
GIT = git.exe
endif
PPU_SRCS = griffin/griffin.c
DEFINES += -DHAVE_RGUI -DHAVE_MATERIALUI -DHAVE_XMB -DHAVE_MENU -DRARCH_INTERNAL
ifeq ($(DEX_BUILD), 1)
DEFINES += -DDEX_BUILD
endif
ifeq ($(CEX_BUILD), 1)
DEFINES += -DCEX_BUILD
endif
ifeq ($(ODE_BUILD), 1)
DEFINES += -DODE_BUILD
endif
ifeq ($(HAVE_GCMGL), 1)
DEFINES += -DHAVE_GCMGL
GL_LIBS := -L. -lrgl_ps3
else
GL_LIBS := -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt -lPSGL -lPSGLcgc
endif
ifeq ($(HAVE_FREETYPE), 1)
DEFINES += -DHAVE_FREETYPE
FONT_LIBS := -lfontFT_stub -lfreetype_stub
else
DEFINES += -DHAVE_LIBDBGFONT
FONT_LIBS := -ldbgfont
endif
ifeq ($(CELL_BUILD_TOOLS), SNC)
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
else ifneq($(system_platform), win)
PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
PPU_CCLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl, --whole-archive
WHOLE_END := -Wl, --no-whole-archive
endif
PPU_LDLIBS = $(FONT_LIBS) $(GL_LIBS) $(WHOLE_START) -lretro_ps3 $(WHOLE_END) -lcgc -lgcm_cmdasm -lgcm_sys_stub -lresc_stub -lm -lio_stub -lfs_stub -lsysutil_stub -lsysutil_game_stub -lsysutil_screenshot_stub -lsysutil_np_stub -lpngdec_stub -ljpgdec_stub -lsysmodule_stub -laudio_stub -lnet_stub -lnetctl_stub -lpthread
PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe
#DEFINES += -DHAVE_VIDEO_LAYOUT
DEFINES += -DHAVE_THREADS -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RSOUND -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -D__CELLOS_LV2__ -DHAVE_NETWORKING=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_MOUSE -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=0 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -DHAVE_STB_VORBIS
ifeq ($(DEBUG), 1)
PPU_OPTIMIZE_LV := -O0 -g
else
PPU_OPTIMIZE_LV := -O3 -g
endif
ifeq ($(HAVE_LOGGER), 1)
DEFINES += -DHAVE_LOGGER
endif
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
PPU_CXXFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
EXIST_EBOOT_WILDCARD := $(wildcard $(EBOOT_PATH))
EXIST_CORE_WILDCARD := $(wildcard $(CORE_PATH))
EBOOT_EXISTS = 1
CORE_EXISTS = 1
ifneq ($(strip $(EXIST_EBOOT_WILDCARD)),)
EBOOT_EXISTS = 0
endif
ifneq ($(strip $(EXIST_CORE_WILDCARD)),)
CORE_EXISTS = 0
endif
include $(CELL_MK_DIR)/sdk.target.mk
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe
MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe
.PHONY: create-npdrm-core create-core create-npdrm-salamander create-shaders clean-selfs create-salamander
create-npdrm-core:
$(MAKE_FSELF_NPDRM) $(PPU_TARGET) $(CORE_PATH)
create-core:
$(MAKE_SELF_WC) $(PPU_TARGET) $(CORE_PATH)
create-npdrm-salamander:
$(MAKE_FSELF_NPDRM) $(SALAMANDER_TARGET) $(EBOOT_PATH)
create-salamander:
$(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL)
copy-media-files:
@cp -r $(ASSETS_DIR)/glui pkg/ps3/USRDIR/cores/assets
@cp -r $(ASSETS_DIR)/xmb pkg/ps3/USRDIR/cores/assets
create-shaders:
make -f Makefile.shaders deploy-ps3
pkg: $(PPU_TARGET) create-shaders copy-media-files create-npdrm-salamander create-npdrm-core
$(MAKE_PACKAGE_NPDRM) pkg/ps3/package.conf pkg/ps3
pkg-signed: $(PPU_TARGET) create-shaders copy-media-files create-salamander create-core
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
pkg-signed-standalone: $(PPU_TARGET) create-shaders copy-media-files create-core
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
pkg-signed-cfw: $(PPU_TARGET) create-shaders copy-media-files create-salamander create-core
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
$(PKG_FINALIZE) retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
pkg-signed-cfw-standalone: $(PPU_TARGET) create-shaders copy-media-files create-core
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
$(PKG_FINALIZE) retroarch-ps3-cfw-$(PACKAGE_VERSION)-kmeaw.pkg
clean-selfs:
ifeq ($(EBOOT_EXISTS),1)
@echo "WARNING: Couldn't find file to delete: [$(EBOOT_PATH)], skipping this step."
else
rm $(EBOOT_PATH)
endif
ifeq ($(CORE_EXISTS),1)
@echo "WARNING: Couldn't find file to delete: [$(CORE_PATH)], skipping this step."
else
rm $(CORE_PATH)
endif

View File

@ -1,91 +0,0 @@
CELL_BUILD_TOOLS = GCC
CELL_SDK ?= /usr/local/cell
HAVE_LOGGER = 0
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
include $(CELL_MK_DIR)/sdk.makedef.mk
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
ifeq ($(DEBUG), 1)
PPU_OPTIMIZE_LV := -O0 -g
else
PPU_OPTIMIZE_LV := -O2 -DNDEBUG
endif
STRIP = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-strip.exe
INCFLAGS = -I. -Idefines -Ilibretro-common/include -Ideps/libz
DEFINES = -D__CELLOS_LV2__ -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_SYSUTILS -DHAVE_SYSMODULES -DHAVE_RARCH_EXEC
ifeq ($(DEX_BUILD), 1)
DEFINES += -DDEX_BUILD
endif
ifeq ($(CEX_BUILD), 1)
DEFINES += -DCEX_BUILD
endif
ifeq ($(ODE_BUILD), 1)
DEFINES += -DODE_BUILD
endif
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
PPU_CXXFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
PPU_SRCS = frontend/frontend_salamander.c \
frontend/frontend_driver.c \
frontend/drivers/platform_ps3.c \
frontend/drivers/platform_null.c \
libretro-common/file/file_path.c \
libretro-common/lists/dir_list.c \
libretro-common/lists/string_list.c \
libretro-common/file/retro_dirent.c \
libretro-common/hash/rhash.c \
libretro-common/string/stdstring.c \
libretro-common/encodings/encoding_utf.c \
libretro-common/compat/compat_strl.c \
libretro-common/compat/compat_strcasestr.c \
libretro-common/compat/fopen_utf8.c \
libretro-common/streams/file_stream.c \
libretro-common/vfs/vfs_implementation.c \
libretro-common/file/config_file.c \
file_path_str.c \
verbosity.c
ifeq ($(HAVE_LOGGER), 1)
PPU_CFLAGS += -DHAVE_LOGGER
PPU_SRCS += network/net_logger.c \
libretro-common/net/net_compat.c \
libretro-common/net/net_socket.c
endif
PPU_TARGET = retroarch-salamander_ps3.elf
ifeq ($(CELL_BUILD_TOOLS),SNC)
PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
PPU_CXXFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
PPU_CLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
else
PPU_CFLAGS += -std=gnu99
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
PPU_CLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
endif
PPU_LDLIBS += -lm -lnet_stub -lnetctl_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lsysutil_game_stub -lfs_stub -lsysutil_np_stub
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
include $(CELL_MK_DIR)/sdk.target.mk

View File

@ -1,133 +0,0 @@
include version.all
DEBUG = 0
HAVE_LOGGER = 0
HAVE_FILE_LOGGER = 0
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
PC_DEVELOPMENT_UDP_PORT = 3490
CC = $(PS3DEV)/ppu/bin/ppu-gcc
CXX = $(PS3DEV)/ppu/bin/ppu-g++
LD = $(PS3DEV)/ppu/bin/ppu-ld
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
ELF_TARGET := retroarch_psl1ght.elf
EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN
CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF
INCLUDE := -I. -I$(PS3DEV)/ppu/include -Ideps/libz -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib
LIBDIRS := -L$(PS3DEV)/ppu/lib -L$(PS3DEV)/portlibs/ppu/lib -L.
MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__
CFLAGS += -Wall $(MACHDEP) $(INCLUDE)
LDFLAGS := $(MACHDEP)
LIBS := -lrgl_ps3 -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
MAKE_SELF = make_self_npdrm
PYTHON2 = python2
GIT = git
else
PKG_FINALIZE = package_finalize.exe
MAKE_SELF_WC = make_self_wc.exe
MAKE_SELF = make_self_npdrm.exe
PYTHON2 = python2.exe
GIT = git.exe
endif
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
MAKE_SELF = make_self_npdrm
PYTHON2 = python2
GIT = git
else
PKG_FINALIZE = package_finalize.exe
MAKE_SELF_WC = make_self_wc.exe
MAKE_SELF = make_self_npdrm.exe
PYTHON2 = python2.exe
GIT = git.exe
endif
MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe
MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe
OBJ = griffin/griffin.o
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
SHARED_FLAGS :=
#SHARED_FLAGS += -DHAVE_VIDEO_LAYOUT
SHARED_FLAGS += -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_GCMGL -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -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
CFLAGS += -std=gnu99 $(SHARED_FLAGS)
CXXFLAGS += $(SHARED_FLAGS)
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3 -g
CXXFLAGS += -03 -g
endif
all: $(ELF_TARGET)
$(ELF_TARGET): $(OBJ)
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.cpp
$(CXX) $(CFLAGS) -c -o $@ $<
create-npdrm-core:
$(MAKE_FSELF_NPDRM) $(ELF_TARGET) $(CORE_PATH)
create-core:
$(MAKE_SELF_WC) $(ELF_TARGET) $(CORE_PATH)
pkg: $(ELF_TARGET) create-npdrm-core
$(MAKE_PACKAGE_NPDRM) pkg/ps3/package.conf ps3/pkg
pkg-signed: $(ELF_TARGET) create-core
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(PACKAGE_VERSION).pkg
clean:
rm -f $(ELF_TARGET)
rm -f $(OBJ)
.PHONY: clean

View File

@ -1,60 +0,0 @@
BUILD_PRX = 0
PSP_LARGE_MEMORY = 1
DEBUG = 0
HAVE_KERNEL_PRX = 1
HAVE_LOGGER = 0
HAVE_FILE_LOGGER = 0
HAVE_THREADS = 1
BIG_STACK = 0
WHOLE_ARCHIVE_LINK = 0
TARGET = retroarchpsp
ifeq ($(DEBUG), 1)
OPTIMIZE_LV := -O0 -g
else
OPTIMIZE_LV := -O3
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
INCDIR = deps deps/stb deps/libz deps/7zip deps/pthreads deps/pthreads/platform/psp deps/pthreads/platform/helper libretro-common/include libretro-common/include/compat/zlib
CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math -fsingle-precision-constant
ASFLAGS = $(CFLAGS)
RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DWANT_ZLIB -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
LIBDIR =
LDFLAGS =
LIBS = $(WHOLE_START) -lretro_psp1 $(WHOLE_END) -lstdc++ -lpspgu -lpspgum -lm -lpspaudio -lpspfpu -lpsppower -lpsprtc
ifeq ($(HAVE_THREADS), 1)
RARCH_DEFINES += -DHAVE_THREADS
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
ifeq ($(HAVE_KERNEL_PRX), 1)
CFLAGS += -DHAVE_KERNEL_PRX
endif
ifeq ($(BIG_STACK), 1)
CFLAGS += -DBIG_STACK
endif
CFLAGS += $(RARCH_DEFINES)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = RetroArch PSP1
PSP_OBJECTS = griffin/griffin.o bootstrap/psp1/kernel_functions.o
OBJS = $(PSP_OBJECTS)
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

View File

@ -1,57 +0,0 @@
BUILD_PRX = 0
PSP_LARGE_MEMORY = 1
HAVE_FILE_LOGGER = 0
DEBUG = 0
TARGET = retroarchpsp_salamander
ifeq ($(DEBUG), 1)
OPTIMIZE_LV := -O0 -g
else
OPTIMIZE_LV := -O2
endif
INCDIR = $(PSPPATH)/include libretro-common/include
CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math
ASFLAGS = $(CFLAGS)
RARCH_DEFINES = -DPSP -DIS_SALAMANDER -DRARCH_CONSOLE
LIBDIR =
LDFLAGS =
LIBS = -lstdc++ -lm -lpsppower
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
CFLAGS += $(RARCH_DEFINES)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = RetroArch
PSP_EBOOT_ICON = pkg/psp1/ICON0.PNG
PSP_EBOOT_PIC1 = pkg/psp1/PIC1.PNG
OBJS = frontend/frontend_salamander.o \
frontend/frontend_driver.o \
frontend/drivers/platform_psp.o \
frontend/drivers/platform_null.o \
libretro-common/file/file_path.o \
libretro-common/string/stdstring.o \
libretro-common/lists/string_list.o \
libretro-common/lists/dir_list.o \
libretro-common/file/retro_dirent.o \
libretro-common/encodings/encoding_utf.o \
libretro-common/compat/fopen_utf8.o \
libretro-common/compat/compat_strl.o \
libretro-common/compat/compat_strcasestr.o \
libretro-common/file/config_file.o \
libretro-common/streams/file_stream.o \
libretro-common/vfs/vfs_implementation.o \
libretro-common/hash/rhash.o \
file_path_str.o \
verbosity.o \
bootstrap/psp1/kernel_functions.o
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

View File

@ -1,70 +0,0 @@
TARGET := retroarch_switch
DEBUG ?= 0
GRIFFIN_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
OBJ :=
DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL -DHAVE_DYNAMIC
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_NEON -DHAVE_MATERIALUI -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB
DEFINES += -DHAVE_RUNAHEAD -DHAVE_DYNAMIC
else
HAVE_CC_RESAMPLER = 1
HAVE_MENU_COMMON = 1
HAVE_RTGA = 1
HAVE_RPNG = 1
HAVE_RJPEG = 1
HAVE_RBMP = 1
HAVE_RGUI = 1
HAVE_ZLIB = 1
HAVE_BUILTINZLIB = 1
HAVE_LIBRETRODB = 1
HAVE_MATERIALUI = 0 # enable later?
HAVE_XMB = 0
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
HAVE_MENU = 1
HAVE_RUNAHEAD = 1
HAVE_DYNAMIC = 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 $(LIBTRANSISTOR_HOME)),)
$(error "Please set LIBTRANSISTOR_HOME in your environment. export LIBTRANSISTOR_HOME=<path/to/libtransistor/dist/>")
endif
include $(LIBTRANSISTOR_HOME)/libtransistor.mk
INCDIRS := -I. -Ideps -Ideps/libz -Ilibretro-common/include -Ilibretro-common/include/compat/zlib -Ideps/stb -I$(LIBTRANSISTOR_HOME)/build/sdl2_install/include/SDL2/
LIBDIRS := -L.
TARGETS := $(TARGET).nro
CFLAGS += $(INCDIRS) $(DEFINES) -Wno-unused-command-line-argument -Werror-implicit-function-declaration
all: $(TARGETS)
$(TARGET).nro.so: $(OBJ) libretro_switch.a fs.squashfs.o $(LIBTRANSISTOR_NRO_LIB) $(LIBTRANSISTOR_COMMON_LIBS)
$(LD) $(LD_FLAGS) --allow-multiple-definition -o $@ $(OBJ) libretro_switch.a fs.squashfs.o $(LIBTRANSISTOR_NRO_LDFLAGS) -lm
%.squashfs.o: %.squashfs
$(LD) -s -r -b binary -m aarch64elf -T $(LIBTRANSISTOR_HOME)/fs.T -o $@ $<
fs.squashfs: fs/*
mksquashfs $^ $@ -comp lz4 -nopad -noappend
clean:
rm -f $(OBJ) $(TARGET).nro.so $(TARGET).nro
.PHONY: clean all

View File

@ -1,182 +0,0 @@
TARGET := retroarch_vita
DEBUG ?= 0
GRIFFIN_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
VITA_TITLE_ID := RETROARCH
VITA_TITLE_NAME := RetroArch
PC_DEVELOPMENT_IP_ADDRESS =
PC_DEVELOPMENT_UDP_PORT =
OBJ :=
DEFINES :=
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1
DEFINES += -DHAVE_NEON -DHAVE_MENU -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB DEFINES -DHAVE_KEYMAPPER
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB -DHAVE_CC_RESAMPLER -DHAVE_UPDATE_ASSETS
ifeq ($(DEBUG), 1)
DEFINES += -DHAVE_NETLOGGER
endif
else
HAVE_NEON := 1
HAVE_FILTERS_BUILTIN := 1
HAVE_LANGEXTRA := 1
HAVE_RPNG := 1
HAVE_RJPEG := 1
HAVE_RBMP := 1
HAVE_RTGA := 1
HAVE_ZLIB := 1
HAVE_7ZIP := 1
HAVE_VITA2D := 1
HAVE_NETWORKING := 1
HAVE_SOCKET_LEGACY := 1
HAVE_MENU := 1
HAVE_MENU_COMMON := 1
HAVE_OVERLAY := 1
HAVE_VIDEO_LAYOUT := 0
HAVE_MATERIALUI := 1
HAVE_XMB := 1
HAVE_RGUI := 1
HAVE_STB_FONT := 1
HAVE_THREADS := 1
HAVE_LIBRETRODB := 1
HAVE_CC_RESAMPLER := 1
HAVE_CHEEVOS := 1
RARCH_CONSOLE := 1
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
ifeq ($(DEBUG), 1)
HAVE_NETLOGGER = 1
endif
include Makefile.common
CFLAGS += $(DEF_FLAGS)
BLACKLIST :=
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
OBJ += input/drivers/psp_input.o
OBJ += input/drivers_joypad/psp_joypad.o
OBJ += audio/drivers/psp_audio.o
OBJ += frontend/drivers/platform_psp.o
endif
ifeq ($(strip $(VITASDK)),)
$(error "Please set VITASDK in your environment. export VITASDK=<path to>vitasdk")
endif
export PATH := $(PATH):$(VITASDK)/bin
PREFIX := arm-vita-eabi-
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
AS := $(PREFIX)as
AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
INCDIRS := -I. -Ideps/libz -Ideps/7zip -Ilibretro-common/include -Ideps/stb
LIBDIRS := -L.
ARCHFLAGS := -march=armv7-a -mfpu=neon -mfloat-abi=hard -DVITA
CFLAGS += $(ARCHFLAGS) -mword-relocations -fno-optimize-sibling-calls
ifeq ($(DEBUG), 1)
CFLAGS += -O2 -g
else
CFLAGS += -O3
endif
ASFLAGS := $(CFLAGS)
LDFLAGS := -Wl,-q
CFLAGS += -Wall -ffast-math
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
ifneq ($(PC_DEVELOPMENT_IP_ADDRESS),)
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS='"$(PC_DEVELOPMENT_IP_ADDRESS)"'
endif
ifneq ($(PC_DEVELOPMENT_UDP_PORT),)
CFLAGS += -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
VITA_LIBS := -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub \
-lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub \
-lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \
-lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lpthread -lpng -lz
LIBS := $(WHOLE_START) -lretro_vita $(WHOLE_END) $(VITA_LIBS) -lm -lc
TARGETS := $(TARGET).vpk
DEPFLAGS = -MT $@ -MMD -MP -MF $*.Tdepend
POSTCOMPILE = mv -f $*.Tdepend $*.depend
all: $(TARGETS)
%.o: %.cpp
%.o: %.cpp %.depend
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.c
%.o: %.c %.depend
$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.S
%.o: %.S %.depend
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.o: %.s
%.o: %.s %.depend
$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
$(POSTCOMPILE)
%.depend: ;
$(TARGET).elf: $(OBJ) libretro_vita.a
$(LD) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
%.velf: %.elf
vita-elf-create $< $@
%.self: %.velf
vita-make-fself -c -s $< $@
%.vpk: %.self
vita-mksfoex -s TITLE_ID=$(VITA_TITLE_ID) "$(VITA_TITLE_NAME)" param.sfo
vita-pack-vpk -s param.sfo -b $< $@
clean:
rm -f $(OBJ) $(TARGET).elf $(TARGET).velf $(TARGET).self param.sfo $(TARGET).vpk
rm -f $(OBJ:.o=.depend)
# Useful for developers
vpksend: $(TARGET).vpk
curl -T $< ftp://$(PSVITAIP):1337/ux0:/
send: $(TARGET).self
curl -T $< ftp://$(PSVITAIP):1337/ux0:/app/$(VITA_TITLE_ID)/eboot.bin
.PHONY: clean all send vpksend
.PRECIOUS: %.depend
-include $(OBJ:.o=.depend)

View File

@ -1,85 +0,0 @@
HAVE_FILE_LOGGER = 0
DEBUG = 0
TARGET = retroarchvita_salamander
TITLE_ID = RETROVITA
ifeq ($(DEBUG), 1)
OPTIMIZE_LV := -O0 -g
else
OPTIMIZE_LV := -O2
endif
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
INCDIR = libretro-common/include
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
LIBDIR =
LDFLAGS =
LIBS = -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\
-lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceAudio_stub -lSceFiber_stub\
-lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \
-lSceMotion_stub -lSceAppMgr_stub -lfreetype -lpng -lm -lc
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
CFLAGS += $(RARCH_DEFINES)
OBJS = frontend/frontend_salamander.o \
frontend/frontend_driver.o \
frontend/drivers/platform_psp.o \
frontend/drivers/platform_null.o \
libretro-common/file/file_path.o \
libretro-common/string/stdstring.o \
libretro-common/lists/string_list.o \
libretro-common/lists/dir_list.o \
libretro-common/file/retro_dirent.o \
libretro-common/encodings/encoding_utf.o \
libretro-common/compat/compat_strl.o \
libretro-common/compat/compat_strcasestr.o \
libretro-common/compat/fopen_utf8.o \
libretro-common/file/config_file.o \
libretro-common/streams/file_stream.o \
libretro-common/vfs/vfs_implementation.o \
libretro-common/hash/rhash.o \
file_path_str.o \
verbosity.o
all: $(TARGET).vpk
%.vpk: eboot.bin
vita-mksfoex -s TITLE_ID=$(TITLE_ID) "$(TARGET)" param.sfo
vita-pack-vpk -s param.sfo -b eboot.bin $@
eboot.bin: $(TARGET).velf
vita-make-fself $< $@
%.velf: %.elf
vita-elf-create $< $@
$(TARGET).elf: $(OBJS)
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
%.o: %.png
$(PREFIX)-ld -r -b binary -o $@ $^
clean:
@rm -rf $(TARGET).vpk $(TARGET).velf $(TARGET).elf $(OBJS) \
eboot.bin param.sfo
vpksend: $(TARGET).vpk
curl -T $(TARGET).vpk ftp://$(PSVITAIP):1337/ux0:/
@echo "Sent."
PSVITAIP = 192.168.1.15
send: eboot.bin
curl -T eboot.bin ftp://$(PSVITAIP):1337/ux0:/app/$(TITLE_ID)/
@echo "Sent."

View File

@ -1,141 +0,0 @@
###
##
# Makefile for RetroArch Wii.
##
DEBUG = 0
HAVE_LOGGER = 0
HAVE_FILE_LOGGER = 0
EXTERNAL_LIBOGC = 0
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PC_DEVELOPMENT_IP_ADDRESS = 255.255.255.255
PC_DEVELOPMENT_UDP_PORT = 3490
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT)
ELF2DOL = $(DEVKITPPC)/bin/elf2dol$(EXE_EXT)
DOL_TARGET := retroarch-salamander_wii.dol
ELF_TARGET := retroarch-salamander_wii.elf
INCLUDE := -I. -Ilibretro-common/include -Ideps/libz
ifeq ($(EXTERNAL_LIBOGC), 1)
INCLUDE += -I$(DEVKITPRO)/libogc/include
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L.
else
INCLUDE += -Iwii/libogc/include
LIBDIRS := -Lwii/libogc/libs/wii -L.
endif
MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float
CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE)
LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map
ifeq ($(EXTERNAL_LIBOGC), 1)
LIBS := -lfat
endif
LIBS += -lwiiuse -logc -lbte
APP_BOOTER_DIR = wii/app_booter
OBJ = frontend/frontend_salamander.o \
frontend/frontend_driver.o \
frontend/drivers/platform_gx.o \
frontend/drivers/platform_wii.o \
frontend/drivers/platform_null.o \
libretro-common/file/file_path.o \
libretro-common/hash/rhash.o \
libretro-common/string/stdstring.o \
libretro-common/lists/string_list.o \
libretro-common/lists/dir_list.o \
libretro-common/streams/file_stream.o \
libretro-common/vfs/vfs_implementation.o \
libretro-common/file/retro_dirent.o \
libretro-common/encodings/encoding_utf.o \
libretro-common/compat/compat_strl.o \
libretro-common/compat/compat_strcasestr.o \
libretro-common/compat/fopen_utf8.o \
libretro-common/file/config_file.o \
file_path_str.o \
verbosity.o \
$(APP_BOOTER_DIR)/app_booter.binobj
ifeq ($(EXTERNAL_LIBOGC), 1)
else
OBJ += wii/libogc/libfat/cache.o \
wii/libogc/libfat/directory.o \
wii/libogc/libfat/disc.o \
wii/libogc/libfat/fatdir.o \
wii/libogc/libfat/fatfile.o \
wii/libogc/libfat/file_allocation_table.o \
wii/libogc/libfat/filetime.o \
wii/libogc/libfat/libfat.o \
wii/libogc/libfat/lock.o \
wii/libogc/libfat/partition.o
endif
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
OBJ += network/net_logger.o \
libretro-common/net/net_compat.o \
libretro-common/net/net_socket.o
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
endif
CFLAGS += -std=gnu99 -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DGEKKO -Wno-char-subscripts
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
ifeq ($(USBGECKO), 1)
LIBS += -ldb
CFLAGS += -DUSBGECKO
endif
all: $(DOL_TARGET)
%.dol: %.elf
$(ELF2DOL) $< $@
$(ELF_TARGET): $(OBJ)
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.binobj: %.bin
$(LD) -r -b binary -o $@ $<
$(APP_BOOTER_DIR)/app_booter.bin:
$(MAKE) -C $(APP_BOOTER_DIR)
pkg: all
cp -r $(DOL_TARGET) pkg/wii/boot.dol
clean:
rm -f $(DOL_TARGET)
rm -f $(ELF_TARGET)
rm -f $(OBJ)
$(MAKE) -C $(APP_BOOTER_DIR) clean
.PHONY: clean

View File

@ -1,352 +0,0 @@
TARGET := retroarch_wiiu
BUILD_HBL_ELF = 1
BUILD_RPX = 1
DEBUG = 0
GRIFFIN_BUILD = 0
SALAMANDER_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
WIIU_HID = 1
HAVE_RUNAHEAD = 1
WIIU_LOG_RPX = 0
BUILD_DIR = objs/wiiu
PC_DEVELOPMENT_TCP_PORT ?=
ifeq ($(SALAMANDER_BUILD),1)
BUILD_DIR := $(BUILD_DIR)-salamander
TARGET := $(TARGET)_salamander
else ifeq ($(GRIFFIN_BUILD),1)
BUILD_DIR := $(BUILD_DIR)-griffin
endif
ifeq ($(DEBUG),1)
BUILD_DIR := $(BUILD_DIR)-debug
endif
ifneq ($(V), 1)
Q := @
endif
DEFINES :=
OBJ :=
INCDIRS :=
#-----------------------------
# Features and object files
OBJ += wiiu/main.o
OBJ += wiiu/system/memory.o
OBJ += wiiu/system/atomic.o
OBJ += wiiu/system/exception_handler.o
OBJ += wiiu/system/missing_libc_functions.o
OBJ += wiiu/fs/sd_fat_devoptab.o
OBJ += wiiu/fs/fs_utils.o
OBJ += wiiu/hbl.o
RPX_OBJ = $(BUILD_DIR)/wiiu/system/stubs_rpl.o
HBL_ELF_OBJ = $(BUILD_DIR)/wiiu/system/dynamic.o \
$(BUILD_DIR)/wiiu/system/stubs_elf.o
ifeq ($(SALAMANDER_BUILD),1)
DEFINES += -DRARCH_CONSOLE -DIS_SALAMANDER
OBJ += frontend/frontend_salamander.o
OBJ += frontend/frontend_driver.o
OBJ += frontend/drivers/platform_wiiu.o
OBJ += frontend/drivers/platform_null.o
OBJ += libretro-common/encodings/encoding_utf.o
OBJ += libretro-common/compat/compat_strcasestr.o
OBJ += libretro-common/compat/fopen_utf8.o
OBJ += libretro-common/file/file_path.o
OBJ += libretro-common/string/stdstring.o
OBJ += libretro-common/lists/string_list.o
OBJ += libretro-common/lists/dir_list.o
OBJ += libretro-common/file/retro_dirent.o
OBJ += libretro-common/compat/compat_strl.o
OBJ += libretro-common/file/config_file.o
OBJ += libretro-common/streams/file_stream.o
OBJ += libretro-common/vfs/vfs_implementation.o
OBJ += libretro-common/hash/rhash.o
OBJ += file_path_str.o
OBJ += verbosity.o
# $(SALAMANDER_BUILD),0
else
DEFINES += -DRARCH_INTERNAL
DEFINES += -DHAVE_KEYMAPPER
DEFINES += -DHAVE_UPDATE_ASSETS
DEFINES += -DHAVE_FILTERS_BUILTIN
DEFINES += -DHAVE_SLANG
DEFINES += -DHAVE_SHADERPIPELINE
ifeq ($(HAVE_RUNAHEAD),1)
DEFINES += -DHAVE_RUNAHEAD
endif
OBJ += wiiu/shader_utils.o
OBJ += gfx/drivers/gx2_shaders/tex.o
OBJ += gfx/drivers/gx2_shaders/sprite.o
OBJ += gfx/drivers/gx2_shaders/frame.o
OBJ += gfx/drivers/gx2_shaders/ribbon.o
OBJ += gfx/drivers/gx2_shaders/ribbon_simple.o
OBJ += gfx/drivers/gx2_shaders/bokeh.o
OBJ += gfx/drivers/gx2_shaders/snow.o
OBJ += gfx/drivers/gx2_shaders/snow_simple.o
OBJ += gfx/drivers/gx2_shaders/snowflake.o
OBJ += gfx/drivers_shader/slang_preprocess.o
OBJ += gfx/drivers_shader/glslang_util.o
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
INCDIRS += -Ilibretro-common/include/compat/zlib
# for stb, libfat, iosuhax
INCDIRS += -Ideps -Ideps/libfat/include -Ideps/libiosuhax
# pad_functions uses wiiu/input.h
INCDIRS += -Iinput/include
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_RGUI -DHAVE_LIBRETRODB
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB -DHAVE_CC_RESAMPLER
DEFINES += -DHAVE_STB_FONT -DHAVE_STB_VORBIS -DHAVE_LANGEXTRA -DHAVE_LIBRETRODB -DHAVE_NETWORKING -DHAVE_NETPLAYDISCOVERY
#DEFINES += -DWANT_IFADDRS
#DEFINES += -DHAVE_FREETYPE
DEFINES += -DHAVE_XMB -DHAVE_MATERIALUI
DEFINES += -DHAVE_HID
DEFINES += -DWANT_LIBFAT -DHAVE_LIBFAT -DWANT_IOSUHAX -DHAVE_IOSUHAX
# $(GRIFFIN_BUILD),0
else
HAVE_MENU_COMMON = 1
HAVE_RTGA = 1
HAVE_RPNG = 1
HAVE_RJPEG = 1
HAVE_RBMP = 1
HAVE_MENU = 1
HAVE_RGUI = 1
HAVE_7ZIP = 1
HAVE_ZLIB = 1
HAVE_BUILTINZLIB = 0
HAVE_LIBRETRODB = 1
HAVE_MATERIALUI = 1
HAVE_XMB = 1
HAVE_STB_FONT = 1
#HAVE_FREETYPE = 1
HAVE_LANGEXTRA = 1
HAVE_LIBRETRODB = 1
HAVE_NETWORKING = 1
HAVE_NETPLAYDISCOVERY = 1
HAVE_CHEEVOS = 1
#WANT_IFADDRS = 1
HAVE_OVERLAY = 1
HAVE_VIDEO_LAYOUT = 0
HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
WANT_LIBFAT = 1
WANT_IOSUHAX = 1
include Makefile.common
DEFINES += $(DEF_FLAGS)
INCDIRS += $(INCLUDE_DIRS)
OBJ += gfx/drivers/gx2_gfx.o
OBJ += gfx/drivers_font/wiiu_font.o
OBJ += menu/drivers_display/menu_display_wiiu.o
OBJ += input/drivers/wiiu_input.o
OBJ += input/drivers_joypad/wiiu_joypad.o
OBJ += input/drivers_joypad/wiiu/wpad_driver.o
OBJ += input/drivers_joypad/wiiu/kpad_driver.o
OBJ += input/drivers_joypad/wiiu/pad_functions.o
INCDIRS += -Iinput/include
OBJ += audio/drivers/wiiu_audio.o
OBJ += frontend/drivers/platform_wiiu.o
ifeq ($(WIIU_HID),1)
DEFINES += -DWIIU_HID
OBJ += input/drivers_joypad/wiiu/hidpad_driver.o
OBJ += input/drivers_hid/wiiu_hid.o
OBJ += input/connect/joypad_connection.o \
input/common/hid/hid_device_driver.o \
input/common/hid/device_wiiu_gca.o \
input/common/hid/device_ds3.o \
input/common/hid/device_ds4.o \
input/common/hid/device_null.o
endif
endif
endif
OBJ := $(addprefix $(BUILD_DIR)/,$(OBJ))
#-----------------------------
# Compile flags
DEFINES += -DWIIU -DMSB_FIRST -D__WUT__ -DHW_WUP -D__wiiu__
DEFINES += -DHAVE_MAIN
DEFINES += -DRARCH_CONSOLE
ifeq ($(WIIU_LOG_RPX),1)
DEFINES += -DWIIU_LOG_RPX
endif
ifneq ($(PC_DEVELOPMENT_TCP_PORT),)
DEFINES += -DPC_DEVELOPMENT_TCP_PORT=$(PC_DEVELOPMENT_TCP_PORT)
endif
INCDIRS += -I.
INCDIRS += -Ilibretro-common/include
INCDIRS += -Iwiiu
INCDIRS += -Iwiiu/include
CFLAGS := -mcpu=750 -meabi -mhard-float
CFLAGS += -ffast-math -Werror=implicit-function-declaration
CFLAGS += -ffunction-sections -fdata-sections
#CFLAGS += -fomit-frame-pointer -mword-relocations
#CFLAGS += -Wall
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
ASFLAGS := $(CFLAGS) -mregnames
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions
#-----------------------------
# Linking/library flags
LIBDIRS := -L.
LDFLAGS := $(CFLAGS)
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
LIBS := $(WHOLE_START) -lretro_wiiu $(WHOLE_END) -lm
# Use portlibs zlib if deps/ isn't being used
ifeq ($(HAVE_ZLIB),1)
ifeq ($(HAVE_BUILTINZLIB),0)
INCDIRS += -I$(DEVKITPRO)/portlibs/ppc/include
LIBDIRS += -L$(DEVKITPRO)/portlibs/ppc/lib
# Bonus: libpng for cores that need it
LIBS += -lpng -lz
endif
endif
LDFLAGS += -Wl,--gc-sections
RPX_LDFLAGS := -pie -fPIE
RPX_LDFLAGS += -z common-page-size=64 -z max-page-size=64
RPX_LDFLAGS += -T wiiu/link_rpl.ld
RPX_LDFLAGS += -nostartfiles
HBL_ELF_LDFLAGS := -T wiiu/link_elf.ld
#-----------------------------
# Compiler setup
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
endif
export PATH := $(PATH):$(DEVKITPPC)/bin
PREFIX := powerpc-eabi-
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
AS := $(PREFIX)as
AR := $(PREFIX)ar
OBJCOPY := $(PREFIX)objcopy
STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
ELF2RPL := wiiu/wut/elf2rpl/elf2rpl
ifneq ($(findstring Linux,$(shell uname -a)),)
else ifneq ($(findstring Darwin,$(shell uname -a)),)
else
ELF2RPL := $(ELF2RPL).exe
endif
#-----------------------------
# Targets and build rules
TARGETS :=
ifeq ($(BUILD_RPX), 1)
TARGETS += $(TARGET).rpx
endif
ifeq ($(BUILD_HBL_ELF), 1)
TARGETS += $(TARGET).elf
endif
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.depend
all: $(TARGETS)
%: $(BUILD_DIR)/%
cp $< $@
$(BUILD_DIR)/%.o: %.cpp %.depend
@$(if $(Q), echo CXX $<,)
@mkdir -p $(dir $@)
$(Q)$(CXX) -c -o $@ $< $(CXXFLAGS) $(DEFINES) $(INCDIRS) $(DEPFLAGS)
$(BUILD_DIR)/%.o: %.c %.depend
@$(if $(Q), echo CC $<,)
@mkdir -p $(dir $@)
$(Q)$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES) $(INCDIRS) $(DEPFLAGS)
$(BUILD_DIR)/%.o: %.S %.depend
@$(if $(Q), echo AS $<,)
@mkdir -p $(dir $@)
$(Q)$(CC) -c -o $@ $< $(ASFLAGS) $(DEFINES) $(INCDIRS) $(DEPFLAGS)
$(BUILD_DIR)/%.o: %.s %.depend
@$(if $(Q), echo AS $<,)
@mkdir -p $(dir $@)
$(Q)$(CC) -c -o $@ $< $(ASFLAGS) $(INCDIRS) $(DEPFLAGS)
%.a:
@$(if $(Q), echo AR $<,)
@mkdir -p $(dir $@)
$(Q)$(AR) -rc $@ $^
%.depend: ;
%.last: ;
$(ELF2RPL):
@$(if $(Q), echo MAKE $@,)
$(Q)$(MAKE) -C wiiu/wut/elf2rpl/
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) $(HBL_ELF_OBJ) libretro_wiiu.a wiiu/link_elf.ld .$(TARGET).elf.last
@$(if $(Q), echo LD $@,)
@touch .$(TARGET).elf.last
$(Q)$(LD) $(OBJ) $(HBL_ELF_OBJ) $(LDFLAGS) $(HBL_ELF_LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
$(BUILD_DIR)/$(TARGET).rpx.elf: $(OBJ) $(RPX_OBJ) libretro_wiiu.a wiiu/link_elf.ld
@$(if $(Q), echo LD $@,)
$(Q)$(LD) $(OBJ) $(RPX_OBJ) $(LDFLAGS) $(RPX_LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
$(BUILD_DIR)/$(TARGET).rpx: $(BUILD_DIR)/$(TARGET).rpx.elf $(ELF2RPL) .$(TARGET).rpx.last
@$(if $(Q), echo ELF2RPL $@,)
@touch .$(TARGET).rpx.last
$(Q)-$(ELF2RPL) $< $@
clean:
@$(if $(Q), echo $@,)
$(Q)rm -f $(OBJ) $(RPX_OBJ) $(HBL_ELF_OBJ) $(TARGET).elf $(TARGET).rpx.elf $(TARGET).rpx
$(Q)rm -f $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).rpx.elf $(BUILD_DIR)/$(TARGET).rpx
$(Q)rm -f .$(TARGET).elf.last .$(TARGET).rpx.elf.last .$(TARGET).rpx.last
$(Q)rm -f $(OBJ:.o=.depend) $(RPX_OBJ:.o=.depend) $(HBL_ELF_OBJ:.o=.depend)
.PHONY: clean all
.PRECIOUS: %.depend %.last
-include $(OBJ:.o=.depend) $(RPX_OBJ:.o=.depend) $(HBL_ELF_OBJ:.o=.depend)

View File

@ -1,184 +0,0 @@
TARGET = retroarch.exe
HAVE_DINPUT = 1
HAVE_XAUDIO = 1
HAVE_DSOUND = 1
HAVE_WASAPI = 1
HAVE_OPENGL = 1
HAVE_DYLIB = 1
HAVE_D3D9 = 1
HAVE_NETWORKING = 1
HAVE_NETPLAYDISCOVERY = 1
HAVE_STDIN_CMD = 1
HAVE_COMMAND = 1
HAVE_THREADS = 1
HAVE_MENU = 1
HAVE_RGUI = 1
HAVE_MATERIALUI = 1
HAVE_7ZIP = 1
HAVE_PYTHON = 0
DYNAMIC = 1
HAVE_XINPUT = 1
HAVE_WINMM = 1
HAVE_SDL := 0
HAVE_SDL2 := 0
HAVE_RSOUND := 0
HAVE_PYTHON := 0
HAVE_STB_FONT := 1
HAVE_FREETYPE := 1
HAVE_FFMPEG := 0
HAVE_CG := 1
HAVE_ZLIB := 1
WANT_ZLIB := 1
HAVE_CC_RESAMPLER := 1
ifeq ($(HAVE_CG), 1)
CG_LIBS := -lcg -lcgGL
endif
ifeq ($(HAVE_FREETYPE), 1)
FREETYPE_CFLAGS := -DHAVE_FREETYPE -Ifreetype2
FREETYPE_LIBS := -lfreetype
endif
ifeq ($(HAVE_SDL), 1)
SDL_LIBS := -lSDL
SDL_CFLAGS := -ISDL -DHAVE_SDL
BSD_LOCAL_INC :=
endif
ifeq ($(HAVE_SDL2), 1)
SDL2_LIBS := -lSDL2
SDL2_CFLAGS := -ISDL2 -DHAVE_SDL2
endif
ifeq ($(HAVE_D3D8), 1)
D3D8_LIBS := -ld3d8
ifeq ($(HAVE_D3DX), 1)
D3DX8_LIBS := -ld3dx8
endif
endif
ifeq ($(HAVE_D3D9), 1)
D3D9_LIBS := -ld3d9
ifeq ($(HAVE_D3DX), 1)
D3DX9_LIBS := -ld3dx9
endif
endif
ifeq ($(HAVE_RSOUND), 1)
RSOUND_CFLAGS := -DHAVE_RSOUND
RSOUND_LIBS := -lrsound
endif
ifeq ($(HAVE_PYTHON), 1)
PYTHON_LIBS := -lpython32
PYTHON_CFLAGS := -DHAVE_PYTHON -Ipython
endif
ifeq ($(HAVE_FFMPEG), 1)
AVCODEC_LIBS := -lavcodec
AVUTIL_LIBS := -lavutil
SWSCALE_LIBS := -lswscale
AVFORMAT_LIBS := -lavformat
SWRESAMPLE_LIBS := -lswresample
FFMPEG_LIBS := -lws2_32 -lz
endif
OBJDIR := obj-w32
OS := Win32
OBJ :=
LIBS := -lm
DEFINES :=
DEFINES += -I. -Ilibretro-common/include -Ilibretro-common/include/compat/zlib -DRARCH_INTERNAL -DHAVE_OVERLAY
#DEFINES += -DHAVE_VIDEO_LAYOUT
LDFLAGS := -L. -static-libgcc
include Makefile.common
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
ifneq ($(HOST_PREFIX),)
CC = $(HOST_PREFIX)gcc
CXX = $(HOST_PREFIX)g++
WINDRES = $(HOST_PREFIX)windres
else
CC = gcc
CXX = g++
WINDRES = windres
endif
libretro ?= -lretro
ifeq ($(DYNAMIC), 1)
DEFINES += -DHAVE_DYNAMIC
else
LIBS += $(libretro)
endif
ifneq ($(V), 1)
Q := @
endif
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
CXXFLAGS += -O0 -g
else
CFLAGS += -O3 -ffast-math
CXXFLAGS += -O3 -ffast-math
endif
CFLAGS += $(DEF_FLAGS) -Wall -Wno-unused-result -Wno-unused-variable -I. -Ideps
CXXFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -Ideps -std=c++98 -D__STDC_CONSTANT_MACROS
ifeq ($(CXX_BUILD), 1)
CFLAGS += -std=c++98 -xc++ -D__STDC_CONSTANT_MACROS
else
ifneq ($(GNU90_BUILD), 1)
CFLAGS += -std=gnu99
endif
endif
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
all: $(TARGET)
-include $(RARCH_OBJ:.o=.d)
$(TARGET): $(RARCH_OBJ)
@$(if $(Q), $(shell echo echo LD $@),)
$(Q)$(CXX) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LDCXXFLAGS)
#those mkdir shenanigans are really ugly, but I can't find any better solution
$(OBJDIR)/%.o: %.c
@-mkdir -p $(dir $@) || mkdir $(subst /,\,$(dir $@)) || echo .
@$(if $(Q), $(shell echo echo CC $<),)
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -c -o $@ $<
.FORCE:
$(OBJDIR)/git_version.o: git_version.c .FORCE
@-mkdir -p $(dir $@) || mkdir $(subst /,\,$(dir $@)) || echo .
@$(if $(Q), $(shell echo echo CC $<),)
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -c -o $@ $<
$(OBJDIR)/%.o: %.cpp | $(dir $@)
@-mkdir -p $(dir $@) || mkdir $(subst /,\,$(dir $@)) || echo .
@$(if $(Q), $(shell echo echo CXX $<),)
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
$(OBJDIR)/%.o: %.rc $(HEADERS)
@-mkdir -p $(dir $@) || mkdir $(subst /,\,$(dir $@)) || echo .
@$(if $(Q), $(shell echo echo WINDRES $<),)
$(Q)$(WINDRES) -o $@ $<
clean:
rm -rf $(OBJDIR)
rm -f $(TARGET)
rm -f *.d
.PHONY: all install uninstall clean

View File

@ -1,38 +0,0 @@
# RetroArch OMAP video driver
The OMAP video driver for RetroArch uses the omapfb (OMAP framebuffer) driver from the Linux kernel. omapfb is not to be confused with omapdrm, which is the corresponding DRM driver.
OMAP framebuffer support is available on platforms like the Pandora (OMAP3) handheld console, the Beagleboard (OMAP3) single-board computer or the Pandaboard (OMAP4), which is also a single-board computer.
The OMAP display hardware provides free scaling to native screen dimensions, using a high-quality polyphase filter.
## DSS setup
The DSS is the underlying layer, which manages the OMAP display hardware. Through DSS we can setup which framebuffer device outputs to which display device. For example there are three framebuffer devices (fb0, fb1 and fb2) on the Pandaboard, each one connected to a 'overlay' device. The DSS controls are exported in '/sys/devices/platform/omapdss'. Here we configure fb1 to connect to our HDMI display connected to the board.
First we disable the overlay we want to use and the two displays:
echo -n 0 > overlay1/enabled
echo -n 0 > display0/enabled
echo -n 0 > display1/enabled
Check that 'manager1' (name = tv) is connected to HDMI:
cat manager1/display:
hdmi
The free scaling property mentioned above is not available on all overlays. Here 'overlay1' supports zero-cost scaling.
Now we connect 'overlay1' to 'manager1':
echo -n tv > overlay1/manager
Last but not least enable the overlay and the HDMI display:
echo -n 1 > overlay1/enabled
echo -n 1 > display0/enabled
## Configuration
The video driver name is 'omap'. It honors the following video settings:
- video\_monitor\_index (selects the fb device used, index = 1 -> fb0, index = 2 -> fb1, etc.)
- video\_vsync (use to disable vsync, however this is not recommended)

View File

@ -1,60 +0,0 @@
# RetroArch Exynos-G2D video driver
The Exynos-G2D video driver for RetroArch uses the Exynos DRM layer for presentation and the Exynos G2D block to scale and blit the emulator framebuffer to the screen. The G2D subsystem is a separate functional block on modern Samsung Exynos SoCs (in particular Exynos4412 and Exynos5250) that accelerates various kind of 2D blit operations. It can fill, copy, scale and blend pixel buffers and therefore provides adequate functionality for RetroArch purposes.
## Reasons to use the driver
Hardware accelerated rendering on devices based on an Exynos SoC is usually restricted to the use of the GPU block, which is either a Mali or PowerVR IP. Both GPU types have the problem that interfacing with them requires a proprietary driver stack, comprised of kernel and userspace code. While the kernel code is open source, the userspace code is only available as a binary blob to the enduser.
If you want to use such a device with an upstream kernel, the GPU block will most likely not work for you. Also the chances of Mali or PowerVR kernel code being accepted upstream is very slim. Still, one might want to ask the question if using the GPU block for such trivial operations (basically scale and blend) is the right approach in the first place.
Since the G2D block is present on all modern Exynos SoCs, the natural way of proceeding would be to use it instead of the GPU block. The G2D is still a dedicated piece of hardware, so all operations are offloaded from the CPU. It should be noted though, that using the G2D instead of the GPU removes the possibility to use GPU shaders to enhance the image quality of your emulator core of choice. If the user relies on these enhancements, then he's advised to continue using the GPU, most likely by using the EGL/GLES video driver.
The author uses a Hardkernel ODROID-X2, which is an developer board powered by an Exynos4412 SoC. The vendor supplied kernel, a Linux tree based on the 3.8.y branch, currently offers no way to use the G2D because of issues related to clock setup. However upstreaming work is in progress and a tree based on 3.15.y, with some slight modifications, is available from here:
[odroid-3.15.y repository](https://github.com/tobiasjakobi/linux-odroid)
Please refer to the minimalistic documentation in README-ODROID for setup.
## Performance analysis
Some simple benchmarking was done to evaluate the performance of the G2D block. The test run was done with the snes9x-next emulation core and a game title that uses a native resolution of 256x224 pixels. The output screen was configured to a 1280x720 mode. Scaling to the output screen was done by keeping the native aspect ratio. In this case this would result in an output rectangle of size 822x720.
total memcpy calls: 18795
total g2d calls: 18795
total memcpy time: 8.978532 seconds
total g2d time: 29.703944 seconds
average time per memcpy call: 477.708540 microseconds
average time per g2d call: 1580.417345 microseconds
The average time to display the emulator framebuffer on screen is roughly 2058 microseconds, or around 486 frames per second. Assuming that the time consumption increases linearly with the amount of pixels processed, which is usually a safe assumption, scaling to an output rectangle of size 1920x1080 would yield a average duration of 7207 microseconds, which is still 138 frames per second.
## Configuration
The video driver uses the libdrm API to interface with the DRM. Some patches are still missing in the upstream tree, therefore the user is advised to use the 'exynos' branch of the repository mentioned below.
[libdrm repository](https://github.com/tobiasjakobi/libdrm)
Make sure that the Exynos API support is enabled. If you're building libdrm from source, then use
./configure --enable-exynos-experimental-api
to enable it.
The video driver name is 'exynos'. It honors the following video settings:
- video\_monitor\_index
- video\_fullscreen\_x and video\_fullscreen\_y
The monitor index maps to the DRM connector index. If it is zero, then it just selects the first 'sane' connector, which means that it is connected to a display device and it provides at least one useable mode. If the value is non-zero, it forces the selection of this connector. For example, on the author's ODROID-X2, with an odroid-3.15.y kernel, the HDMI connector has index 1.
The two fullscreen parameters select the mode the DRM should select. If zero, the native connector mode is selected. If non-zero, the DRM tries to select the wanted mode. This might fail if the mode is not available from the connector.
## Issues and TODOs
The driver still suffers from some issues.
- The aspect ratio computation can be improved. In particular the user supplied aspect ratio is currently unused.
- Font rendering and blitting is very inefficient since the backing buffer is cleared every frame. Introduce a invalidation rectangle which covers the region where font glyphs are drawn, and then only clear this region. Also consider converting the buffer to A8 color format and using global color (not sure if this is possible).
- Temporary GEM buffers are used as source for blitting operations. Support for the IOMMU has to be enabled, so that one can use the 'userptr' functionality.
- More TODOs are pointed out in the code itself.

View File

@ -1,88 +0,0 @@
USAGE NOTES
===========
This driver is meant for devices with Allwinner SoCs with Mali400 3D block and a
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 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.
So we will use
-This kernel : https://github.com/mireq/linux-sunxi
-This small patch : https://gist.github.com/ssvb/8088519
-Files in this thread : http://forum.odroid.com/viewtopic.php?f=52&t=4956
First we will clone and build the kernel:
git clone https://github.com/mireq/linux-sunxi.git -b sunxi-3.4 --depth 1
Now we edit drivers/video/sunxi/disp/dev_fb.c, and uncomment the line 1074:
// Fb_wait_for_vsync(info);
It is assumed you have a cross-compiler installed, so we configure and build the kernel and modules:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sun7i_defconfig
(This is for Cubieboard2, for other Sunxi boards look here: http://linux-sunxi.org/Linux_Kernel#Compilation)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
(Just in case we want to customize kernel options. It is OK to build with default config)
make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=<path_to_rootfs_mountpoint> modules_install
cp arch/arm/boot/uImage /<path_to_sd_rootfs_mountpoint>/boot/
Now we should download and extract the EGL/GLES/GLES2 MALI FBDEV blobs from this thread:
http://forum.odroid.com/viewtopic.php?f=52&t=4956
This is the exact link:
http://builder.mdrjr.net/tools/r4p0-mp400-fbdev.tar
Copy these libraries to /usr/lib.
Now we need the headers. We can get them from here:
http://malideveloper.arm.com/develop-for-mali/sdks/opengl-es-sdk-for-linux/#opengl-es-sdk-for-linux-download
Download whatever version you want. We just get the headers from here, not machine-dependant compiled code.
Extract the files and copy the directories inside inc to /usr/include .
Also, copy simple_framework/inc/mali/EGL/fbdev_window.h to /usr/include/EGL .
In the end you should have this on your system:
/usr/include/EGL/
eglext.h
egl.h
eglplatform.h
fbdev_window.h
/usr/include/GLES/
glext.h
gl.h
glplatform.h
/usr/include/GLES2
gl2ext.h
gl2.h
gl2platform.h
/usr/include/GLES3
gl3ext.h
gl3.h
gl3platform.h
To enable mali_fbdev you must configure RetroArch with --enable-gles and --enable-mali_fbdev.
This is an example of what you would use on a CubieBoard2 for a lightweight RetroArch:
./configure --enable-gles --enable-mali_fbdev --disable-x11 --disable-sdl2 --enable-floathard --disable-ffmpeg --disable-netplay --enable-udev --disable-sdl --disable-pulse --disable-oss --disable-freetype --disable-7zip
NOTE: A TTY hack is used to auto-clean the console on exit, and the fbdev ioctls are used to retrieve
current video mode. Both things work good, but they are not exactly ideal solutions.
If you come up with something better, feel free to improve the driver.

665
README.md
View File

@ -1,258 +1,493 @@
[![Build Status](https://travis-ci.org/libretro/RetroArch.svg?branch=master)](https://travis-ci.org/libretro/RetroArch)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/8936/badge.svg)](https://scan.coverity.com/projects/retroarch)
# SPIRV-Cross
# RetroArch
SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages.
RetroArch is the reference frontend for the libretro API.
Popular examples of implementations for this API includes video game system emulators and game engines as well as
more generalized 3D programs.
These programs are instantiated as dynamic libraries. We refer to these as "libretro cores".
[![Build Status](https://travis-ci.org/KhronosGroup/SPIRV-Cross.svg?branch=master)](https://travis-ci.org/KhronosGroup/SPIRV-Cross)
[![Build Status](https://ci.appveyor.com/api/projects/status/github/KhronosGroup/SPIRV-Cross?svg=true&branch=master)](https://ci.appveyor.com/project/HansKristian-Work/SPIRV-Cross)
![XMB menu driver](http://i.imgur.com/BMR1xxr.png "XMB menu driver")
## Features
![rgui menu driver](http://i.imgur.com/X3CbBKa.png "rgui menu driver")
- Convert SPIR-V to readable, usable and efficient GLSL
- Convert SPIR-V to readable, usable and efficient Metal Shading Language (MSL)
- Convert SPIR-V to readable, usable and efficient HLSL
- Convert SPIR-V to debuggable C++ [DEPRECATED]
- Convert SPIR-V to a JSON reflection format [EXPERIMENTAL]
- Reflection API to simplify the creation of Vulkan pipeline layouts
- Reflection API to modify and tweak OpDecorations
- Supports "all" of vertex, fragment, tessellation, geometry and compute shaders.
![glui menu driver](http://i.imgur.com/ooqv8rw.png "glui menu driver")
SPIRV-Cross tries hard to emit readable and clean output from the SPIR-V.
The goal is to emit GLSL or MSL that looks like it was written by a human and not awkward IR/assembly-like code.
## libretro
NOTE: Individual features are expected to be mostly complete, but it is possible that certain obscure GLSL features are not yet supported.
However, most missing features are expected to be "trivial" improvements at this stage.
[libretro](http://libretro.com) is an API that exposes generic audio/video/input callbacks.
A frontend for libretro (such as RetroArch) handles video output, audio output, input and application lifecycle.
A libretro core written in portable C or C++ can run seamlessly on many platforms with very little to no porting effort.
## Building
While RetroArch is the reference frontend for libretro, several other projects have used the libretro
interface to include support for emulators and/or game engines. libretro is completely open and free for anyone to use.
SPIRV-Cross has been tested on Linux, iOS/OSX, Windows and Android. CMake is the main build system.
[libretro API header](https://github.com/libretro/RetroArch/blob/master/libretro-common/include/libretro.h)
### Linux and macOS
## Binaries
Building with CMake is recommended, as it is the only build system which is tested in continuous integration.
It is also the only build system which has install commands and other useful build system features.
Latest binaries are currently hosted on the [buildbot](http://buildbot.libretro.com/).
However, you can just run `make` on the command line as a fallback if you only care about the CLI tool.
## Support
A non-ancient GCC (4.8+) or Clang (3.x+) compiler is required as SPIRV-Cross uses C++11 extensively.
To reach developers, either make an issue here on GitHub, make a thread on the [forum](http://www.libretro.com/forums/), chat on [discord](https://discord.gg/C4amCeV), or visit our IRC channel: #retroarch @ irc.freenode.org.
### Windows
## Documentation
Building with CMake is recommended, which is the only way to target MSVC.
MinGW-w64 based compilation works with `make` as a fallback.
See our [Documentation Center](https://docs.libretro.com/). On Unix, man-pages are provided.
More developer-centric stuff is found [here](https://github.com/libretro/libretro.github.com/wiki/Documentation-devs).
### Android
## Related projects
SPIRV-Cross is only useful as a library here. Use the CMake build to link SPIRV-Cross to your project.
- Cg/HLSL shaders: [common-shaders](https://github.com/libretro/common-shaders)
- slang shaders: [slang-shaders](https://github.com/libretro/slang-shaders)
- GLSL shaders: [glsl-shaders](https://github.com/libretro/glsl-shaders)
- Helper scripts to build libretro implementations: [libretro-super](https://github.com/libretro/libretro-super)
- GitHub mirrors of projects, useful for generating diff files: [libretro-mirrors](https://github.com/libretro-mirrors/)
### C++ exceptions
## Philosophy
The make and CMake build flavors offer the option to treat exceptions as assertions. To disable exceptions for make just append `SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=1` to the command line. For CMake append `-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=ON`. By default exceptions are enabled.
RetroArch attempts to be small and lean
while still having all the useful core features expected from an emulator.
It is designed to be very portable and features a gamepad-centric and touchscreen UI.
It also has a full-featured command-line interface.
### Static, shared and CLI
In some areas, RetroArch goes beyond and emphasizes on not-so-common technical features such as multi-pass shader support,
real-time rewind (Braid-style), video recording (using FFmpeg), run-ahead input latency removal, etc.
You can use `-DSPIRV_CROSS_STATIC=ON/OFF` `-DSPIRV_CROSS_SHARED=ON/OFF` `-DSPIRV_CROSS_CLI=ON/OFF` to control which modules are built (and installed).
RetroArch also emphasizes being easy to integrate into various launcher frontends.
## Usage
## Platforms
### Using the C++ API
RetroArch has been ported to the following platforms:
The C++ API is the main API for SPIRV-Cross. For more in-depth documentation than what's provided in this README,
please have a look at the [Wiki](https://github.com/KhronosGroup/SPIRV-Cross/wiki).
**NOTE**: This API is not guaranteed to be ABI-stable, and it is highly recommended to link against this API statically.
The API is generally quite stable, but it can change over time, see the C API for more stability.
- DOS
- Windows
- Linux
- Emscripten (WebAssembly and JavaScript)
- FreeBSD
- NetBSD
- OpenBSD
- Haiku
- Solaris
- macOS (PPC, x86-32 and x86-64)
- PlayStation 3
- PlayStation Portable
- PlayStation Vita
- Original Microsoft Xbox
- Microsoft Xbox 360 (Libxenon/XeXDK)
- Nintendo GameCube
- Nintendo Wii
- Nintendo Wii U
- Nintendo 3DS
- Nintendo Switch
- Nintendo NES/SNES Classic Edition
- Raspberry Pi
- Android
- iOS
- Blackberry
To perform reflection and convert to other shader languages you can use the SPIRV-Cross API.
For example:
## Dependencies (PC)
```c++
#include "spirv_glsl.hpp"
#include <vector>
#include <utility>
There are no true hard dependencies per se.
extern std::vector<uint32_t> load_spirv_file();
On Windows, RetroArch can run with only Win32 as dependency.
int main()
{
// Read SPIR-V from disk or similar.
std::vector<uint32_t> spirv_binary = load_spirv_file();
On Linux, there are no true dependencies. For optimal usage, the
following dependencies come as recommended:
spirv_cross::CompilerGLSL glsl(std::move(spirv_binary));
- GL headers / Vulkan headers
- X11 headers and libs, or EGL/KMS/GBM
// The SPIR-V is now parsed, and we can perform reflection on it.
spirv_cross::ShaderResources resources = glsl.get_shader_resources();
OSX port of RetroArch requires latest versions of XCode to build.
// Get all sampled images in the shader.
for (auto &resource : resources.sampled_images)
{
unsigned set = glsl.get_decoration(resource.id, spv::DecorationDescriptorSet);
unsigned binding = glsl.get_decoration(resource.id, spv::DecorationBinding);
printf("Image %s at set = %u, binding = %u\n", resource.name.c_str(), set, binding);
RetroArch can utilize these libraries if enabled:
// Modify the decoration to prepare it for GLSL.
glsl.unset_decoration(resource.id, spv::DecorationDescriptorSet);
- nvidia-cg-toolkit
- libfreetype2 (TTF font rendering on screen)
// Some arbitrary remapping if we want.
glsl.set_decoration(resource.id, spv::DecorationBinding, set * 16 + binding);
}
RetroArch needs at least one of these audio driver libraries:
// Set some options.
spirv_cross::CompilerGLSL::Options options;
options.version = 310;
options.es = true;
glsl.set_options(options);
- ALSA
- OSS
- RoarAudio
- RSound
- OpenAL
- JACK
- SDL
- PulseAudio
- XAudio2 (Win32, Xbox 360)
- DirectSound (Win32, Xbox 1)
- CoreAudio (OSX, iOS)
// Compile to GLSL, ready to give to GL driver.
std::string source = glsl.compile();
}
```
To run properly, RetroArch requires a libretro implementation present; however, as it's typically loaded
dynamically, it's not required at build time.
### Using the C API wrapper
## Dependencies (Console ports, mobile)
Console ports have their own dependencies, but generally do not require
anything other than what the respective SDKs provide.
## Configuring
The default configuration is defined in `config.def.h`.
It is not recommended to change this unless you know what you're doing.
These can later be tweaked by using a config file.
A sample configuration file is installed to `/etc/retroarch.cfg`. This is the system-wide config file.
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 the `retroarch-joyconfig` command-line tool.
## Compiling and installing
Instructions for compiling and installing RetroArch can be found in the [Libretro/RetroArch Documentation Center](https://docs.libretro.com/).
## CRT 15Khz Resolution Switching
CRT SwitchRes will turn on, on the fly. However, you will need to restart RetroArch to disable it. With CRT SwitchRes enable RetroArch will start in 2560 x 480 @ 60.
If you are running Windows, before enabling the CRT SwitchRes options please make sure you have installed CRTEmudriver and installed some modelines. The minimum modelines for all games to switch correctly are:
- 2560 x 192 @ 60.000000
- 2560 x 200 @ 60.000000
- 2560 x 240 @ 60.000000
- 2560 x 224 @ 60.000000
- 2560 x 237 @ 60.000000
- 2560 x 256 @ 50.000000
- 2560 x 254 @ 55.000000
- 2560 x 448 @ 60.000000
- 2560 x 480 @ 60.000000
Install these modelines replacing 2560 with your desired super resolution. The above resolutions are NTSC only so if you would be playing any PAL content please add PAL modelines:
- 2560 x 192 @ 50.000000
- 2560 x 200 @ 50.000000
- 2560 x 240 @ 50.000000
- 2560 x 224 @ 50.000000
- 2560 x 288 @ 50.000000
- 2560 x 237 @ 50.000000
- 2560 x 254 @ 55.000000
- 2560 x 448 @ 50.000000
- 2560 x 480 @ 50.000000
Some games will require higher PAL resolutions which should also be installed:
- 2560 x 512 @ 50.000000
- 2560 x 576 @ 50.000000
To facilitate C compatibility and compatibility with foreign programming languages, a C89-compatible API wrapper is provided. Unlike the C++ API,
the goal of this wrapper is to be fully stable, both API and ABI-wise.
This is the only interface which is supported when building SPIRV-Cross as a shared library.
Ideally install all these modelines and everything will work great.
An important point of the wrapper is that all memory allocations are contained in the `spvc_context`.
This simplifies the use of the API greatly. However, you should destroy the context as soon as reasonable,
or use `spvc_context_release_allocations()` if you intend to reuse the `spvc_context` object again soon.
## Super Resolutions
Most functions return a `spvc_result`, where `SPVC_SUCCESS` is the only success code.
For brevity, the code below does not do any error checking.
The default super resolution is 2560. It is displayed just under the CRT switch option, which can be found in video settings. This can be changed within the retroarch.cfg. The only compatible resolutions are 1920, 2560 and 3840. Any other resolutions will be ignored and native switching will be activated.
```c
#include <spirv_cross_c.h>
## Native Resolutions
const SpvId *spirv = get_spirv_data();
size_t word_count = get_spirv_word_count();
If native resolutions are activated you will need a whole new set of modelines:
spvc_context context = NULL;
spvc_parsed_ir ir = NULL;
spvc_compiler compiler_glsl = NULL;
spvc_compiler_options options = NULL;
spvc_resources resources = NULL;
const spvc_reflected_resource *list = NULL;
const char *result = NULL;
size_t count;
size_t i;
- 256 x 240 @ 50.006977 SNESpal
- 256 x 448 @ 50.006977 SNESpal
- 512 x 224 @ 50.006977 SNESpal
- 512 x 240 @ 50.006977 SNESpal
- 512 x 448 @ 50.006977 SNESpal
- 256 x 240 @ 60.098812 SNESntsc
- 256 x 448 @ 60.098812 SNESntsc
- 512 x 240 @ 60.098812 SNESntsc
- 512 x 224 @ 60.098812 SNESntsc
- 512 x 448 @ 60.098812 SNESntsc
- 256 x 192 @ 59.922745 MDntsc
- 256 x 224 @ 59.922745 MDntsc
- 320 x 224 @ 59.922745 MDntsc
- 320 x 240 @ 59.922745 MDntsc
- 320 x 448 @ 59.922745 MDntsc
- 320 x 480 @ 59.922745 MDntsc
- 256 x 192 @ 49.701458 MDpal
- 256 x 224 @ 49.701458 MDpal
- 320 x 224 @ 49.701458 MDpal
- 320 x 240 @ 49.701458 MDpal
- 320 x 288 @ 49.701458 MDpal
- 320 x 448 @ 49.701458 MDpal
- 320 x 480 @ 49.701458 MDpal
- 320 x 576 @ 49.701458 MDpal
- 256 x 288 @ 49.701458 MSYSpal
- 256 x 240 @ 60.098812 NESntsc
- 256 x 240 @ 50.006977 NESpal
- 640 x 237 @ 60.130001 N64ntsc
- 640 x 240 @ 60.130001 N64ntsc
- 640 x 480 @ 60.130001 N64ntsc
- 640 x 288 @ 50.000000 N64pal
- 640 x 480 @ 50.000000 N64pal
- 640 x 576 @ 50.000000 N64pal
// Create context.
spvc_context_create(&context);
// Set debug callback.
spvc_context_set_error_callback(context, error_callback, userdata);
// Parse the SPIR-V.
spvc_context_parse_spirv(context, spirv, word_count, &ir);
// Hand it off to a compiler instance and give it ownership of the IR.
spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler_glsl);
// Do some basic reflection.
spvc_compiler_create_shader_resources(compiler_glsl, &resources);
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
for (i = 0; i < count; i++)
{
printf("ID: %u, BaseTypeID: %u, TypeID: %u, Name: %s\n", list[i].id, list[i].base_type_id, list[i].type_id,
list[i].name);
printf(" Set: %u, Binding: %u\n",
spvc_compiler_get_decoration(compiler_glsl, list[i].id, SpvDecorationDescriptorSet),
spvc_compiler_get_decoration(compiler_glsl, list[i].id, SpvDecorationBinding));
}
// Modify options.
spvc_compiler_create_compiler_options(context, &options);
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 330);
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE);
spvc_compiler_install_compiler_options(compiler_glsl, options);
spvc_compiler_compile(compiler, &result);
printf("Cross-compiled source: %s\n", result);
// Frees all memory we allocated so far.
spvc_context_destroy(context);
```
### Linking
#### CMake add_subdirectory()
This is the recommended way if you are using CMake and want to link against SPIRV-Cross statically.
#### Integrating SPIRV-Cross in a custom build system
To add SPIRV-Cross to your own codebase, just copy the source and header files from root directory
and build the relevant .cpp files you need. Make sure to build with C++11 support, e.g. `-std=c++11` in GCC and Clang.
Alternatively, the Makefile generates a libspirv-cross.a static library during build that can be linked in.
#### Linking against SPIRV-Cross as a system library
It is possible to link against SPIRV-Cross when it is installed as a system library,
which would be mostly relevant for Unix-like platforms.
##### pkg-config
For Unix-based systems, a pkg-config is installed for the C API, e.g.:
```
$ pkg-config spirv-cross-c-shared --libs --cflags
-I/usr/local/include/spirv_cross -L/usr/local/lib -lspirv-cross-c-shared
```
##### CMake
If the project is installed, it can be found with `find_package()`, e.g.:
```
cmake_minimum_required(VERSION 3.5)
set(CMAKE_C_STANDARD 99)
project(Test LANGUAGES C)
find_package(spirv_cross_c_shared)
if (spirv_cross_c_shared_FOUND)
message(STATUS "Found SPIRV-Cross C API! :)")
else()
message(STATUS "Could not find SPIRV-Cross C API! :(")
endif()
add_executable(test test.c)
target_link_libraries(test spirv-cross-c-shared)
```
test.c:
```c
#include <spirv_cross_c.h>
int main(void)
{
spvc_context context;
spvc_context_create(&context);
spvc_context_destroy(context);
}
```
### CLI
The CLI is suitable for basic cross-compilation tasks, but it cannot support the full flexibility that the API can.
Some examples below.
#### Creating a SPIR-V file from GLSL with glslang
```
glslangValidator -H -V -o test.spv test.frag
```
#### Converting a SPIR-V file to GLSL ES
```
glslangValidator -H -V -o test.spv shaders/comp/basic.comp
./spirv-cross --version 310 --es test.spv
```
#### Converting to desktop GLSL
```
glslangValidator -H -V -o test.spv shaders/comp/basic.comp
./spirv-cross --version 330 --no-es test.spv --output test.comp
```
#### Disable prettifying optimizations
```
glslangValidator -H -V -o test.spv shaders/comp/basic.comp
./spirv-cross --version 310 --es test.spv --output test.comp --force-temporary
```
### Using shaders generated from C++ backend
Please see `samples/cpp` where some GLSL shaders are compiled to SPIR-V, decompiled to C++ and run with test data.
Reading through the samples should explain how to use the C++ interface.
A simple Makefile is included to build all shaders in the directory.
### Implementation notes
When using SPIR-V and SPIRV-Cross as an intermediate step for cross-compiling between high level languages there are some considerations to take into account,
as not all features used by one high-level language are necessarily supported natively by the target shader language.
SPIRV-Cross aims to provide the tools needed to handle these scenarios in a clean and robust way, but some manual action is required to maintain compatibility.
#### HLSL source to GLSL
##### HLSL entry points
When using SPIR-V shaders compiled from HLSL, there are some extra things you need to take care of.
First make sure that the entry point is used correctly.
If you forget to set the entry point correctly in glslangValidator (-e MyFancyEntryPoint),
you will likely encounter this error message:
```
Cannot end a function before ending the current block.
Likely cause: If this SPIR-V was created from glslang HLSL, make sure the entry point is valid.
```
##### Vertex/Fragment interface linking
HLSL relies on semantics in order to effectively link together shader stages. In the SPIR-V generated by glslang, the transformation from HLSL to GLSL ends up looking like
```c++
struct VSOutput {
// SV_Position is rerouted to gl_Position
float4 position : SV_Position;
float4 coord : TEXCOORD0;
};
VSOutput main(...) {}
```
```c++
struct VSOutput {
float4 coord;
}
layout(location = 0) out VSOutput _magicNameGeneratedByGlslang;
```
While this works, be aware of the type of the struct which is used in the vertex stage and the fragment stage.
There may be issues if the structure type name differs in vertex stage and fragment stage.
You can make use of the reflection interface to force the name of the struct type.
```
// Something like this for both vertex outputs and fragment inputs.
compiler.set_name(varying_resource.base_type_id, "VertexFragmentLinkage");
```
Some platform may require identical variable name for both vertex outputs and fragment inputs. (for example MacOSX)
to rename varaible base on location, please add
```
--rename-interface-variable <in|out> <location> <new_variable_name>
```
#### HLSL source to legacy GLSL/ESSL
HLSL tends to emit varying struct types to pass data between vertex and fragment.
This is not supported in legacy GL/GLES targets, so to support this, varying structs are flattened.
This is done automatically, but the API user might need to be aware that this is happening in order to support all cases.
Modern GLES code like this:
```c++
struct Output {
vec4 a;
vec2 b;
};
out Output vout;
```
Is transformed into:
```c++
struct Output {
vec4 a;
vec2 b;
};
varying vec4 Output_a;
varying vec2 Output_b;
```
Note that now, both the struct name and the member names will participate in the linking interface between vertex and fragment, so
API users might want to ensure that both the struct names and member names match so that vertex outputs and fragment inputs can link properly.
#### Separate image samplers (HLSL/Vulkan) for backends which do not support it (GLSL)
Another thing you need to remember is when using samplers and textures in HLSL these are separable, and not directly compatible with GLSL. If you need to use this with desktop GL/GLES, you need to call `Compiler::build_combined_image_samplers` first before calling `Compiler::compile`, or you will get an exception.
```c++
// From main.cpp
// Builds a mapping for all combinations of images and samplers.
compiler->build_combined_image_samplers();
// Give the remapped combined samplers new names.
// Here you can also set up decorations if you want (binding = #N).
for (auto &remap : compiler->get_combined_image_samplers())
{
compiler->set_name(remap.combined_id, join("SPIRV_Cross_Combined", compiler->get_name(remap.image_id),
compiler->get_name(remap.sampler_id)));
}
```
If your target is Vulkan GLSL, `--vulkan-semantics` will emit separate image samplers as you'd expect.
The command line client calls `Compiler::build_combined_image_samplers` automatically, but if you're calling the library, you'll need to do this yourself.
#### Descriptor sets (Vulkan GLSL) for backends which do not support them (HLSL/GLSL/Metal)
Descriptor sets are unique to Vulkan, so make sure that descriptor set + binding is remapped to a flat binding scheme (set always 0), so that other APIs can make sense of the bindings.
This can be done with `Compiler::set_decoration(id, spv::DecorationDescriptorSet)`.
#### Linking by name for targets which do not support explicit locations (legacy GLSL/ESSL)
Modern GLSL and HLSL sources (and SPIR-V) relies on explicit layout(location) qualifiers to guide the linking process between shader stages,
but older GLSL relies on symbol names to perform the linking. When emitting shaders with older versions, these layout statements will be removed,
so it is important that the API user ensures that the names of I/O variables are sanitized so that linking will work properly.
The reflection API can rename variables, struct types and struct members to deal with these scenarios using `Compiler::set_name` and friends.
#### Clip-space conventions
SPIRV-Cross can perform some common clip space conversions on gl_Position/SV_Position by enabling `CompilerGLSL::Options.vertex.fixup_clipspace`.
While this can be convenient, it is recommended to modify the projection matrices instead as that can achieve the same result.
For GLSL targets, enabling this will convert a shader which assumes `[0, w]` depth range (Vulkan / D3D / Metal) into `[-w, w]` range.
For MSL and HLSL targets, enabling this will convert a shader in `[-w, w]` depth range (OpenGL) to `[0, w]` depth range.
By default, the CLI will not enable `fixup_clipspace`, but in the API you might want to set an explicit value using `CompilerGLSL::set_options()`.
Y-flipping of gl_Position and similar is also supported.
The use of this is discouraged, because relying on vertex shader Y-flipping tends to get quite messy.
To enable this, set `CompilerGLSL::Options.vertex.flip_vert_y` or `--flip-vert-y` in CLI.
## Contributing
Contributions to SPIRV-Cross are welcome. See Testing and Licensing sections for details.
### Testing
SPIRV-Cross maintains a test suite of shaders with reference output of how the output looks after going through a roundtrip through
glslangValidator/spirv-as then back through SPIRV-Cross again.
The reference files are stored inside the repository in order to be able to track regressions.
All pull requests should ensure that test output does not change unexpectedly. This can be tested with:
```
./checkout_glslang_spirv_tools.sh # Checks out glslang and SPIRV-Tools at a fixed revision which matches the reference output.
# NOTE: Some users have reported problems cloning from git:// paths. To use https:// instead pass in
# $ PROTOCOL=https ./checkout_glslang_spirv_tools.sh
# instead.
./build_glslang_spirv_tools.sh # Builds glslang and SPIRV-Tools.
./test_shaders.sh # Runs over all changes and makes sure that there are no deltas compared to reference files.
```
`./test_shaders.sh` currently requires a Makefile setup with GCC/Clang to be set up.
However, on Windows, this can be rather inconvenient if a MinGW environment is not set up.
To use a spirv-cross binary you built with CMake (or otherwise), you can pass in an environment variable as such:
```
SPIRV_CROSS_PATH=path/to/custom/spirv-cross ./test_shaders.sh
```
However, when improving SPIRV-Cross there are of course legitimate cases where reference output should change.
In these cases, run:
```
./update_test_shaders.sh # SPIRV_CROSS_PATH also works here.
```
to update the reference files and include these changes as part of the pull request.
Always make sure you are running the correct version of glslangValidator as well as SPIRV-Tools when updating reference files.
See `checkout_glslang_spirv_tools.sh` which revisions are currently expected. The revisions change regularly.
In short, the master branch should always be able to run `./test_shaders.py shaders` and friends without failure.
SPIRV-Cross uses Travis CI to test all pull requests, so it is not strictly needed to perform testing yourself if you have problems running it locally.
A pull request which does not pass testing on Travis will not be accepted however.
When adding support for new features to SPIRV-Cross, a new shader and reference file should be added which covers usage of the new shader features in question.
Travis CI runs the test suite with the CMake, by running `ctest`. This is a more straight-forward alternative to `./test_shaders.sh`.
### Licensing
Contributors of new files should add a copyright header at the top of every new source code file with their copyright
along with the Apache 2.0 licensing stub.
### Formatting
SPIRV-Cross uses `clang-format` to automatically format code.
Please use `clang-format` with the style sheet found in `.clang-format` to automatically format code before submitting a pull request.
To make things easy, the `format_all.sh` script can be used to format all
source files in the library. In this directory, run the following from the
command line:
./format_all.sh
## Regression testing
In shaders/ a collection of shaders are maintained for purposes of regression testing.
The current reference output is contained in reference/.
`./test_shaders.py shaders` can be run to perform regression testing.
See `./test_shaders.py --help` for more.
### Metal backend
To test the roundtrip path GLSL -> SPIR-V -> MSL, `--msl` can be added, e.g. `./test_shaders.py --msl shaders-msl`.
### HLSL backend
To test the roundtrip path GLSL -> SPIR-V -> HLSL, `--hlsl` can be added, e.g. `./test_shaders.py --hlsl shaders-hlsl`.
### Updating regression tests
When legitimate changes are found, use `--update` flag to update regression files.
Otherwise, `./test_shaders.py` will fail with error code.
### Mali Offline Compiler cycle counts
To obtain a CSV of static shader cycle counts before and after going through spirv-cross, add
`--malisc` flag to `./test_shaders`. This requires the Mali Offline Compiler to be installed in PATH.
- 256 x 252 @ 49.759998 PSXpal
- 320 x 252 @ 49.759998 PSXpal
- 384 x 252 @ 49.759998 PSXpal
- 640 x 252 @ 49.759998 PSXpal
- 640 x 540 @ 49.759998 PSXpal
- 384 x 240 @ 59.941002 PSXntsc
- 256 x 480 @ 59.941002 PSXntsc
- 352 x 240 @ 59.820000 Saturn/SGFX_NTSCp
- 704 x 240 @ 59.820000 SaturnNTSCp
- 352 x 480 @ 59.820000 SaturnNTSCi
- 704 x 480 @ 59.820000 SaturnNTSCi
- 352 x 288 @ 49.701458 SaturnPALp
- 704 x 288 @ 49.701458 SaturnPALp
- 352 x 576 @ 49.701458 SaturnPALi
- 704 x 576 @ 49.701458 SaturnPALi
- 240 x 160 @ 59.730000 GBA
- 320 x 200 @ 60.000000 Doom
// Arcade
- 400 x 254 @ 54.706841 MK
- 384 x 224 @ 59.637405 CPS1
These modelines are more accurate giving exact hz. However, some games may have unwanted results. This is due to mid-scanline resolution changes on the original hardware. For the best results super resolutions are the way to go.
## CRT resolution switching & MAME
Some arcade resolutions can be very different from consumer CRTs. There is resolution detection to ensure MAME games will be displayed in the closest available resolution but drawn at their native resolution within this resolution. Meaning that the MAME game will look just like the original hardware.
MAME ROMs that run in a vertical aspect like DoDonPachi need to be rotated within MAME before resolution switching and aspect correction will work. Do this before enabling CRT SwitchRes so that RetroArch will run in your desktop resolution. Once you have rotated any games that may need it turn CRT SwitchRes on.

View File

@ -1,88 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 __AUDIO_DEFINES__H
#define __AUDIO_DEFINES__H
#include <retro_common_api.h>
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 + 4)
/* 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_BGM
};
enum audio_action
{
AUDIO_ACTION_NONE = 0,
AUDIO_ACTION_RATE_CONTROL_DELTA,
AUDIO_ACTION_MIXER_MUTE_ENABLE,
AUDIO_ACTION_MUTE_ENABLE,
AUDIO_ACTION_VOLUME_GAIN,
AUDIO_ACTION_MIXER_VOLUME_GAIN,
AUDIO_ACTION_MIXER
};
enum audio_mixer_slot_selection_type
{
AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC = 0,
AUDIO_MIXER_SLOT_SELECTION_MANUAL
};
enum audio_mixer_stream_type
{
AUDIO_STREAM_TYPE_NONE = 0,
AUDIO_STREAM_TYPE_USER,
AUDIO_STREAM_TYPE_SYSTEM
};
enum audio_mixer_state
{
AUDIO_STREAM_STATE_NONE = 0,
AUDIO_STREAM_STATE_STOPPED,
AUDIO_STREAM_STATE_PLAYING,
AUDIO_STREAM_STATE_PLAYING_LOOPED,
AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL
};
typedef struct audio_statistics
{
float average_buffer_saturation;
float std_deviation_percentage;
float close_to_underrun;
float close_to_blocking;
unsigned samples;
} audio_statistics_t;
RETRO_END_DECLS
#endif

View File

@ -1,327 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <queues/fifo_queue.h>
#include <rthreads/rthreads.h>
#include "audio_thread_wrapper.h"
#include "../verbosity.h"
typedef struct audio_thread
{
const audio_driver_t *driver;
void *driver_data;
sthread_t *thread;
slock_t *lock;
scond_t *cond;
bool alive;
bool stopped;
bool stopped_ack;
bool is_paused;
bool is_shutdown;
bool use_float;
int inited;
/* Initialization options. */
const char *device;
unsigned *new_rate;
unsigned out_rate;
unsigned latency;
unsigned block_frames;
} audio_thread_t;
static void audio_thread_loop(void *data)
{
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return;
RARCH_LOG("[Audio Thread]: Initializing audio driver.\n");
thr->driver_data = thr->driver->init(thr->device, thr->out_rate, thr->latency,
thr->block_frames, thr->new_rate);
slock_lock(thr->lock);
thr->inited = thr->driver_data ? 1 : -1;
if (thr->inited > 0 && thr->driver->use_float)
thr->use_float = thr->driver->use_float(thr->driver_data);
scond_signal(thr->cond);
slock_unlock(thr->lock);
if (thr->inited < 0)
return;
/* Wait until we start to avoid calling
* stop immediately after initialization. */
slock_lock(thr->lock);
while (thr->stopped)
scond_wait(thr->cond, thr->lock);
slock_unlock(thr->lock);
RARCH_LOG("[Audio Thread]: Starting audio.\n");
for (;;)
{
slock_lock(thr->lock);
if (!thr->alive)
{
scond_signal(thr->cond);
thr->stopped_ack = true;
slock_unlock(thr->lock);
break;
}
if (thr->stopped)
{
thr->driver->stop(thr->driver_data);
while (thr->stopped)
{
/* If we stop right after start, we might not be able to properly ack.
* Signal in the loop instead. */
thr->stopped_ack = true;
scond_signal(thr->cond);
scond_wait(thr->cond, thr->lock);
}
thr->driver->start(thr->driver_data, thr->is_shutdown);
}
slock_unlock(thr->lock);
audio_driver_callback();
}
RARCH_LOG("[Audio Thread]: Tearing down driver.\n");
thr->driver->free(thr->driver_data);
}
static void audio_thread_block(audio_thread_t *thr)
{
if (!thr)
return;
if (thr->stopped)
return;
slock_lock(thr->lock);
thr->stopped_ack = false;
thr->stopped = true;
scond_signal(thr->cond);
/* Wait until audio driver actually goes to sleep. */
while (!thr->stopped_ack)
scond_wait(thr->cond, thr->lock);
slock_unlock(thr->lock);
}
static void audio_thread_unblock(audio_thread_t *thr)
{
if (!thr)
return;
slock_lock(thr->lock);
thr->stopped = false;
scond_signal(thr->cond);
slock_unlock(thr->lock);
}
static void audio_thread_free(void *data)
{
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return;
if (thr->thread)
{
slock_lock(thr->lock);
thr->stopped = false;
thr->alive = false;
scond_signal(thr->cond);
slock_unlock(thr->lock);
sthread_join(thr->thread);
}
if (thr->lock)
slock_free(thr->lock);
if (thr->cond)
scond_free(thr->cond);
free(thr);
}
static bool audio_thread_alive(void *data)
{
bool alive = false;
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return false;
audio_thread_block(thr);
alive = !thr->is_paused;
audio_thread_unblock(thr);
return alive;
}
static bool audio_thread_stop(void *data)
{
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return false;
audio_thread_block(thr);
thr->is_paused = true;
audio_driver_disable_callback();
return true;
}
static bool audio_thread_start(void *data, bool is_shutdown)
{
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return false;
audio_driver_enable_callback();
thr->is_paused = false;
thr->is_shutdown = is_shutdown;
audio_thread_unblock(thr);
return true;
}
static void audio_thread_set_nonblock_state(void *data, bool state)
{
(void)data;
(void)state;
}
static bool audio_thread_use_float(void *data)
{
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return false;
return thr->use_float;
}
static ssize_t audio_thread_write(void *data, const void *buf, size_t size)
{
ssize_t ret;
audio_thread_t *thr = (audio_thread_t*)data;
if (!thr)
return 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 ret;
}
static const audio_driver_t audio_thread = {
NULL,
audio_thread_write,
audio_thread_stop,
audio_thread_start,
audio_thread_alive,
audio_thread_set_nonblock_state,
audio_thread_free,
audio_thread_use_float,
"audio-thread",
NULL, /* No point in using rate control with threaded audio. */
NULL,
};
/**
* audio_init_thread:
* @out_driver : output driver
* @out_data : output audio data
* @device : audio device (optional)
* @out_rate : output audio rate
* @latency : audio latency
* @driver : audio driver
*
* Starts a audio driver in a new thread.
* Access to audio driver will be mediated through this driver.
* This driver interfaces with audio callback and is
* only used in that case.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool audio_init_thread(const audio_driver_t **out_driver,
void **out_data, const char *device, unsigned audio_out_rate,
unsigned *new_rate, unsigned latency,
unsigned block_frames, const audio_driver_t *drv)
{
audio_thread_t *thr = (audio_thread_t*)calloc(1, sizeof(*thr));
if (!thr)
return false;
thr->driver = (const audio_driver_t*)drv;
thr->device = device;
thr->out_rate = audio_out_rate;
thr->new_rate = new_rate;
thr->latency = latency;
thr->block_frames = block_frames;
if (!(thr->cond = scond_new()))
goto error;
if (!(thr->lock = slock_new()))
goto error;
thr->alive = true;
thr->stopped = true;
if (!(thr->thread = sthread_create(audio_thread_loop, thr)))
goto error;
/* Wait until thread has initialized (or failed) the driver. */
slock_lock(thr->lock);
while (!thr->inited)
scond_wait(thr->cond, thr->lock);
slock_unlock(thr->lock);
if (thr->inited < 0) /* Thread failed. */
goto error;
*out_driver = &audio_thread;
*out_data = thr;
return true;
error:
*out_driver = NULL;
*out_data = NULL;
audio_thread_free(thr);
return false;
}

View File

@ -1,45 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 RARCH_AUDIO_THREAD_H__
#define RARCH_AUDIO_THREAD_H__
#include <boolean.h>
#include "../retroarch.h"
/**
* audio_init_thread:
* @out_driver : output driver
* @out_data : output audio data
* @device : audio device (optional)
* @out_rate : output audio rate
* @new_rate : new output audio rate
* @latency : audio latency
* @driver : audio driver
*
* Starts a audio driver in a new thread.
* Access to audio driver will be mediated through this driver.
* This driver interfaces with audio callback and is only used in that case.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool audio_init_thread(const audio_driver_t **out_driver, void **out_data,
const char *device, unsigned out_rate, unsigned *new_rate, unsigned latency,
unsigned block_frames,
const audio_driver_t *driver);
#endif

View File

@ -1,431 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <lists/string_list.h>
#include <string/stdstring.h>
#include <alsa/asoundlib.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
typedef struct alsa
{
snd_pcm_t *pcm;
size_t buffer_size;
bool nonblock;
unsigned int frame_bits;
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->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_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)
return NULL;
if (device)
alsa_dev = device;
if (snd_pcm_open(
&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0)
goto error;
if (snd_pcm_hw_params_malloc(&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_any(alsa->pcm, params) < 0)
goto error;
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");
if (params)
snd_pcm_hw_params_free(params);
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 ssize_t alsa_write(void *data, const void *buf_, size_t size_)
{
alsa_t *alsa = (alsa_t*)data;
const uint8_t *buf = (const uint8_t*)buf_;
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)
if (!alsa_start(alsa, false))
return -1;
if (alsa->nonblock)
{
while (size)
{
snd_pcm_sframes_t frames = snd_pcm_writei(alsa->pcm, buf, size);
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
{
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
return -1;
break;
}
else if (frames == -EAGAIN)
break;
else if (frames < 0)
return -1;
written += frames;
buf += (frames << 1) * frames_size;
size -= frames;
}
}
else
{
bool eagain_retry = true;
while (size)
{
snd_pcm_sframes_t frames;
int rc = snd_pcm_wait(alsa->pcm, -1);
if (rc == -EPIPE || rc == -ESTRPIPE || rc == -EINTR)
{
if (snd_pcm_recover(alsa->pcm, rc, 1) < 0)
return -1;
continue;
}
frames = snd_pcm_writei(alsa->pcm, buf, size);
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
{
if (snd_pcm_recover(alsa->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;
written += frames;
buf += (frames << 1) * frames_size;
size -= frames;
}
}
return written;
}
static bool alsa_alive(void *data)
{
alsa_t *alsa = (alsa_t*)data;
if (!alsa)
return false;
return !alsa->is_paused;
}
static bool alsa_stop(void *data)
{
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, 1);
if (ret < 0)
return false;
alsa->is_paused = true;
}
return true;
}
static void alsa_set_nonblock_state(void *data, bool state)
{
alsa_t *alsa = (alsa_t*)data;
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)
{
if (alsa->pcm)
{
snd_pcm_drop(alsa->pcm);
snd_pcm_close(alsa->pcm);
snd_config_update_free_global();
}
free(alsa);
}
}
static size_t alsa_write_avail(void *data)
{
alsa_t *alsa = (alsa_t*)data;
snd_pcm_sframes_t avail = snd_pcm_avail(alsa->pcm);
if (avail < 0)
return alsa->buffer_size;
return FRAMES_TO_BYTES(avail, alsa->frame_bits);
}
static size_t alsa_buffer_size(void *data)
{
alsa_t *alsa = (alsa_t*)data;
return alsa->buffer_size;
}
static void *alsa_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 != NULL)
{
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_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_alsa = {
alsa_init,
alsa_write,
alsa_stop,
alsa_start,
alsa_alive,
alsa_set_nonblock_state,
alsa_free,
alsa_use_float,
"alsa",
alsa_device_list_new,
alsa_device_list_free,
alsa_write_avail,
alsa_buffer_size,
};

View File

@ -1,382 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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/>.
*/
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <sys/asoundlib.h>
#include <retro_math.h>
#include "../../retroarch.h"
#define MAX_FRAG_SIZE 3072
#define DEFAULT_RATE 48000
#define CHANNELS 2
typedef struct alsa
{
uint8_t **buffer;
uint8_t *buffer_chunk;
unsigned buffer_index;
unsigned buffer_ptr;
volatile unsigned buffered_blocks;
snd_pcm_t *pcm;
bool nonblock;
bool has_float;
bool can_pause;
bool is_paused;
unsigned buf_size;
unsigned buf_count;
} alsa_qsa_t;
typedef long snd_pcm_sframes_t;
static void *alsa_qsa_init(const char *device,
unsigned rate, unsigned latency, unsigned block_frames,
unsigned *new_rate)
{
int err, card, dev, i;
snd_pcm_channel_info_t pi;
snd_pcm_channel_params_t params = {0};
snd_pcm_channel_setup_t setup = {0};
alsa_qsa_t *alsa = (alsa_qsa_t*)calloc(1, sizeof(alsa_qsa_t));
if (!alsa)
return NULL;
(void)device;
(void)rate;
(void)latency;
if ((err = snd_pcm_open_preferred(&alsa->pcm, &card, &dev,
SND_PCM_OPEN_PLAYBACK)) < 0)
{
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",
snd_strerror(err));
goto error;
}
memset(&pi, 0, sizeof(pi));
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",
snd_strerror(err));
goto error;
}
memset(&params, 0, sizeof(params));
params.channel = SND_PCM_CHANNEL_PLAYBACK;
params.mode = SND_PCM_MODE_BLOCK;
params.format.interleave = 1;
params.format.format = SND_PCM_SFMT_S16_LE;
params.format.rate = DEFAULT_RATE;
params.format.voices = 2;
params.start_mode = SND_PCM_START_FULL;
params.stop_mode = SND_PCM_STOP_STOP;
params.buf.block.frag_size = pi.max_fragment_size;
params.buf.block.frags_min = 2;
params.buf.block.frags_max = 8;
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, &params)) < 0)
{
RARCH_ERR("[ALSA QSA]: Channel Parameter Error: %s\n",
snd_strerror(err));
goto error;
}
setup.channel = SND_PCM_CHANNEL_PLAYBACK;
if ((err = snd_pcm_channel_setup(alsa->pcm, &setup)) < 0)
{
RARCH_ERR("[ALSA QSA]: Channel Parameter Read Back Error: %s\n",
snd_strerror(err));
goto error;
}
if (block_frames)
alsa->buf_size = block_frames * 4;
else
alsa->buf_size = next_pow2(32 * latency);
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;
if ((err = snd_pcm_channel_prepare(alsa->pcm,
SND_PCM_CHANNEL_PLAYBACK)) < 0)
{
RARCH_ERR("[ALSA QSA]: Channel Prepare Error: %s\n",
snd_strerror(err));
goto error;
}
alsa->buffer = (uint8_t**)calloc(sizeof(uint8_t*), alsa->buf_count);
if (!alsa->buffer)
goto error;
alsa->buffer_chunk = (uint8_t*)calloc(alsa->buf_count, alsa->buf_size);
if (!alsa->buffer_chunk)
goto error;
for (i = 0; i < alsa->buf_count; i++)
alsa->buffer[i] = alsa->buffer_chunk + i * alsa->buf_size;
alsa->has_float = false;
alsa->can_pause = true;
RARCH_LOG("[ALSA QSA]: Can pause: %s.\n",
alsa->can_pause ? "yes" : "no");
return alsa;
error:
return (void*)-1;
}
static int check_pcm_status(void *data, int channel_type)
{
snd_pcm_channel_status_t status;
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
int ret = EOK;
memset(&status, 0, sizeof (status));
status.channel = channel_type;
if ((ret = snd_pcm_channel_status(alsa->pcm, &status)) == 0)
{
if (status.status == SND_PCM_STATUS_UNSECURE)
{
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("check_pcm_status: SNDP_CM_STATUS_UNDERRUN.\n");
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
{
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("check_pcm_status: SNDP_CM_STATUS_OVERRUN.\n");
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
{
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("check_pcm_status: SNDP_CM_STATUS_CHANGE.\n");
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
{
RARCH_ERR("Invalid state detected for change on snd_pcm_channel_prepare: %s\n",
snd_strerror(ret));
ret = -EPROTO;
}
}
}
else
{
RARCH_ERR("check_pcm_status failed: %s\n", snd_strerror(ret));
if (ret == -ESRCH)
ret = -EBADF;
}
return ret;
}
static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size)
{
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, size);
if (avail_write)
{
memcpy(alsa->buffer[alsa->buffer_index] +
alsa->buffer_ptr, buf, avail_write);
alsa->buffer_ptr += avail_write;
buf = (void*)((uint8_t*)buf + avail_write);
size -= avail_write;
written += avail_write;
}
if (alsa->buffer_ptr >= alsa->buf_size)
{
snd_pcm_sframes_t frames = snd_pcm_write(alsa->pcm,
alsa->buffer[alsa->buffer_index], alsa->buf_size);
alsa->buffer_index = (alsa->buffer_index + 1) % alsa->buf_count;
alsa->buffer_ptr = 0;
if (frames <= 0)
{
int ret;
if (frames == -EAGAIN)
continue;
ret = check_pcm_status(alsa, SND_PCM_CHANNEL_PLAYBACK);
if (ret == -EPROTO || ret == -EBADF)
return -1;
}
}
}
return written;
}
static bool alsa_qsa_stop(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
if (alsa->can_pause && !alsa->is_paused)
{
int ret = snd_pcm_playback_pause(alsa->pcm);
if (ret < 0)
return false;
alsa->is_paused = true;
}
return true;
}
static bool alsa_qsa_alive(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
if (alsa)
return !alsa->is_paused;
return false;
}
static bool alsa_qsa_start(void *data, bool is_shutdown)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
if (alsa->can_pause && alsa->is_paused)
{
int ret = snd_pcm_playback_resume(alsa->pcm);
if (ret < 0)
{
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n",
snd_strerror(ret));
return false;
}
alsa->is_paused = false;
}
return true;
}
static void alsa_qsa_set_nonblock_state(void *data, bool state)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
int err;
if((err = snd_pcm_nonblock_mode(alsa->pcm, state)) < 0)
{
RARCH_ERR("Can't set blocking mode to %d: %s\n", state,
snd_strerror(err));
return;
}
alsa->nonblock = state;
}
static bool alsa_qsa_use_float(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
return alsa->has_float;
}
static void alsa_qsa_free(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
if (alsa)
{
if (alsa->pcm)
{
snd_pcm_close(alsa->pcm);
alsa->pcm = NULL;
}
free(alsa->buffer);
free(alsa->buffer_chunk);
free(alsa);
}
}
static size_t alsa_qsa_write_avail(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
size_t avail = (alsa->buf_count -
(int)alsa->buffered_blocks - 1) * alsa->buf_size +
(alsa->buf_size - (int)alsa->buffer_ptr);
return avail;
}
static size_t alsa_qsa_buffer_size(void *data)
{
alsa_qsa_t *alsa = (alsa_qsa_t*)data;
return alsa->buf_size * alsa->buf_count;
}
audio_driver_t audio_alsa = {
alsa_qsa_init,
alsa_qsa_write,
alsa_qsa_stop,
alsa_qsa_start,
alsa_qsa_alive,
alsa_qsa_set_nonblock_state,
alsa_qsa_free,
alsa_qsa_use_float,
"alsa",
NULL,
NULL,
alsa_qsa_write_avail,
alsa_qsa_buffer_size,
};

View File

@ -1,420 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2012-2015 - Michael Lelli
*
* 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 <lists/string_list.h>
#include <alsa/asoundlib.h>
#include <rthreads/rthreads.h>
#include <queues/fifo_queue.h>
#include <string/stdstring.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
#define TRY_ALSA(x) if (x < 0) \
goto error;
typedef struct alsa_thread
{
snd_pcm_t *pcm;
bool nonblock;
bool is_paused;
bool has_float;
volatile bool thread_dead;
size_t buffer_size;
size_t period_size;
snd_pcm_uframes_t period_frames;
fifo_buffer_t *buffer;
sthread_t *worker_thread;
slock_t *fifo_lock;
scond_t *cond;
slock_t *cond_lock;
} 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->period_size);
if (!buf)
{
RARCH_ERR("failed to allocate audio buffer");
goto end;
}
while (!alsa->thread_dead)
{
size_t avail;
size_t fifo_size;
snd_pcm_sframes_t frames;
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->period_size - fifo_size);
frames = snd_pcm_writei(alsa->pcm, buf, alsa->period_frames);
if (frames == -EPIPE || frames == -EINTR ||
frames == -ESTRPIPE)
{
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
{
RARCH_ERR("[ALSA]: (#2) Failed to recover from error (%s)\n",
snd_strerror(frames));
break;
}
continue;
}
else if (frames < 0)
{
RARCH_ERR("[ALSA]: Unknown error occurred (%s).\n",
snd_strerror(frames));
break;
}
}
end:
slock_lock(alsa->cond_lock);
alsa->thread_dead = true;
scond_signal(alsa->cond);
slock_unlock(alsa->cond_lock);
free(buf);
}
static bool alsa_thread_use_float(void *data)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
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)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
if (alsa)
{
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);
}
}
static void *alsa_thread_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
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)
return NULL;
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));
TRY_ALSA(snd_pcm_hw_params_malloc(&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_any(alsa->pcm, params));
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->worker_thread = sthread_create(alsa_worker_thread, alsa);
if (!alsa->worker_thread)
{
RARCH_ERR("error initializing worker thread");
goto error;
}
return alsa;
error:
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 *buf, size_t size)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
if (alsa->thread_dead)
return -1;
if (alsa->nonblock)
{
size_t avail;
size_t write_amt;
slock_lock(alsa->fifo_lock);
avail = fifo_write_avail(alsa->buffer);
write_amt = MIN(avail, size);
fifo_write(alsa->buffer, buf, write_amt);
slock_unlock(alsa->fifo_lock);
return write_amt;
}
else
{
size_t written = 0;
while (written < size && !alsa->thread_dead)
{
size_t avail;
slock_lock(alsa->fifo_lock);
avail = fifo_write_avail(alsa->buffer);
if (avail == 0)
{
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(size - written, avail);
fifo_write(alsa->buffer,
(const char*)buf + written, write_amt);
slock_unlock(alsa->fifo_lock);
written += write_amt;
}
}
return written;
}
}
static bool alsa_thread_alive(void *data)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
if (!alsa)
return false;
return !alsa->is_paused;
}
static bool alsa_thread_stop(void *data)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
if (alsa)
alsa->is_paused = true;
return true;
}
static void alsa_thread_set_nonblock_state(void *data, bool state)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
alsa->nonblock = state;
}
static bool alsa_thread_start(void *data, bool is_shutdown)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
if (alsa)
alsa->is_paused = false;
return true;
}
static size_t alsa_thread_write_avail(void *data)
{
alsa_thread_t *alsa = (alsa_thread_t*)data;
size_t val;
if (alsa->thread_dead)
return 0;
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->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 != NULL)
{
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 = {
alsa_thread_init,
alsa_thread_write,
alsa_thread_stop,
alsa_thread_start,
alsa_thread_alive,
alsa_thread_set_nonblock_state,
alsa_thread_free,
alsa_thread_use_float,
"alsathread",
alsa_thread_device_list_new,
alsa_thread_device_list_free,
alsa_thread_write_avail,
alsa_thread_buffer_size,
};

View File

@ -1,212 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/audioio.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../../retroarch.h"
#include "../../verbosity.h"
#define DEFAULT_DEV "/dev/audio"
static void *audioio_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_out_rate)
{
int *fd = (int*)calloc(1, sizeof(int));
const char *audiodev = device ? device : DEFAULT_DEV;
struct audio_info info;
if (!fd)
return NULL;
AUDIO_INITINFO(&info);
#ifdef AUMODE_PLAY_ALL
info.mode = AUMODE_PLAY_ALL;
#elif defined(AUMODE_PLAY)
info.mode = AUMODE_PLAY;
#endif
info.play.sample_rate = rate;
info.play.channels = 2;
info.play.precision = 16;
#ifdef AUDIO_ENCODING_SLINEAR
info.play.encoding = AUDIO_ENCODING_SLINEAR;
#else
info.play.encoding = AUDIO_ENCODING_LINEAR;
#endif
if ((*fd = open(audiodev, O_WRONLY)) < 0)
{
free(fd);
perror("open");
return NULL;
}
if (ioctl(*fd, AUDIO_SETINFO, &info) < 0)
goto error;
if (ioctl(*fd, AUDIO_GETINFO, &info) < 0)
goto error;
*new_out_rate = info.play.sample_rate;
return fd;
error:
close(*fd);
free(fd);
perror("ioctl");
return NULL;
}
static ssize_t audioio_write(void *data, const void *buf, size_t size)
{
ssize_t ret;
int *fd = (int*)data;
if (size == 0)
return 0;
if ((ret = write(*fd, buf, size)) < 0)
{
if (errno == EAGAIN && (fcntl(*fd, F_GETFL) & O_NONBLOCK))
return 0;
return -1;
}
return ret;
}
static bool audioio_stop(void *data)
{
struct audio_info info;
int *fd = (int*)data;
#ifdef AUDIO_FLUSH
if (ioctl(*fd, AUDIO_FLUSH, NULL) < 0)
return false;
#endif
if (ioctl(*fd, AUDIO_GETINFO, &info) < 0)
return false;
info.play.pause = true;
return ioctl(*fd, AUDIO_SETINFO, &info) == 0;
}
static bool audioio_start(void *data, bool is_shutdown)
{
struct audio_info info;
int *fd = (int*)data;
#ifdef AUDIO_FLUSH
if (ioctl(*fd, AUDIO_FLUSH, NULL) < 0)
return false;
#endif
if (ioctl(*fd, AUDIO_GETINFO, &info) < 0)
return false;
info.play.pause = false;
return ioctl(*fd, AUDIO_SETINFO, &info) == 0;
}
static bool audioio_alive(void *data)
{
struct audio_info info;
int *fd = (int*)data;
if (ioctl(*fd, AUDIO_GETINFO, &info) < 0)
return false;
return !info.play.pause;
}
static void audioio_set_nonblock_state(void *data, bool state)
{
int rc;
int *fd = (int*)data;
if (state)
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
else
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & (~O_NONBLOCK));
if (rc != 0)
RARCH_WARN("Could not set nonblocking on audio file descriptor. Will not be able to fast-forward.\n");
}
static void audioio_free(void *data)
{
int *fd = (int*)data;
#ifdef AUDIO_FLUSH
(void)ioctl(*fd, AUDIO_FLUSH, NULL);
#endif
close(*fd);
free(fd);
}
static size_t audioio_buffer_size(void *data)
{
struct audio_info info;
int *fd = (int*)data;
if (ioctl(*fd, AUDIO_GETINFO, &info) < 0)
return false;
return info.play.buffer_size;
}
static size_t audioio_write_avail(void *data)
{
return audioio_buffer_size(data);
}
static bool audioio_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_audioio = {
audioio_init,
audioio_write,
audioio_stop,
audioio_start,
audioio_alive,
audioio_set_nonblock_state,
audioio_free,
audioio_use_float,
"audioio",
NULL,
NULL,
audioio_write_avail,
audioio_buffer_size,
};

View File

@ -1,464 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Chris Moeller
*
* 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>
#if TARGET_OS_IPHONE
#include <AudioToolbox/AudioToolbox.h>
#else
#include <CoreAudio/CoreAudio.h>
#endif
#include <CoreAudio/CoreAudioTypes.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioUnit/AUComponent.h>
#include <boolean.h>
#include <queues/fifo_queue.h>
#include <rthreads/rthreads.h>
#include <retro_endianness.h>
#include <string/stdstring.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
typedef struct coreaudio
{
slock_t *lock;
scond_t *cond;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
ComponentInstance dev;
#else
AudioComponentInstance dev;
#endif
bool dev_alive;
bool is_paused;
fifo_buffer_t *buffer;
bool nonblock;
size_t buffer_size;
} coreaudio_t;
static bool g_interrupted;
static void coreaudio_free(void *data)
{
coreaudio_t *dev = (coreaudio_t*)data;
if (!dev)
return;
if (dev->dev_alive)
{
AudioOutputUnitStop(dev->dev);
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
CloseComponent(dev->dev);
#else
AudioComponentInstanceDispose(dev->dev);
#endif
}
if (dev->buffer)
fifo_free(dev->buffer);
slock_free(dev->lock);
scond_free(dev->cond);
free(dev);
}
static OSStatus audio_write_cb(void *userdata,
AudioUnitRenderActionFlags *action_flags,
const AudioTimeStamp *time_stamp, UInt32 bus_number,
UInt32 number_frames, AudioBufferList *io_data)
{
unsigned write_avail;
void *outbuf = NULL;
coreaudio_t *dev = (coreaudio_t*)userdata;
(void)time_stamp;
(void)bus_number;
(void)number_frames;
if (!io_data || io_data->mNumberBuffers != 1)
return noErr;
write_avail = io_data->mBuffers[0].mDataByteSize;
outbuf = io_data->mBuffers[0].mData;
slock_lock(dev->lock);
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;
}
fifo_read(dev->buffer, outbuf, write_avail);
slock_unlock(dev->lock);
scond_signal(dev->cond);
return noErr;
}
#if TARGET_OS_IPHONE
static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
{
(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;
propaddr.mSelector = kAudioHardwarePropertyDevices;
#if MAC_OS_X_VERSION_10_12
propaddr.mScope = kAudioObjectPropertyScopeOutput;
#else
propaddr.mScope = kAudioObjectPropertyScopeGlobal;
#endif
propaddr.mElement = kAudioObjectPropertyElementMaster;
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
&propaddr, 0, 0, &size) != noErr)
return;
deviceCount = size / sizeof(AudioDeviceID);
devices = (AudioDeviceID*)malloc(size);
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject,
&propaddr, 0, 0, &size, devices) != noErr)
goto done;
#if MAC_OS_X_VERSION_10_12
#else
propaddr.mScope = kAudioDevicePropertyScopeOutput;
#endif
propaddr.mSelector = kAudioDevicePropertyDeviceName;
for (i = 0; i < deviceCount; i ++)
{
char device_name[1024];
device_name[0] = 0;
size = 1024;
if (AudioObjectGetPropertyData(devices[i],
&propaddr, 0, 0, &size, device_name) == noErr
&& string_is_equal(device_name, device))
{
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
goto done;
}
}
done:
free(devices);
}
#endif
static void *coreaudio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
size_t fifo_size;
UInt32 i_size;
AudioStreamBasicDescription real_desc;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
Component comp;
#else
AudioComponent comp;
#endif
#ifndef TARGET_OS_IPHONE
AudioChannelLayout layout = {0};
#endif
AURenderCallbackStruct cb = {0};
AudioStreamBasicDescription stream_desc = {0};
bool component_unavailable = false;
static bool session_initialized = false;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
ComponentDescription desc = {0};
#else
AudioComponentDescription desc = {0};
#endif
coreaudio_t *dev = (coreaudio_t*)
calloc(1, sizeof(*dev));
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
desc.componentSubType = kAudioUnitSubType_RemoteIO;
#else
desc.componentSubType = kAudioUnitSubType_HALOutput;
#endif
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
comp = FindNextComponent(NULL, &desc);
#else
comp = AudioComponentFindNext(NULL, &desc);
#endif
if (comp == NULL)
goto error;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
component_unavailable = (OpenAComponent(comp, &dev->dev) != noErr);
#else
component_unavailable = (AudioComponentInstanceNew(comp, &dev->dev) != noErr);
#endif
if (component_unavailable)
goto error;
#if !TARGET_OS_IPHONE
if (device)
choose_output_device(dev, device);
#endif
dev->dev_alive = true;
/* Set audio format */
stream_desc.mSampleRate = rate;
stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT;
stream_desc.mChannelsPerFrame = 2;
stream_desc.mBytesPerPacket = 2 * sizeof(float);
stream_desc.mBytesPerFrame = 2 * sizeof(float);
stream_desc.mFramesPerPacket = 1;
stream_desc.mFormatID = kAudioFormatLinearPCM;
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)
goto error;
/* Check returned audio format. */
i_size = sizeof(real_desc);
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
goto error;
if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame)
goto error;
if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel)
goto error;
if (real_desc.mFormatFlags != stream_desc.mFormatFlags)
goto error;
if (real_desc.mFormatID != stream_desc.mFormatID)
goto error;
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n",
(float)real_desc.mSampleRate);
*new_rate = real_desc.mSampleRate;
/* Set channel layout (fails on iOS). */
#ifndef TARGET_OS_IPHONE
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout,
kAudioUnitScope_Input, 0, &layout, sizeof(layout)) != noErr)
goto error;
#endif
/* Set callbacks and finish up. */
cb.inputProc = audio_write_cb;
cb.inputProcRefCon = dev;
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &cb, sizeof(cb)) != noErr)
goto error;
if (AudioUnitInitialize(dev->dev) != noErr)
goto error;
fifo_size = (latency * (*new_rate)) / 1000;
fifo_size *= 2 * sizeof(float);
dev->buffer_size = 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",
(unsigned)fifo_size, latency);
if (AudioOutputUnitStart(dev->dev) != noErr)
goto error;
return dev;
error:
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 size)
{
coreaudio_t *dev = (coreaudio_t*)data;
const uint8_t *buf = (const uint8_t*)buf_;
size_t written = 0;
while (!g_interrupted && size > 0)
{
size_t write_avail;
slock_lock(dev->lock);
write_avail = fifo_write_avail(dev->buffer);
if (write_avail > size)
write_avail = size;
fifo_write(dev->buffer, buf, write_avail);
buf += write_avail;
written += write_avail;
size -= write_avail;
if (dev->nonblock)
{
slock_unlock(dev->lock);
break;
}
#if TARGET_OS_IPHONE
if (write_avail == 0 && !scond_wait_timeout(
dev->cond, dev->lock, 3000000))
g_interrupted = true;
#else
if (write_avail == 0)
scond_wait(dev->cond, dev->lock);
#endif
slock_unlock(dev->lock);
}
return written;
}
static void coreaudio_set_nonblock_state(void *data, bool state)
{
coreaudio_t *dev = (coreaudio_t*)data;
if (dev)
dev->nonblock = state;
}
static bool coreaudio_alive(void *data)
{
coreaudio_t *dev = (coreaudio_t*)data;
if (!dev)
return false;
return !dev->is_paused;
}
static bool coreaudio_stop(void *data)
{
coreaudio_t *dev = (coreaudio_t*)data;
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)
return false;
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
return dev->is_paused ? false : true;
}
static bool coreaudio_use_float(void *data)
{
(void)data;
return true;
}
static size_t coreaudio_write_avail(void *data)
{
size_t avail;
coreaudio_t *dev = (coreaudio_t*)data;
slock_lock(dev->lock);
avail = fifo_write_avail(dev->buffer);
slock_unlock(dev->lock);
return avail;
}
static size_t coreaudio_buffer_size(void *data)
{
coreaudio_t *dev = (coreaudio_t*)data;
return dev->buffer_size;
}
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,
coreaudio_write,
coreaudio_stop,
coreaudio_start,
coreaudio_alive,
coreaudio_set_nonblock_state,
coreaudio_free,
coreaudio_use_float,
"coreaudio",
coreaudio_device_list_new,
coreaudio_device_list_free,
coreaudio_write_avail,
coreaudio_buffer_size,
};

View File

@ -1,392 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2019 - Stuart Carnie
*
* 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/>.
*/
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#include <stdio.h>
#include <stdatomic.h>
#include <stdlib.h>
#include <memory.h>
#include "../../retroarch.h"
#pragma mark - ringbuffer
typedef struct ringbuffer
{
float *buffer;
size_t cap;
atomic_int len;
size_t writePtr;
size_t readPtr;
} ringbuffer_t;
typedef ringbuffer_t * ringbuffer_h;
static inline size_t rb_len(ringbuffer_h r)
{
return atomic_load_explicit(&r->len, memory_order_relaxed);
}
static inline size_t rb_cap(ringbuffer_h r)
{
return (r->readPtr + r->cap - r->writePtr) % r->cap;
}
static inline size_t rb_avail(ringbuffer_h r)
{
return r->cap - rb_len(r);
}
static inline void rb_advance_write(ringbuffer_h r)
{
r->writePtr = (r->writePtr + 1) % r->cap;
}
static inline void rb_advance_write_n(ringbuffer_h r, size_t n)
{
r->writePtr = (r->writePtr + n) % r->cap;
}
static inline void rb_advance_read(ringbuffer_h r)
{
r->readPtr = (r->readPtr + 1) % r->cap;
}
static inline void rb_len_add(ringbuffer_h r, int n)
{
atomic_fetch_add(&r->len, n);
}
static inline void rb_len_sub(ringbuffer_h r, int n)
{
atomic_fetch_sub(&r->len, n);
}
static void rb_init(ringbuffer_h r, size_t cap)
{
r->buffer = malloc(cap * sizeof(float));
r->cap = cap;
atomic_init(&r->len, 0);
r->writePtr = 0;
r->readPtr = 0;
}
static void rb_free(ringbuffer_h r)
{
free(r->buffer);
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);
size_t n = MIN(len, avail);
size_t first_write = n;
size_t rest_write = 0;
if (r->writePtr + n > r->cap)
{
first_write = r->cap - r->writePtr;
rest_write = n - first_write;
}
memcpy(r->buffer + r->writePtr, data, first_write*sizeof(float));
memcpy(r->buffer, data + first_write, rest_write*sizeof(float));
rb_advance_write_n(r, n);
rb_len_add(r, (int)n);
}
static void rb_read_data(ringbuffer_h r,
float *d0, float *d1, size_t len)
{
size_t need = len * 2;
do {
size_t have = rb_len(r);
size_t n = MIN(have, need);
int i = 0;
for (; i < n/2; i++)
{
d0[i] = r->buffer[r->readPtr];
rb_advance_read(r);
d1[i] = r->buffer[r->readPtr];
rb_advance_read(r);
}
need -= n;
rb_len_sub(r, (int)n);
if (UNLIKELY(need > 0))
{
const float quiet = 0.0f;
size_t fill;
/* we got more data */
if (rb_len(r) > 0)
continue;
/* underflow */
fill = (need/2)*sizeof(float);
memset_pattern4(&d0[i], &quiet, fill);
memset_pattern4(&d1[i], &quiet, fill);
}
} while (0);
}
#pragma mark - CoreAudio3
static bool g_interrupted;
@interface CoreAudio3 : NSObject {
ringbuffer_t _rb;
dispatch_semaphore_t _sema;
AUAudioUnit *_au;
size_t _bufferSize;
BOOL _nonBlock;
}
@property (nonatomic, readwrite) BOOL nonBlock;
@property (nonatomic, readonly) BOOL paused;
@property (nonatomic, readonly) size_t writeAvailableInBytes;
@property (nonatomic, readonly) size_t bufferSizeInBytes;
- (instancetype)initWithRate:(NSUInteger)rate
latency:(NSUInteger)latency;
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples;
- (void)start;
- (void)stop;
@end
@implementation CoreAudio3
- (instancetype)initWithRate:(NSUInteger)rate
latency:(NSUInteger)latency {
if (self = [super init])
{
NSError *err;
AUAudioUnit *au;
AudioComponentDescription desc;
AVAudioFormat *format, *renderFormat;
_sema = dispatch_semaphore_create(0);
_bufferSize = (latency * rate) / 1000;
_bufferSize *= 2; /* stereo */
rb_init(&_rb, _bufferSize);
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err];
if (err != nil)
return nil;
format = au.outputBusses[0].format;
if (format.channelCount != 2)
return nil;
renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2];
[au.inputBusses[0] setFormat:renderFormat error:&err];
if (err != nil)
return nil;
ringbuffer_h rb = &_rb;
__block dispatch_semaphore_t sema = _sema;
au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData)
{
rb_read_data(rb, inputData->mBuffers[0].mData, inputData->mBuffers[1].mData, frameCount);
dispatch_semaphore_signal(sema);
return 0;
};
[au allocateRenderResourcesAndReturnError:&err];
if (err != nil)
return nil;
_au = au;
RARCH_LOG("[CoreAudio3]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)self.bufferSizeInBytes, latency);
[self start];
}
return self;
}
- (void)dealloc {
rb_free(&_rb);
}
- (BOOL)paused {
return !_au.running;
}
- (size_t)bufferSizeInBytes {
return _bufferSize * sizeof(float);
}
- (size_t)writeAvailableInBytes {
return rb_avail(&_rb) * sizeof(float);
}
- (void)start {
NSError *err;
[_au startHardwareAndReturnError:&err];
}
- (void)stop {
[_au stopHardware];
}
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
size_t written = 0;
while (!g_interrupted && samples > 0)
{
size_t write_avail = rb_avail(&_rb);
if (write_avail > samples)
write_avail = samples;
rb_write_data(&_rb, data, write_avail);
data += write_avail;
written += write_avail;
samples -= write_avail;
if (_nonBlock)
break;
if (write_avail == 0)
dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
}
return written;
}
@end
static void coreaudio3_free(void *data)
{
CoreAudio3 *dev = (__bridge_transfer CoreAudio3 *)data;
if (dev == nil)
return;
[dev stop];
dev = nil;
}
static void *coreaudio3_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
CoreAudio3 *dev = [[CoreAudio3 alloc] initWithRate:rate
latency:latency];
*new_rate = rate;
return (__bridge_retained void *)dev;
}
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:size/sizeof(float)] * sizeof(float);
}
static void coreaudio3_set_nonblock_state(void *data, bool state)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return;
dev.nonBlock = state;
}
static bool coreaudio3_alive(void *data)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return NO;
return !dev.paused;
}
static bool coreaudio3_stop(void *data)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return NO;
[dev stop];
return dev.paused;
}
static bool coreaudio3_start(void *data, bool is_shutdown)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return NO;
[dev start];
return !dev.paused;
}
static bool coreaudio3_use_float(void *data)
{
return YES;
}
static size_t coreaudio3_write_avail(void *data)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return 0;
return dev.writeAvailableInBytes;
}
static size_t coreaudio3_buffer_size(void *data)
{
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
if (dev == nil)
return 0;
return dev.bufferSizeInBytes;
}
audio_driver_t audio_coreaudio3 = {
coreaudio3_init,
coreaudio3_write,
coreaudio3_stop,
coreaudio3_start,
coreaudio3_alive,
coreaudio3_set_nonblock_state,
coreaudio3_free,
coreaudio3_use_float,
"coreaudio3",
NULL, /* device_list_new */
NULL, /* device_list_free */
coreaudio3_write_avail,
coreaudio3_buffer_size,
};

View File

@ -1,305 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Ali Bouhlel
*
* 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 <3ds.h>
#include <string.h>
#include <malloc.h>
#include <retro_miscellaneous.h>
#include <retro_timers.h>
#include "../../retroarch.h"
typedef struct
{
bool nonblocking;
bool playing;
int16_t* l;
int16_t* r;
uint32_t l_paddr;
uint32_t r_paddr;
uint32_t pos;
uint32_t playpos;
uint64_t cpu_ticks_last;
} ctr_csnd_audio_t;
#define CTR_CSND_AUDIO_COUNT (1u << 11u)
#define CTR_CSND_AUDIO_COUNT_MASK (CTR_CSND_AUDIO_COUNT - 1u)
#define CTR_CSND_AUDIO_SIZE (CTR_CSND_AUDIO_COUNT * sizeof(int16_t))
#define CTR_CSND_AUDIO_SIZE_MASK (CTR_CSND_AUDIO_SIZE - 1u)
#define CTR_CSND_AUDIO_RATE 32730
#define CTR_CSND_TICKS_PER_SAMPLE 2048
#define CTR_CSND_CPU_TICKS_PER_SAMPLE (CTR_CSND_TICKS_PER_SAMPLE * 4)
static void ctr_csnd_audio_update_playpos(ctr_csnd_audio_t* ctr)
{
uint64_t current_tick = svcGetSystemTick();
uint32_t samples_played = (current_tick - ctr->cpu_ticks_last)
/ CTR_CSND_CPU_TICKS_PER_SAMPLE;
ctr->playpos = (ctr->playpos + samples_played) & CTR_CSND_AUDIO_COUNT_MASK;
ctr->cpu_ticks_last += samples_played * CTR_CSND_CPU_TICKS_PER_SAMPLE;
}
Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan,
void* data0, void* data1, u32 size)
{
u32 paddr0 = 0;
u32 paddr1 = 0;
int encoding = (flags >> 12) & 3;
int loopMode = (flags >> 10) & 3;
if (!(csndChannels & BIT(chn)))
return 1;
if (!loopMode)
flags |= SOUND_ONE_SHOT;
if (encoding != CSND_ENCODING_PSG)
{
if (data0)
paddr0 = osConvertVirtToPhys(data0);
if (data1)
paddr1 = osConvertVirtToPhys(data1);
if (data0 && encoding == CSND_ENCODING_ADPCM)
{
int adpcmSample = ((s16*)data0)[-2];
int adpcmIndex = ((u8*)data0)[-2];
CSND_SetAdpcmState(chn, 0, adpcmSample, adpcmIndex);
}
}
flags &= ~0xFFFF001F;
flags |= SOUND_ENABLE | SOUND_CHANNEL(chn) | (CTR_CSND_TICKS_PER_SAMPLE << 16);
u32 volumes = CSND_VOL(vol, pan);
CSND_SetChnRegs(flags, paddr0, paddr1, size, volumes, volumes);
if (loopMode == CSND_LOOPMODE_NORMAL && paddr1 > paddr0)
{
/* Now that the first block is playing,
* configure the size of the subsequent blocks */
size -= paddr1 - paddr0;
CSND_SetBlock(chn, 1, paddr1, size);
}
return 0;
}
static void *ctr_csnd_audio_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
ctr_csnd_audio_t *ctr = (ctr_csnd_audio_t*)calloc(1, sizeof(ctr_csnd_audio_t));
if (!ctr)
return NULL;
(void)device;
(void)rate;
(void)latency;
*new_rate = CTR_CSND_AUDIO_RATE;
ctr->l = linearAlloc(CTR_CSND_AUDIO_SIZE);
ctr->r = linearAlloc(CTR_CSND_AUDIO_SIZE);
memset(ctr->l, 0, CTR_CSND_AUDIO_SIZE);
memset(ctr->r, 0, CTR_CSND_AUDIO_SIZE);
ctr->l_paddr = osConvertVirtToPhys(ctr->l);
ctr->r_paddr = osConvertVirtToPhys(ctr->r);
ctr->pos = 0;
GSPGPU_FlushDataCache((void*)ctr->l_paddr, CTR_CSND_AUDIO_SIZE);
GSPGPU_FlushDataCache((void*)ctr->r_paddr, CTR_CSND_AUDIO_SIZE);
csndPlaySound_custom(0x8, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
1.0, -1.0, ctr->l, ctr->l, CTR_CSND_AUDIO_SIZE);
csndPlaySound_custom(0x9, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
1.0, 1.0, ctr->r, ctr->r, CTR_CSND_AUDIO_SIZE);
csndExecCmds(true);
ctr->playpos = 0;
ctr->cpu_ticks_last = svcGetSystemTick();
ctr->playing = true;
return ctr;
}
static void ctr_csnd_audio_free(void *data)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
#if 0
csndExit();
#endif
CSND_SetPlayState(0x8, 0);
CSND_SetPlayState(0x9, 0);
csndExecCmds(false);
linearFree(ctr->l);
linearFree(ctr->r);
free(ctr);
}
static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size)
{
int i;
uint32_t samples_played = 0;
uint64_t current_tick = 0;
const uint16_t *src = buf;
ctr_csnd_audio_t *ctr = (ctr_csnd_audio_t*)data;
(void)data;
(void)buf;
(void)samples_played;
(void)current_tick;
ctr_csnd_audio_update_playpos(ctr);
if((((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 2)) ||
(((ctr->pos - ctr->playpos ) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)) ||
(((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (size >> 2)))
{
if (ctr->nonblocking)
ctr->pos = (ctr->playpos + (CTR_CSND_AUDIO_COUNT >> 1)) & CTR_CSND_AUDIO_COUNT_MASK;
else
{
do{
/* todo: compute the correct sleep period */
retro_sleep(1);
ctr_csnd_audio_update_playpos(ctr);
}while (((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 1)
|| (((ctr->pos - ctr->playpos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)));
}
}
for (i = 0; i < (size >> 1); i += 2)
{
ctr->l[ctr->pos] = src[i];
ctr->r[ctr->pos] = src[i + 1];
ctr->pos++;
ctr->pos &= CTR_CSND_AUDIO_COUNT_MASK;
}
GSPGPU_FlushDataCache(ctr->l, CTR_CSND_AUDIO_SIZE);
GSPGPU_FlushDataCache(ctr->r, CTR_CSND_AUDIO_SIZE);
return size;
}
static bool ctr_csnd_audio_stop(void *data)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
/* using SetPlayState would make tracking the playback
* position more difficult */
#if 0
CSND_SetPlayState(0x8, 0);
CSND_SetPlayState(0x9, 0);
#endif
/* setting the channel volume to 0 seems to make it
* impossible to set it back to full volume later */
CSND_SetVol(0x8, 0x00000001, 0);
CSND_SetVol(0x9, 0x00010000, 0);
csndExecCmds(false);
ctr->playing = false;
return true;
}
static bool ctr_csnd_audio_alive(void *data)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
return ctr->playing;
}
static bool ctr_csnd_audio_start(void *data, bool is_shutdown)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
/* Prevents restarting audio when the menu
* is toggled off on shutdown */
if (is_shutdown)
return true;
#if 0
CSND_SetPlayState(0x8, 1);
CSND_SetPlayState(0x9, 1);
#endif
CSND_SetVol(0x8, 0x00008000, 0);
CSND_SetVol(0x9, 0x80000000, 0);
csndExecCmds(false);
ctr->playing = true;
return true;
}
static void ctr_csnd_audio_set_nonblock_state(void *data, bool state)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
if (ctr)
ctr->nonblocking = state;
}
static bool ctr_csnd_audio_use_float(void *data)
{
(void)data;
return false;
}
static size_t ctr_csnd_audio_write_avail(void *data)
{
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
ctr_csnd_audio_update_playpos(ctr);
return (ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK;
}
static size_t ctr_csnd_audio_buffer_size(void *data)
{
(void)data;
return CTR_CSND_AUDIO_COUNT;
}
audio_driver_t audio_ctr_csnd = {
ctr_csnd_audio_init,
ctr_csnd_audio_write,
ctr_csnd_audio_stop,
ctr_csnd_audio_start,
ctr_csnd_audio_alive,
ctr_csnd_audio_set_nonblock_state,
ctr_csnd_audio_free,
ctr_csnd_audio_use_float,
"csnd",
NULL,
NULL,
ctr_csnd_audio_write_avail,
ctr_csnd_audio_buffer_size
};

View File

@ -1,212 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Ali Bouhlel
*
* 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 <3ds.h>
#include <string.h>
#include <malloc.h>
#include "../../retroarch.h"
#include "../../ctr/ctr_debug.h"
typedef struct
{
bool nonblocking;
bool playing;
int channel;
ndspWaveBuf dsp_buf;
uint32_t pos;
} ctr_dsp_audio_t;
#define CTR_DSP_AUDIO_COUNT (1u << 11u)
#define CTR_DSP_AUDIO_COUNT_MASK (CTR_DSP_AUDIO_COUNT - 1u)
#define CTR_DSP_AUDIO_SIZE (CTR_DSP_AUDIO_COUNT * sizeof(int16_t) * 2)
#define CTR_DSP_AUDIO_SIZE_MASK (CTR_DSP_AUDIO_SIZE - 1u)
static void *ctr_dsp_audio_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
ctr_dsp_audio_t *ctr = NULL;
(void)device;
(void)rate;
(void)latency;
if (ndspInit() < 0)
return NULL;
ctr = (ctr_dsp_audio_t*)calloc(1, sizeof(ctr_dsp_audio_t));
if (!ctr)
return NULL;
*new_rate = 32730;
ctr->channel = 0;
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetClippingMode(NDSP_CLIP_SOFT); /* ?? */
ndspSetOutputCount(1);
ndspChnReset(ctr->channel);
ndspChnSetFormat(ctr->channel, NDSP_FORMAT_STEREO_PCM16);
ndspChnSetInterp(ctr->channel, NDSP_INTERP_NONE);
ndspChnSetRate(ctr->channel, 32728.0f);
ndspChnWaveBufClear(ctr->channel);
ctr->dsp_buf.data_pcm16 = linearAlloc(CTR_DSP_AUDIO_SIZE);
memset(ctr->dsp_buf.data_pcm16, 0, CTR_DSP_AUDIO_SIZE);
DSP_FlushDataCache(ctr->dsp_buf.data_pcm16, CTR_DSP_AUDIO_SIZE);
ctr->dsp_buf.looping = true;
ctr->dsp_buf.nsamples = CTR_DSP_AUDIO_COUNT;
ndspChnWaveBufAdd(ctr->channel, &ctr->dsp_buf);
ctr->pos = 0;
ctr->playing = true;
ndspSetMasterVol(1.0);
return ctr;
}
static void ctr_dsp_audio_free(void *data)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
ndspChnWaveBufClear(ctr->channel);
linearFree(ctr->dsp_buf.data_pcm16);
free(ctr);
ndspExit();
}
static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
{
u32 pos;
ctr_dsp_audio_t * ctr = (ctr_dsp_audio_t*)data;
uint32_t sample_pos = ndspChnGetSamplePos(ctr->channel);
if((((sample_pos - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK) < (CTR_DSP_AUDIO_COUNT >> 2)) ||
(((ctr->pos - sample_pos ) & CTR_DSP_AUDIO_COUNT_MASK) < (CTR_DSP_AUDIO_COUNT >> 4)) ||
(((sample_pos - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK) < (size >> 2)))
{
if (ctr->nonblocking)
ctr->pos = (sample_pos + (CTR_DSP_AUDIO_COUNT >> 1)) & CTR_DSP_AUDIO_COUNT_MASK;
else
{
do{
svcSleepThread(100000);
sample_pos = ndspChnGetSamplePos(ctr->channel);
}while (((sample_pos - (ctr->pos + (size >>2))) & CTR_DSP_AUDIO_COUNT_MASK) > (CTR_DSP_AUDIO_COUNT >> 1)
|| (((ctr->pos - (CTR_DSP_AUDIO_COUNT >> 4) - sample_pos) & CTR_DSP_AUDIO_COUNT_MASK) > (CTR_DSP_AUDIO_COUNT >> 1)));
}
}
pos = ctr->pos << 2;
if((pos + size) > CTR_DSP_AUDIO_SIZE)
{
memcpy(ctr->dsp_buf.data_pcm8 + pos, buf,
(CTR_DSP_AUDIO_SIZE - pos));
DSP_FlushDataCache(ctr->dsp_buf.data_pcm8 + pos, (CTR_DSP_AUDIO_SIZE - pos));
memcpy(ctr->dsp_buf.data_pcm8, (uint8_t*) buf + (CTR_DSP_AUDIO_SIZE - pos),
(pos + size - CTR_DSP_AUDIO_SIZE));
DSP_FlushDataCache(ctr->dsp_buf.data_pcm8, (pos + size - CTR_DSP_AUDIO_SIZE));
}
else
{
memcpy(ctr->dsp_buf.data_pcm8 + pos, buf, size);
DSP_FlushDataCache(ctr->dsp_buf.data_pcm8 + pos, size);
}
ctr->pos += size >> 2;
ctr->pos &= CTR_DSP_AUDIO_COUNT_MASK;
return size;
}
static bool ctr_dsp_audio_stop(void *data)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
ndspSetMasterVol(0.0);
ctr->playing = false;
return true;
}
static bool ctr_dsp_audio_alive(void *data)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
return ctr->playing;
}
static bool ctr_dsp_audio_start(void *data, bool is_shutdown)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
/* Prevents restarting audio when the menu
* is toggled off on shutdown */
if (is_shutdown)
return true;
ndspSetMasterVol(1.0);
ctr->playing = true;
return true;
}
static void ctr_dsp_audio_set_nonblock_state(void *data, bool state)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
if (ctr)
ctr->nonblocking = state;
}
static bool ctr_dsp_audio_use_float(void *data)
{
(void)data;
return false;
}
static size_t ctr_dsp_audio_write_avail(void *data)
{
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
return (ndspChnGetSamplePos(ctr->channel) - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK;
}
static size_t ctr_dsp_audio_buffer_size(void *data)
{
(void)data;
return CTR_DSP_AUDIO_COUNT;
}
audio_driver_t audio_ctr_dsp = {
ctr_dsp_audio_init,
ctr_dsp_audio_write,
ctr_dsp_audio_stop,
ctr_dsp_audio_start,
ctr_dsp_audio_alive,
ctr_dsp_audio_set_nonblock_state,
ctr_dsp_audio_free,
ctr_dsp_audio_use_float,
"dsp",
NULL,
NULL,
ctr_dsp_audio_write_avail,
ctr_dsp_audio_buffer_size
};

View File

@ -1,529 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#ifndef _XBOX
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#endif
#include <dsound.h>
#include <boolean.h>
#include <retro_inline.h>
#include <retro_miscellaneous.h>
#include <retro_timers.h>
#ifdef HAVE_THREADS
#include <rthreads/rthreads.h>
#endif
#include <queues/fifo_queue.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
#ifdef _XBOX
#define DSERR_BUFFERLOST MAKE_DSHRESULT(150)
#define DSERR_INVALIDPARAM E_INVALIDARG
#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70)
#endif
#if defined(_MSC_VER) && !defined(_XBOX)
#pragma comment(lib, "dsound")
#pragma comment(lib, "dxguid")
#endif
typedef struct dsound
{
LPDIRECTSOUND ds;
LPDIRECTSOUNDBUFFER dsb;
fifo_buffer_t *buffer;
CRITICAL_SECTION crit;
HANDLE event;
#ifdef HAVE_THREADS
sthread_t *thread;
#else
HANDLE thread;
#endif
unsigned buffer_size;
bool nonblock;
bool is_paused;
volatile bool thread_alive;
} dsound_t;
static INLINE unsigned write_avail(unsigned read_ptr,
unsigned write_ptr, unsigned buffer_size)
{
return (read_ptr + buffer_size - write_ptr) % buffer_size;
}
static INLINE void get_positions(dsound_t *ds, DWORD *read_ptr, DWORD *write_ptr)
{
IDirectSoundBuffer_GetCurrentPosition(ds->dsb, read_ptr, write_ptr);
}
#define CHUNK_SIZE 256
struct audio_lock
{
void *chunk1;
void *chunk2;
DWORD size1;
DWORD size2;
};
static INLINE bool grab_region(dsound_t *ds, uint32_t write_ptr,
struct audio_lock *region)
{
const char *err = NULL;
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
&region->chunk1, &region->size1, &region->chunk2, &region->size2, 0);
if (res == DSERR_BUFFERLOST)
{
res = IDirectSoundBuffer_Restore(ds->dsb);
if (res != DS_OK)
return false;
res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
&region->chunk1, &region->size1, &region->chunk2, &region->size2, 0);
if (res != DS_OK)
return false;
}
switch (res)
{
case DSERR_BUFFERLOST:
err = "DSERR_BUFFERLOST";
break;
case DSERR_INVALIDCALL:
err = "DSERR_INVALIDCALL";
break;
case DSERR_INVALIDPARAM:
err = "DSERR_INVALIDPARAM";
break;
case DSERR_PRIOLEVELNEEDED:
err = "DSERR_PRIOLEVELNEEDED";
break;
default:
return true;
}
RARCH_WARN("[DirectSound error]: %s\n", err);
return false;
}
static INLINE void release_region(dsound_t *ds, const struct audio_lock *region)
{
IDirectSoundBuffer_Unlock(ds->dsb, region->chunk1,
region->size1, region->chunk2, region->size2);
}
#ifdef HAVE_THREADS
static void dsound_thread(void *data)
#else
static DWORD CALLBACK dsound_thread(PVOID data)
#endif
{
DWORD write_ptr;
dsound_t *ds = (dsound_t*)data;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
get_positions(ds, NULL, &write_ptr);
write_ptr = (write_ptr + ds->buffer_size / 2) % ds->buffer_size;
while (ds->thread_alive)
{
struct audio_lock region;
DWORD read_ptr, avail, fifo_avail;
get_positions(ds, &read_ptr, NULL);
avail = write_avail(read_ptr, write_ptr, ds->buffer_size);
EnterCriticalSection(&ds->crit);
fifo_avail = fifo_read_avail(ds->buffer);
LeaveCriticalSection(&ds->crit);
if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2)))
{
/* No space to write, or we don't have data in our fifo,
* but we can wait some time before it underruns ... */
/* We could opt for using the notification interface,
* but it is not guaranteed to work, so use high
* priority sleeping patterns.
*/
retro_sleep(1);
continue;
}
if (!grab_region(ds, write_ptr, &region))
{
ds->thread_alive = false;
SetEvent(ds->event);
break;
}
if (fifo_avail < CHUNK_SIZE)
{
/* Got space to write, but nothing in FIFO (underrun),
* fill block with silence. */
memset(region.chunk1, 0, region.size1);
memset(region.chunk2, 0, region.size2);
release_region(ds, &region);
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
}
else
{
/* All is good. Pull from it and notify FIFO. */
EnterCriticalSection(&ds->crit);
if (region.chunk1)
fifo_read(ds->buffer, region.chunk1, region.size1);
if (region.chunk2)
fifo_read(ds->buffer, region.chunk2, region.size2);
LeaveCriticalSection(&ds->crit);
release_region(ds, &region);
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
SetEvent(ds->event);
}
}
ExitThread(0);
}
static void dsound_stop_thread(dsound_t *ds)
{
if (!ds->thread)
return;
ds->thread_alive = false;
#ifdef HAVE_THREADS
sthread_join(ds->thread);
#else
WaitForSingleObject(ds->thread, INFINITE);
CloseHandle(ds->thread);
#endif
ds->thread = NULL;
}
static bool dsound_start_thread(dsound_t *ds)
{
if (!ds->thread)
{
ds->thread_alive = true;
#ifdef HAVE_THREADS
ds->thread = sthread_create(dsound_thread, ds);
#else
ds->thread = CreateThread(NULL, 0, dsound_thread, ds, 0, NULL);
#endif
if (!ds->thread)
return false;
}
return true;
}
static void dsound_clear_buffer(dsound_t *ds)
{
DWORD size;
void *ptr = NULL;
IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size,
NULL, NULL, DSBLOCK_ENTIREBUFFER) == DS_OK)
{
memset(ptr, 0, size);
IDirectSoundBuffer_Unlock(ds->dsb, ptr, size, NULL, 0);
}
}
static void dsound_free(void *data)
{
dsound_t *ds = (dsound_t*)data;
if (!ds)
return;
if (ds->thread)
{
ds->thread_alive = false;
#ifdef HAVE_THREADS
sthread_join(ds->thread);
#else
WaitForSingleObject(ds->thread, INFINITE);
CloseHandle(ds->thread);
#endif
}
DeleteCriticalSection(&ds->crit);
if (ds->dsb)
{
IDirectSoundBuffer_Stop(ds->dsb);
IDirectSoundBuffer_Release(ds->dsb);
}
if (ds->ds)
IDirectSound_Release(ds->ds);
if (ds->event)
CloseHandle(ds->event);
if (ds->buffer)
fifo_free(ds->buffer);
free(ds);
}
struct dsound_dev
{
unsigned device;
unsigned total_count;
LPGUID guid;
};
static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context)
{
struct dsound_dev *dev = (struct dsound_dev*)context;
RARCH_LOG("\t%u: %s\n", dev->total_count, desc);
if (dev->device == dev->total_count)
dev->guid = guid;
dev->total_count++;
return TRUE;
}
static void *dsound_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
WAVEFORMATEX wfx = {0};
DSBUFFERDESC bufdesc = {0};
struct dsound_dev dev = {0};
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
if (!ds)
goto error;
InitializeCriticalSection(&ds->crit);
if (device)
dev.device = strtoul(device, NULL, 0);
RARCH_LOG("DirectSound devices:\n");
#ifndef _XBOX
#ifdef UNICODE
DirectSoundEnumerate((LPDSENUMCALLBACKW)enumerate_cb, &dev);
#else
DirectSoundEnumerate((LPDSENUMCALLBACKA)enumerate_cb, &dev);
#endif
#endif
if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
goto error;
#ifndef _XBOX
if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK)
goto error;
#endif
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = rate;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = 2 * sizeof(int16_t);
wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t);
ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000;
ds->buffer_size /= CHUNK_SIZE;
ds->buffer_size *= CHUNK_SIZE;
if (ds->buffer_size < 4 * CHUNK_SIZE)
ds->buffer_size = 4 * CHUNK_SIZE;
RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size);
RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec));
bufdesc.dwSize = sizeof(DSBUFFERDESC);
bufdesc.dwFlags = 0;
#ifndef _XBOX
bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
#endif
bufdesc.dwBufferBytes = ds->buffer_size;
bufdesc.lpwfxFormat = &wfx;
ds->event = CreateEvent(NULL, false, false, NULL);
if (!ds->event)
goto error;
ds->buffer = fifo_new(4 * 1024);
if (!ds->buffer)
goto error;
if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK)
goto error;
IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX);
IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
dsound_clear_buffer(ds);
if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK)
goto error;
if (!dsound_start_thread(ds))
goto error;
return ds;
error:
RARCH_ERR("[DirectSound] Error occurred in init.\n");
dsound_free(ds);
return NULL;
}
static bool dsound_stop(void *data)
{
dsound_t *ds = (dsound_t*)data;
dsound_stop_thread(ds);
ds->is_paused = (IDirectSoundBuffer_Stop(ds->dsb) == DS_OK) ? true : false;
return (ds->is_paused) ? true : false;
}
static bool dsound_start(void *data, bool is_shutdown)
{
dsound_t *ds = (dsound_t*)data;
dsound_clear_buffer(ds);
if (!dsound_start_thread(ds))
return false;
ds->is_paused = (IDirectSoundBuffer_Play(
ds->dsb, 0, 0, DSBPLAY_LOOPING) == DS_OK) ? false : true;
return (ds->is_paused) ? false : true;
}
static bool dsound_alive(void *data)
{
dsound_t *ds = (dsound_t*)data;
if (!ds)
return false;
return !ds->is_paused;
}
static void dsound_set_nonblock_state(void *data, bool state)
{
dsound_t *ds = (dsound_t*)data;
if (ds)
ds->nonblock = state;
}
static ssize_t dsound_write(void *data, const void *buf_, size_t size)
{
size_t written = 0;
dsound_t *ds = (dsound_t*)data;
const uint8_t *buf = (const uint8_t*)buf_;
if (!ds->thread_alive)
return -1;
while (size > 0)
{
size_t avail;
EnterCriticalSection(&ds->crit);
avail = fifo_write_avail(ds->buffer);
if (avail > size)
avail = size;
fifo_write(ds->buffer, buf, avail);
LeaveCriticalSection(&ds->crit);
buf += avail;
size -= avail;
written += avail;
if (ds->nonblock || !ds->thread_alive)
break;
if (avail == 0)
WaitForSingleObject(ds->event, INFINITE);
}
return written;
}
static size_t dsound_write_avail(void *data)
{
size_t avail;
dsound_t *ds = (dsound_t*)data;
EnterCriticalSection(&ds->crit);
avail = fifo_write_avail(ds->buffer);
LeaveCriticalSection(&ds->crit);
return avail;
}
static size_t dsound_buffer_size(void *data)
{
return 4 * 1024;
}
static bool dsound_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_dsound = {
dsound_init,
dsound_write,
dsound_stop,
dsound_start,
dsound_alive,
dsound_set_nonblock_state,
dsound_free,
dsound_use_float,
"dsound",
NULL,
NULL,
dsound_write_avail,
dsound_buffer_size,
};

View File

@ -1,239 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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>
#ifdef GEKKO
#include <gccore.h>
#include <ogcsys.h>
#else
#include <cafe/ai.h>
#endif
#include <boolean.h>
#include <retro_inline.h>
#include "../../retroarch.h"
#include "../../defines/gx_defines.h"
typedef struct
{
uint32_t data[BLOCKS][CHUNK_FRAMES];
volatile unsigned dma_busy;
volatile unsigned dma_next;
volatile unsigned dma_write;
size_t write_ptr;
bool nonblock;
bool is_paused;
} gx_audio_t;
static volatile gx_audio_t *gx_audio_data = NULL;
static volatile bool stop_audio = false;
static void dma_callback(void)
{
gx_audio_t *wa = (gx_audio_t*)gx_audio_data;
if (stop_audio)
return;
/* Erase last chunk to avoid repeating audio. */
memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE);
wa->dma_busy = wa->dma_next;
wa->dma_next = (wa->dma_next + 1) & (BLOCKS - 1);
DCFlushRange(wa->data[wa->dma_next], CHUNK_SIZE);
AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE);
}
static void *gx_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
gx_audio_t *wa = (gx_audio_t*)memalign(32, sizeof(*wa));
if (!wa)
return NULL;
gx_audio_data = (gx_audio_t*)wa;
memset(wa, 0, sizeof(*wa));
AIInit(NULL);
AIRegisterDMACallback(dma_callback);
//ranges 0-32000 (default low) and 40000-47999 (in settings going down from 48000) -> set to 32000 hz
if (rate <= 32000 || (rate >= 40000 && rate < 48000))
{
AISetDSPSampleRate(AI_SAMPLERATE_32KHZ);
*new_rate = 32000;
}
else //ranges 32001-39999 (in settings going up from 32000) and 48000-max (default high) -> set to 48000 hz
{
AISetDSPSampleRate(AI_SAMPLERATE_48KHZ);
*new_rate = 48000;
}
wa->dma_write = BLOCKS - 1;
DCFlushRange(wa->data, sizeof(wa->data));
stop_audio = false;
AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE);
AIStartDMA();
return wa;
}
/* Wii uses silly R, L, R, L interleaving. */
static INLINE void copy_swapped(uint32_t * restrict dst,
const uint32_t * restrict src, size_t size)
{
do
{
uint32_t s = *src++;
*dst++ = (s >> 16) | (s << 16);
}while(--size);
}
static ssize_t gx_audio_write(void *data, const void *buf_, size_t size)
{
size_t frames = size >> 2;
const uint32_t *buf = buf_;
gx_audio_t *wa = data;
while (frames)
{
size_t to_write = CHUNK_FRAMES - wa->write_ptr;
if (frames < to_write)
to_write = frames;
/* FIXME: Nonblocking audio should break out of loop
* when it has nothing to write. */
while ((wa->dma_write == wa->dma_next ||
wa->dma_write == wa->dma_busy) && !wa->nonblock);
copy_swapped(wa->data[wa->dma_write] + wa->write_ptr, buf, to_write);
wa->write_ptr += to_write;
frames -= to_write;
buf += to_write;
if (wa->write_ptr >= CHUNK_FRAMES)
{
wa->write_ptr -= CHUNK_FRAMES;
wa->dma_write = (wa->dma_write + 1) & (BLOCKS - 1);
}
}
return size;
}
static bool gx_audio_stop(void *data)
{
gx_audio_t *wa = (gx_audio_t*)data;
if (!wa)
return false;
AIStopDMA();
memset(wa->data, 0, sizeof(wa->data));
DCFlushRange(wa->data, sizeof(wa->data));
wa->is_paused = true;
return true;
}
static void gx_audio_set_nonblock_state(void *data, bool state)
{
gx_audio_t *wa = (gx_audio_t*)data;
if (wa)
wa->nonblock = state;
}
static bool gx_audio_start(void *data, bool is_shutdown)
{
gx_audio_t *wa = (gx_audio_t*)data;
if (!wa)
return false;
AIStartDMA();
wa->is_paused = false;
return true;
}
static bool gx_audio_alive(void *data)
{
gx_audio_t *wa = (gx_audio_t*)data;
if (!wa)
return false;
return !wa->is_paused;
}
static void gx_audio_free(void *data)
{
gx_audio_t *wa = (gx_audio_t*)data;
if (!wa)
return;
stop_audio = true;
AIStopDMA();
AIRegisterDMACallback(NULL);
free(data);
}
static size_t gx_audio_write_avail(void *data)
{
gx_audio_t *wa = (gx_audio_t*)data;
return ((wa->dma_busy - wa->dma_write + BLOCKS)
& (BLOCKS - 1)) * CHUNK_SIZE;
}
static size_t gx_audio_buffer_size(void *data)
{
(void)data;
return BLOCKS * CHUNK_SIZE;
}
static bool gx_audio_use_float(void *data)
{
/* TODO/FIXME - verify */
(void)data;
return false;
}
audio_driver_t audio_gx = {
gx_audio_init,
gx_audio_write,
gx_audio_stop,
gx_audio_start,
gx_audio_alive,
gx_audio_set_nonblock_state,
gx_audio_free,
gx_audio_use_float,
"gx",
NULL,
NULL,
gx_audio_write_avail,
gx_audio_buffer_size,
};

View File

@ -1,388 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
*
* 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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include <jack/types.h>
#include <jack/ringbuffer.h>
#include <boolean.h>
#include <rthreads/rthreads.h>
#include "../../retroarch.h"
#include "../../configuration.h"
#include "../../verbosity.h"
#define FRAMES(x) (x / (sizeof(float) * 2))
typedef struct jack
{
jack_client_t *client;
jack_port_t *ports[2];
jack_ringbuffer_t *buffer[2];
volatile bool shutdown;
bool nonblock;
bool is_paused;
#ifdef HAVE_THREADS
scond_t *cond;
slock_t *cond_lock;
#endif
size_t buffer_size;
} jack_t;
static int process_cb(jack_nframes_t nframes, void *data)
{
int i;
jack_nframes_t avail[2], min_avail;
jack_t *jd = (jack_t*)data;
if (nframes <= 0)
{
#ifdef HAVE_THREADS
scond_signal(jd->cond);
#endif
return 0;
}
avail[0] = jack_ringbuffer_read_space(jd->buffer[0]);
avail[1] = jack_ringbuffer_read_space(jd->buffer[1]);
min_avail = ((avail[0] < avail[1]) ? avail[0] : avail[1]) / sizeof(jack_default_audio_sample_t);
if (min_avail > nframes)
min_avail = nframes;
for (i = 0; i < 2; i++)
{
jack_nframes_t f;
jack_default_audio_sample_t *out = (jack_default_audio_sample_t*)jack_port_get_buffer(jd->ports[i], nframes);
jack_ringbuffer_read(jd->buffer[i], (char*)out, min_avail * sizeof(jack_default_audio_sample_t));
for (f = min_avail; f < nframes; f++)
out[f] = 0.0f;
}
#ifdef HAVE_THREADS
scond_signal(jd->cond);
#endif
return 0;
}
static void shutdown_cb(void *data)
{
jack_t *jd = (jack_t*)data;
if (!jd)
return;
jd->shutdown = true;
#ifdef HAVE_THREADS
scond_signal(jd->cond);
#endif
}
static int parse_ports(char **dest_ports, const char **jports)
{
int i;
char *save = NULL;
int parsed = 0;
settings_t *settings = config_get_ptr();
char *audio_device_cpy = strdup(settings->arrays.audio_device);
const char *con = strtok_r(audio_device_cpy, ",", &save);
if (con)
dest_ports[parsed++] = strdup(con);
con = strtok_r(NULL, ",", &save);
if (con)
dest_ports[parsed++] = strdup(con);
for (i = parsed; i < 2; i++)
dest_ports[i] = strdup(jports[i]);
free(audio_device_cpy);
return 2;
}
static size_t find_buffersize(jack_t *jd, int latency, unsigned out_rate)
{
jack_latency_range_t range;
int i, buffer_frames, min_buffer_frames;
int jack_latency = 0;
int frames = latency * out_rate / 1000;
for (i = 0; i < 2; i++)
{
jack_port_get_latency_range(jd->ports[i], JackPlaybackLatency, &range);
if ((int)range.max > jack_latency)
jack_latency = range.max;
}
RARCH_LOG("[JACK]: Jack latency is %d frames.\n", jack_latency);
buffer_frames = frames - jack_latency;
min_buffer_frames = jack_get_buffer_size(jd->client) * 2;
RARCH_LOG("[JACK]: Minimum buffer size is %d frames.\n", min_buffer_frames);
if (buffer_frames < min_buffer_frames)
buffer_frames = min_buffer_frames;
return buffer_frames * sizeof(jack_default_audio_sample_t);
}
static void *ja_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
int i;
char *dest_ports[2];
const char **jports = NULL;
size_t bufsize = 0;
int parsed = 0;
jack_t *jd = (jack_t*)calloc(1, sizeof(jack_t));
if (!jd)
return NULL;
#ifdef HAVE_THREADS
jd->cond = scond_new();
jd->cond_lock = slock_new();
#endif
jd->client = jack_client_open("RetroArch", JackNullOption, NULL);
if (jd->client == NULL)
goto error;
*new_rate = jack_get_sample_rate(jd->client);
jack_set_process_callback(jd->client, process_cb, jd);
jack_on_shutdown(jd->client, shutdown_cb, jd);
jd->ports[0] = jack_port_register(jd->client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
jd->ports[1] = jack_port_register(jd->client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
if (jd->ports[0] == NULL || jd->ports[1] == NULL)
{
RARCH_ERR("[JACK]: Failed to register ports.\n");
goto error;
}
jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
if (jports == NULL)
{
RARCH_ERR("[JACK]: Failed to get ports.\n");
goto error;
}
bufsize = find_buffersize(jd, latency, *new_rate);
jd->buffer_size = bufsize;
RARCH_LOG("[JACK]: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
for (i = 0; i < 2; i++)
{
jd->buffer[i] = jack_ringbuffer_create(bufsize);
if (jd->buffer[i] == NULL)
{
RARCH_ERR("[JACK]: Failed to create buffers.\n");
goto error;
}
}
parsed = parse_ports(dest_ports, jports);
if (jack_activate(jd->client) < 0)
{
RARCH_ERR("[JACK]: Failed to activate Jack...\n");
goto error;
}
for (i = 0; i < 2; i++)
{
if (jack_connect(jd->client, jack_port_name(jd->ports[i]), dest_ports[i]))
{
RARCH_ERR("[JACK]: Failed to connect to Jack port.\n");
goto error;
}
}
for (i = 0; i < parsed; i++)
free(dest_ports[i]);
jack_free(jports);
return jd;
error:
for (i = 0; i < parsed; i++)
free(dest_ports[i]);
if (jports != NULL)
jack_free(jports);
free(jd);
return NULL;
}
static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
{
int i;
size_t j, written = 0;
jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO];
size_t frames = FRAMES(size);
/* Avoid buffer overflow if a DSP plugin generated a huge number of frames. */
if (frames > AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO)
frames = AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO;
for (i = 0; i < 2; i++)
for (j = 0; j < frames; j++)
out_deinterleaved_buffer[i][j] = buf[j * 2 + i];
while (written < frames)
{
size_t avail[2], min_avail, write_frames;
if (jd->shutdown)
return 0;
avail[0] = jack_ringbuffer_write_space(jd->buffer[0]);
avail[1] = jack_ringbuffer_write_space(jd->buffer[1]);
min_avail = avail[0] < avail[1] ? avail[0] : avail[1];
min_avail /= sizeof(float);
write_frames = frames - written > min_avail ? min_avail : frames - written;
if (write_frames > 0)
{
for (i = 0; i < 2; i++)
{
jack_ringbuffer_write(jd->buffer[i], (const char*)&out_deinterleaved_buffer[i][written],
write_frames * sizeof(jack_default_audio_sample_t));
}
written += write_frames;
}
#ifdef HAVE_THREADS
else
{
slock_lock(jd->cond_lock);
scond_wait(jd->cond, jd->cond_lock);
slock_unlock(jd->cond_lock);
}
#endif
if (jd->nonblock)
break;
}
return written * sizeof(float) * 2;
}
static ssize_t ja_write(void *data, const void *buf, size_t size)
{
jack_t *jd = (jack_t*)data;
return write_buffer(jd, (const float*)buf, size);
}
static bool ja_stop(void *data)
{
jack_t *jd = (jack_t*)data;
if (jd)
jd->is_paused = true;
return true;
}
static bool ja_alive(void *data)
{
jack_t *jd = (jack_t*)data;
if (!jd)
return false;
return !jd->is_paused;
}
static void ja_set_nonblock_state(void *data, bool state)
{
jack_t *jd = (jack_t*)data;
if (jd)
jd->nonblock = state;
}
static bool ja_start(void *data, bool is_shutdown)
{
jack_t *jd = (jack_t*)data;
if (jd)
jd->is_paused = false;
return true;
}
static void ja_free(void *data)
{
int i;
jack_t *jd = (jack_t*)data;
jd->shutdown = true;
if (jd->client != NULL)
{
jack_deactivate(jd->client);
jack_client_close(jd->client);
}
for (i = 0; i < 2; i++)
if (jd->buffer[i] != NULL)
jack_ringbuffer_free(jd->buffer[i]);
#ifdef HAVE_THREADS
if (jd->cond_lock)
slock_free(jd->cond_lock);
if (jd->cond)
scond_free(jd->cond);
#endif
free(jd);
}
static bool ja_use_float(void *data)
{
(void)data;
return true;
}
static size_t ja_write_avail(void *data)
{
jack_t *jd = (jack_t*)data;
return jack_ringbuffer_write_space(jd->buffer[0]);
}
static size_t ja_buffer_size(void *data)
{
jack_t *jd = (jack_t*)data;
return jd->buffer_size;
}
audio_driver_t audio_jack = {
ja_init,
ja_write,
ja_stop,
ja_start,
ja_alive,
ja_set_nonblock_state,
ja_free,
ja_use_float,
"jack",
NULL,
NULL,
ja_write_avail,
ja_buffer_size,
};

View File

@ -1,96 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 "../../retroarch.h"
#include "../../verbosity.h"
static void *null_audio_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
RARCH_ERR("Using the null audio driver. RetroArch will be silent.\n");
(void)device;
(void)rate;
(void)latency;
(void)new_rate;
return (void*)-1;
}
static void null_audio_free(void *data)
{
(void)data;
}
static ssize_t null_audio_write(void *data, const void *buf, size_t size)
{
(void)data;
(void)buf;
return size;
}
static bool null_audio_stop(void *data)
{
(void)data;
return true;
}
static bool null_audio_alive(void *data)
{
(void)data;
return true;
}
static bool null_audio_start(void *data, bool is_shutdown)
{
(void)data;
return true;
}
static void null_audio_set_nonblock_state(void *data, bool state)
{
(void)data;
(void)state;
}
static bool null_audio_use_float(void *data)
{
(void)data;
return true;
}
static size_t null_audio_write_avail(void *data)
{
(void)data;
return 0;
}
audio_driver_t audio_null = {
null_audio_init,
null_audio_write,
null_audio_stop,
null_audio_start,
null_audio_alive,
null_audio_set_nonblock_state,
null_audio_free,
null_audio_use_float,
"null",
NULL,
NULL,
null_audio_write_avail,
NULL
};

View File

@ -1,280 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <time.h>
#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif
#include <retro_miscellaneous.h>
#include <retro_timers.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
#define BUFSIZE 1024
typedef struct al
{
ALuint source;
ALuint *buffers;
ALuint *res_buf;
size_t res_ptr;
ALenum format;
size_t num_buffers;
int rate;
uint8_t tmpbuf[BUFSIZE];
size_t tmpbuf_ptr;
ALCdevice *handle;
ALCcontext *ctx;
bool nonblock;
bool is_paused;
} al_t;
static void al_free(void *data)
{
al_t *al = (al_t*)data;
if (!al)
return;
alSourceStop(al->source);
alDeleteSources(1, &al->source);
if (al->buffers)
alDeleteBuffers(al->num_buffers, al->buffers);
free(al->buffers);
free(al->res_buf);
alcMakeContextCurrent(NULL);
if (al->ctx)
alcDestroyContext(al->ctx);
if (al->handle)
alcCloseDevice(al->handle);
free(al);
}
static void *al_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
al_t *al;
(void)device;
al = (al_t*)calloc(1, sizeof(al_t));
if (!al)
return NULL;
al->handle = alcOpenDevice(NULL);
if (!al->handle)
goto error;
al->ctx = alcCreateContext(al->handle, NULL);
if (!al->ctx)
goto error;
alcMakeContextCurrent(al->ctx);
al->rate = rate;
/* We already use one buffer for tmpbuf. */
al->num_buffers = (latency * rate * 2 * sizeof(int16_t)) / (1000 * BUFSIZE) - 1;
if (al->num_buffers < 2)
al->num_buffers = 2;
RARCH_LOG("[OpenAL]: Using %u buffers of %u bytes.\n", (unsigned)al->num_buffers, BUFSIZE);
al->buffers = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
al->res_buf = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
if (al->buffers == NULL || al->res_buf == NULL)
goto error;
alGenSources(1, &al->source);
alGenBuffers(al->num_buffers, al->buffers);
memcpy(al->res_buf, al->buffers, al->num_buffers * sizeof(ALuint));
al->res_ptr = al->num_buffers;
return al;
error:
al_free(al);
return NULL;
}
static bool al_unqueue_buffers(al_t *al)
{
ALint val;
alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &val);
if (val <= 0)
return false;
alSourceUnqueueBuffers(al->source, val, &al->res_buf[al->res_ptr]);
al->res_ptr += val;
return true;
}
static bool al_get_buffer(al_t *al, ALuint *buffer)
{
if (!al->res_ptr)
{
for (;;)
{
if (al_unqueue_buffers(al))
break;
if (al->nonblock)
return false;
/* Must sleep as there is no proper blocking method. */
retro_sleep(1);
}
}
*buffer = al->res_buf[--al->res_ptr];
return true;
}
static size_t al_fill_internal_buf(al_t *al, const void *buf, size_t size)
{
size_t read_size = MIN(BUFSIZE - al->tmpbuf_ptr, size);
memcpy(al->tmpbuf + al->tmpbuf_ptr, buf, read_size);
al->tmpbuf_ptr += read_size;
return read_size;
}
static ssize_t al_write(void *data, const void *buf_, size_t size)
{
al_t *al = (al_t*)data;
const uint8_t *buf = (const uint8_t*)buf_;
size_t written = 0;
while (size)
{
ALint val;
ALuint buffer;
size_t rc = al_fill_internal_buf(al, buf, size);
written += rc;
buf += rc;
size -= rc;
if (al->tmpbuf_ptr != BUFSIZE)
break;
if (!al_get_buffer(al, &buffer))
break;
alBufferData(buffer, AL_FORMAT_STEREO16, al->tmpbuf, BUFSIZE, al->rate);
al->tmpbuf_ptr = 0;
alSourceQueueBuffers(al->source, 1, &buffer);
if (alGetError() != AL_NO_ERROR)
return -1;
alGetSourcei(al->source, AL_SOURCE_STATE, &val);
if (val != AL_PLAYING)
alSourcePlay(al->source);
if (alGetError() != AL_NO_ERROR)
return -1;
}
return written;
}
static bool al_stop(void *data)
{
al_t *al = (al_t*)data;
if (al)
al->is_paused = true;
return true;
}
static bool al_alive(void *data)
{
al_t *al = (al_t*)data;
if (!al)
return false;
return !al->is_paused;
}
static void al_set_nonblock_state(void *data, bool state)
{
al_t *al = (al_t*)data;
if (al)
al->nonblock = state;
}
static bool al_start(void *data, bool is_shutdown)
{
al_t *al = (al_t*)data;
if (al)
al->is_paused = false;
return true;
}
static size_t al_write_avail(void *data)
{
al_t *al = (al_t*)data;
al_unqueue_buffers(al);
return al->res_ptr * BUFSIZE + (BUFSIZE - al->tmpbuf_ptr);
}
static size_t al_buffer_size(void *data)
{
al_t *al = (al_t*)data;
return (al->num_buffers + 1) * BUFSIZE; /* Also got tmpbuf. */
}
static bool al_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_openal = {
al_init,
al_write,
al_stop,
al_start,
al_alive,
al_set_nonblock_state,
al_free,
al_use_float,
"openal",
NULL,
NULL,
al_write_avail,
al_buffer_size,
};

View File

@ -1,320 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <SLES/OpenSLES.h>
#ifdef ANDROID
#include <SLES/OpenSLES_Android.h>
#endif
#include <rthreads/rthreads.h>
#include "../../retroarch.h"
/* Helper macros, COM-style. */
#define SLObjectItf_Realize(a, ...) ((*(a))->Realize(a, __VA_ARGS__))
#define SLObjectItf_GetInterface(a, ...) ((*(a))->GetInterface(a, __VA_ARGS__))
#define SLObjectItf_Destroy(a) ((*(a))->Destroy((a)))
#define SLEngineItf_CreateOutputMix(a, ...) ((*(a))->CreateOutputMix(a, __VA_ARGS__))
#define SLEngineItf_CreateAudioPlayer(a, ...) ((*(a))->CreateAudioPlayer(a, __VA_ARGS__))
#define SLPlayItf_SetPlayState(a, ...) ((*(a))->SetPlayState(a, __VA_ARGS__))
typedef struct sl
{
uint8_t **buffer;
uint8_t *buffer_chunk;
unsigned buffer_index;
unsigned buffer_ptr;
volatile unsigned buffered_blocks;
SLObjectItf engine_object;
SLEngineItf engine;
SLObjectItf output_mix;
SLObjectItf buffer_queue_object;
SLAndroidSimpleBufferQueueItf buffer_queue;
SLPlayItf player;
slock_t *lock;
scond_t *cond;
bool nonblock;
bool is_paused;
unsigned buf_size;
unsigned buf_count;
} sl_t;
static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *ctx)
{
sl_t *sl = (sl_t*)ctx;
__sync_fetch_and_sub(&sl->buffered_blocks, 1);
scond_signal(sl->cond);
}
#define GOTO_IF_FAIL(x) do { \
if ((res = (x)) != SL_RESULT_SUCCESS) \
goto error; \
} while(0)
static void sl_free(void *data)
{
sl_t *sl = (sl_t*)data;
if (!sl)
return;
if (sl->player)
SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED);
if (sl->buffer_queue_object)
SLObjectItf_Destroy(sl->buffer_queue_object);
if (sl->output_mix)
SLObjectItf_Destroy(sl->output_mix);
if (sl->engine_object)
SLObjectItf_Destroy(sl->engine_object);
if (sl->lock)
slock_free(sl->lock);
if (sl->cond)
scond_free(sl->cond);
free(sl->buffer);
free(sl->buffer_chunk);
free(sl);
}
static void *sl_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
unsigned i;
SLDataFormat_PCM fmt_pcm = {0};
SLDataSource audio_src = {0};
SLDataSink audio_sink = {0};
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {0};
SLDataLocator_OutputMix loc_outmix = {0};
SLresult res = 0;
SLInterfaceID id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
SLboolean req = SL_BOOLEAN_TRUE;
sl_t *sl = (sl_t*)calloc(1, sizeof(sl_t));
(void)device;
if (!sl)
goto error;
RARCH_LOG("[OpenSL]: Requested audio latency: %u ms.", latency);
GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL));
GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE));
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine));
GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL));
GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE));
if (block_frames)
sl->buf_size = block_frames * 4;
else
sl->buf_size = next_pow2(32 * latency);
sl->buf_count = (latency * 4 * rate + 500) / 1000;
sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size;
if (sl->buf_count < 2)
sl->buf_count = 2;
sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count);
if (!sl->buffer)
goto error;
sl->buffer_chunk = (uint8_t*)calloc(sl->buf_count, sl->buf_size);
if (!sl->buffer_chunk)
goto error;
for (i = 0; i < sl->buf_count; i++)
sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size;
RARCH_LOG("[OpenSL]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n",
sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count);
fmt_pcm.formatType = SL_DATAFORMAT_PCM;
fmt_pcm.numChannels = 2;
fmt_pcm.samplesPerSec = rate * 1000; // Samplerate is in milli-Hz.
fmt_pcm.bitsPerSample = 16;
fmt_pcm.containerSize = 16;
fmt_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; /* Android only. */
audio_src.pLocator = &loc_bufq;
audio_src.pFormat = &fmt_pcm;
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
loc_bufq.numBuffers = sl->buf_count;
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
loc_outmix.outputMix = sl->output_mix;
audio_sink.pLocator = &loc_outmix;
GOTO_IF_FAIL(SLEngineItf_CreateAudioPlayer(sl->engine, &sl->buffer_queue_object,
&audio_src, &audio_sink,
1, &id, &req));
GOTO_IF_FAIL(SLObjectItf_Realize(sl->buffer_queue_object, SL_BOOLEAN_FALSE));
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&sl->buffer_queue));
sl->cond = scond_new();
sl->lock = slock_new();
(*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl);
/* Enqueue a bit to get stuff rolling. */
sl->buffered_blocks = sl->buf_count;
sl->buffer_index = 0;
for (i = 0; i < sl->buf_count; i++)
(*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], sl->buf_size);
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player));
GOTO_IF_FAIL(SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING));
return sl;
error:
RARCH_ERR("[OpenSL]: Couldn't initialize OpenSL ES driver, error code: [%d].\n", (int)res);
sl_free(sl);
return NULL;
}
static bool sl_stop(void *data)
{
sl_t *sl = (sl_t*)data;
sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED)
== SL_RESULT_SUCCESS) ? true : false;
return sl->is_paused ? true : false;
}
static bool sl_alive(void *data)
{
sl_t *sl = (sl_t*)data;
if (!sl)
return false;
return !sl->is_paused;
}
static void sl_set_nonblock_state(void *data, bool state)
{
sl_t *sl = (sl_t*)data;
if (sl)
sl->nonblock = state;
}
static bool sl_start(void *data, bool is_shutdown)
{
sl_t *sl = (sl_t*)data;
sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING)
== SL_RESULT_SUCCESS) ? false : true;
return sl->is_paused ? false : true;
}
static ssize_t sl_write(void *data, const void *buf_, size_t size)
{
sl_t *sl = (sl_t*)data;
size_t written = 0;
const uint8_t *buf = (const uint8_t*)buf_;
while (size)
{
size_t avail_write;
if (sl->nonblock)
{
if (sl->buffered_blocks == sl->buf_count)
break;
}
else
{
slock_lock(sl->lock);
while (sl->buffered_blocks == sl->buf_count)
scond_wait(sl->cond, sl->lock);
slock_unlock(sl->lock);
}
avail_write = MIN(sl->buf_size - sl->buffer_ptr, size);
if (avail_write)
{
memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
sl->buffer_ptr += avail_write;
buf += avail_write;
size -= avail_write;
written += avail_write;
}
if (sl->buffer_ptr >= sl->buf_size)
{
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
__sync_fetch_and_add(&sl->buffered_blocks, 1);
sl->buffer_ptr = 0;
if (res != SL_RESULT_SUCCESS)
{
RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
return -1;
}
}
}
return written;
}
static size_t sl_write_avail(void *data)
{
sl_t *sl = (sl_t*)data;
size_t avail = (sl->buf_count - (int)sl->buffered_blocks - 1) * sl->buf_size + (sl->buf_size - (int)sl->buffer_ptr);
return avail;
}
static size_t sl_buffer_size(void *data)
{
sl_t *sl = (sl_t*)data;
return sl->buf_size * sl->buf_count;
}
static bool sl_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_opensl = {
sl_init,
sl_write,
sl_stop,
sl_start,
sl_alive,
sl_set_nonblock_state,
sl_free,
sl_use_float,
"opensl",
NULL,
NULL,
sl_write_avail,
sl_buffer_size,
};

View File

@ -1,215 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#ifdef HAVE_OSS_BSD
#include <soundcard.h>
#else
#include <sys/soundcard.h>
#endif
#include <retro_endianness.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../../retroarch.h"
#include "../../verbosity.h"
#ifdef HAVE_OSS_BSD
#define DEFAULT_OSS_DEV "/dev/audio"
#else
#define DEFAULT_OSS_DEV "/dev/dsp"
#endif
static bool oss_is_paused = false;
static void *oss_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_out_rate)
{
int frags, frag, channels, format, new_rate;
int *fd = (int*)calloc(1, sizeof(int));
const char *oss_device = device ? device : DEFAULT_OSS_DEV;
if (!fd)
return NULL;
if ((*fd = open(oss_device, O_WRONLY)) < 0)
{
free(fd);
perror("open");
return NULL;
}
frags = (latency * rate * 4) / (1000 * (1 << 10));
frag = (frags << 16) | 10;
if (ioctl(*fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0)
RARCH_WARN("Cannot set fragment sizes. Latency might not be as expected ...\n");
channels = 2;
format = is_little_endian() ? AFMT_S16_LE : AFMT_S16_BE;
if (ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0)
goto error;
if (ioctl(*fd, SNDCTL_DSP_SETFMT, &format) < 0)
goto error;
new_rate = rate;
if (ioctl(*fd, SNDCTL_DSP_SPEED, &new_rate) < 0)
goto error;
if (new_rate != (int)rate)
{
RARCH_WARN("Requested sample rate not supported. Adjusting output rate to %d Hz.\n", new_rate);
*new_out_rate = new_rate;
}
return fd;
error:
close(*fd);
free(fd);
perror("ioctl");
return NULL;
}
static ssize_t oss_write(void *data, const void *buf, size_t size)
{
ssize_t ret;
int *fd = (int*)data;
if (size == 0)
return 0;
if ((ret = write(*fd, buf, size)) < 0)
{
if (errno == EAGAIN && (fcntl(*fd, F_GETFL) & O_NONBLOCK))
return 0;
return -1;
}
return ret;
}
static bool oss_stop(void *data)
{
int *fd = (int*)data;
if (ioctl(*fd, SNDCTL_DSP_RESET, 0) < 0)
return false;
oss_is_paused = true;
return true;
}
static bool oss_start(void *data, bool is_shutdown)
{
(void)data;
oss_is_paused = false;
return true;
}
static bool oss_alive(void *data)
{
(void)data;
return !oss_is_paused;
}
static void oss_set_nonblock_state(void *data, bool state)
{
int rc;
int *fd = (int*)data;
if (state)
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
else
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & (~O_NONBLOCK));
if (rc != 0)
RARCH_WARN("Could not set nonblocking on OSS file descriptor. Will not be able to fast-forward.\n");
}
static void oss_free(void *data)
{
int *fd = (int*)data;
if (ioctl(*fd, SNDCTL_DSP_RESET, 0) < 0)
return;
close(*fd);
free(fd);
}
static size_t oss_write_avail(void *data)
{
audio_buf_info info;
int *fd = (int*)data;
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
{
RARCH_ERR("[OSS]: SNDCTL_DSP_GETOSPACE failed ...\n");
return 0;
}
return info.bytes;
}
static size_t oss_buffer_size(void *data)
{
audio_buf_info info;
int *fd = (int*)data;
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
{
RARCH_ERR("[OSS]: SNDCTL_DSP_GETOSPACE failed ...\n");
return 1; /* Return something non-zero to avoid SIGFPE. */
}
return info.fragsize * info.fragstotal;
}
static bool oss_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_oss = {
oss_init,
oss_write,
oss_stop,
oss_start,
oss_alive,
oss_set_nonblock_state,
oss_free,
oss_use_float,
"oss",
NULL,
NULL,
oss_write_avail,
oss_buffer_size,
};

View File

@ -1,177 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Francisco Javier Trujillo Mata
*
* 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 <stdint.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <kernel.h>
#include <audsrv.h>
#include "../../retroarch.h"
#define AUDIO_BUFFER 128 * 1024
#define AUDIO_CHANNELS 2
#define AUDIO_BITS 16
typedef struct ps2_audio
{
bool nonblocking;
bool running;
} ps2_audio_t;
static void audioConfigure(ps2_audio_t *ps2, unsigned rate)
{
int err;
struct audsrv_fmt_t format;
format.bits = AUDIO_BITS;
format.freq = rate;
format.channels = AUDIO_CHANNELS;
err = audsrv_set_format(&format);
if (err){
printf("set format returned %d\n", err);
printf("audsrv returned error string: %s\n", audsrv_get_error_string());
}
audsrv_set_volume(MAX_VOLUME);
}
static void *ps2_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
ps2_audio_t *ps2 = (ps2_audio_t*)calloc(1, sizeof(ps2_audio_t));
if (!ps2)
return NULL;
audioConfigure(ps2, rate);
return ps2;
}
static void ps2_audio_free(void *data)
{
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if(!ps2)
return;
ps2->running = false;
audsrv_stop_audio();
free(ps2);
}
static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
{
int bytes_sent;
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (!ps2->running)
return -1;
bytes_sent = audsrv_play_audio(buf, size);
return bytes_sent;
}
static bool ps2_audio_alive(void *data)
{
bool alive = false;
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (ps2)
alive = ps2->running;
return alive;
}
static bool ps2_audio_stop(void *data)
{
bool stop = true;
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (ps2)
{
audsrv_stop_audio();
ps2->running = false;
}
return stop;
}
static bool ps2_audio_start(void *data, bool is_shutdown)
{
ps2_audio_t* ps2 = (ps2_audio_t*)data;
bool start = true;
if (ps2)
{
ps2->running = true;
}
return start;
}
static void ps2_audio_set_nonblock_state(void *data, bool toggle)
{
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (ps2)
ps2->nonblocking = toggle;
}
static bool ps2_audio_use_float(void *data)
{
return false;
}
static size_t ps2_audio_write_avail(void *data)
{
ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (ps2 && ps2->running)
{
return AUDIO_BUFFER;
}
return 0;
}
static size_t ps2_audio_buffer_size(void *data)
{
return AUDIO_BUFFER;
}
audio_driver_t audio_ps2 = {
ps2_audio_init,
ps2_audio_write,
ps2_audio_stop,
ps2_audio_start,
ps2_audio_alive,
ps2_audio_set_nonblock_state,
ps2_audio_free,
ps2_audio_use_float,
"ps2",
NULL,
NULL,
ps2_audio_write_avail,
ps2_audio_buffer_size
};

View File

@ -1,253 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <queues/fifo_queue.h>
#include "../../retroarch.h"
#include "../../defines/ps3_defines.h"
#define AUDIO_BLOCKS 8
#define AUDIO_CHANNELS 2
typedef struct
{
uint32_t audio_port;
bool nonblocking;
bool started;
volatile bool quit_thread;
fifo_buffer_t *buffer;
sys_ppu_thread_t thread;
sys_lwmutex_t lock;
sys_lwmutex_t cond_lock;
sys_lwcond_t cond;
} ps3_audio_t;
#ifdef __PSL1GHT__
static void event_loop(void *data)
#else
static void event_loop(uint64_t data)
#endif
{
float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS]
__attribute__((aligned(16)));
sys_event_queue_t id;
sys_ipc_key_t key;
sys_event_t event;
ps3_audio_t *aud = (ps3_audio_t*)(uintptr_t)data;
cellAudioCreateNotifyEventQueue(&id, &key);
cellAudioSetNotifyEventQueue(key);
while (!aud->quit_thread)
{
sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT);
sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT);
if (fifo_read_avail(aud->buffer) >= sizeof(out_tmp))
fifo_read(aud->buffer, out_tmp, sizeof(out_tmp));
else
memset(out_tmp, 0, sizeof(out_tmp));
sys_lwmutex_unlock(&aud->lock);
sys_lwcond_signal(&aud->cond);
cellAudioAddData(aud->audio_port, out_tmp,
CELL_AUDIO_BLOCK_SAMPLES, 1.0);
}
cellAudioRemoveNotifyEventQueue(key);
sys_ppu_thread_exit(0);
}
static void *ps3_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
CellAudioPortParam params;
ps3_audio_t *data = calloc(1, sizeof(*data));
if (!data)
return NULL;
(void)latency;
(void)device;
(void)rate;
cellAudioInit();
params.numChannels = AUDIO_CHANNELS;
params.numBlocks = AUDIO_BLOCKS;
#if 0
#ifdef HAVE_HEADSET
if(global->console.sound.mode == SOUND_MODE_HEADSET)
params.param_attrib = CELL_AUDIO_PORTATTR_OUT_SECONDARY;
else
#endif
#endif
params.param_attrib = 0;
if (cellAudioPortOpen(&params, &data->audio_port) != CELL_OK)
{
cellAudioQuit();
free(data);
return NULL;
}
data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES *
AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(float));
#ifdef __PSL1GHT__
sys_lwmutex_attr_t lock_attr =
{SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
sys_lwmutex_attr_t cond_lock_attr =
{SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
sys_lwcond_attribute_t cond_attr = {"\0"};
#else
sys_lwmutex_attribute_t lock_attr;
sys_lwmutex_attribute_t cond_lock_attr;
sys_lwcond_attribute_t cond_attr;
sys_lwmutex_attribute_initialize(lock_attr);
sys_lwmutex_attribute_initialize(cond_lock_attr);
sys_lwcond_attribute_initialize(cond_attr);
#endif
sys_lwmutex_create(&data->lock, &lock_attr);
sys_lwmutex_create(&data->cond_lock, &cond_lock_attr);
sys_lwcond_create(&data->cond, &data->cond_lock, &cond_attr);
cellAudioPortStart(data->audio_port);
data->started = true;
sys_ppu_thread_create(&data->thread, event_loop,
#ifdef __PSL1GHT__
data,
#else
(uint64_t)data,
#endif
1500, 0x1000, SYS_PPU_THREAD_CREATE_JOINABLE, (char*)"sound");
return data;
}
static ssize_t ps3_audio_write(void *data, const void *buf, size_t size)
{
ps3_audio_t *aud = data;
if (aud->nonblocking)
{
if (fifo_write_avail(aud->buffer) < size)
return 0;
}
while (fifo_write_avail(aud->buffer) < size)
sys_lwcond_wait(&aud->cond, 0);
sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT);
fifo_write(aud->buffer, buf, size);
sys_lwmutex_unlock(&aud->lock);
return size;
}
static bool ps3_audio_stop(void *data)
{
ps3_audio_t *aud = data;
if (aud->started)
{
cellAudioPortStop(aud->audio_port);
aud->started = false;
}
return true;
}
static bool ps3_audio_start(void *data, bool is_shutdown)
{
ps3_audio_t *aud = data;
if (!aud->started)
{
cellAudioPortStart(aud->audio_port);
aud->started = true;
}
return true;
}
static bool ps3_audio_alive(void *data)
{
ps3_audio_t *aud = data;
if (!aud)
return false;
return aud->started;
}
static void ps3_audio_set_nonblock_state(void *data, bool toggle)
{
ps3_audio_t *aud = data;
if (aud)
aud->nonblocking = toggle;
}
static void ps3_audio_free(void *data)
{
uint64_t val;
ps3_audio_t *aud = data;
aud->quit_thread = true;
ps3_audio_start(aud, false);
sys_ppu_thread_join(aud->thread, &val);
ps3_audio_stop(aud);
cellAudioPortClose(aud->audio_port);
cellAudioQuit();
fifo_free(aud->buffer);
sys_lwmutex_destroy(&aud->lock);
sys_lwmutex_destroy(&aud->cond_lock);
sys_lwcond_destroy(&aud->cond);
free(data);
}
static bool ps3_audio_use_float(void *data)
{
(void)data;
return true;
}
static size_t ps3_audio_write_avail(void *data)
{
(void)data;
return 0;
}
audio_driver_t audio_ps3 = {
ps3_audio_init,
ps3_audio_write,
ps3_audio_stop,
ps3_audio_start,
ps3_audio_alive,
ps3_audio_set_nonblock_state,
ps3_audio_free,
ps3_audio_use_float,
"ps3",
NULL,
NULL,
ps3_audio_write_avail,
NULL
};

View File

@ -1,339 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2014-2017 - Ali Bouhlel
*
* 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 <stdint.h>
#if defined(VITA) || defined(PSP)
#include <malloc.h>
#endif
#include <stdio.h>
#include <string.h>
#include <rthreads/rthreads.h>
#include <queues/fifo_queue.h>
#if defined(VITA)
#include <psp2/kernel/processmgr.h>
#include <psp2/kernel/threadmgr.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/audioout.h>
#elif defined(PSP)
#include <pspkernel.h>
#include <pspaudio.h>
#elif defined(ORBIS)
#include <audioout.h>
#define SCE_AUDIO_OUT_PORT_TYPE_MAIN 0
#define SCE_AUDIO_OUT_MODE_STEREO 1
#define SceUID uint32_t
#endif
#include "../../retroarch.h"
typedef struct psp_audio
{
bool nonblocking;
uint32_t* buffer;
uint32_t* zeroBuffer;
SceUID thread;
int rate;
volatile bool running;
volatile uint16_t read_pos;
volatile uint16_t write_pos;
sthread_t *worker_thread;
slock_t *fifo_lock;
scond_t *cond;
slock_t *cond_lock;
} psp_audio_t;
#define AUDIO_OUT_COUNT 512u
#define AUDIO_BUFFER_SIZE (1u<<13u)
#define AUDIO_BUFFER_SIZE_MASK (AUDIO_BUFFER_SIZE-1)
static void audioMainLoop(void *data)
{
psp_audio_t* psp = (psp_audio_t*)data;
#if defined(VITA)
int port = sceAudioOutOpenPort(
SCE_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT,
psp->rate, SCE_AUDIO_OUT_MODE_STEREO);
#elif defined(ORBIS)
int port = sceAudioOutOpen(0xff,
SCE_AUDIO_OUT_PORT_TYPE_MAIN, 0, AUDIO_OUT_COUNT,
psp->rate, SCE_AUDIO_OUT_MODE_STEREO);
#else
sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2);
#endif
while (psp->running)
{
bool cond = false;
uint16_t read_pos = psp->read_pos;
uint16_t read_pos_2 = psp->read_pos;
slock_lock(psp->fifo_lock);
cond = ((uint16_t)(psp->write_pos - read_pos) & AUDIO_BUFFER_SIZE_MASK)
< (AUDIO_OUT_COUNT * 2);
if (!cond)
{
read_pos += AUDIO_OUT_COUNT;
read_pos &= AUDIO_BUFFER_SIZE_MASK;
psp->read_pos = read_pos;
}
slock_unlock(psp->fifo_lock);
slock_lock(psp->cond_lock);
scond_signal(psp->cond);
slock_unlock(psp->cond_lock);
#if defined(VITA) || defined(ORBIS)
sceAudioOutOutput(port,
cond ? (psp->zeroBuffer)
: (psp->buffer + read_pos_2));
#else
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer)
: (psp->buffer + read_pos));
#endif
}
#if defined(VITA)
sceAudioOutReleasePort(port);
#elif defined(ORBIS)
sceAudioOutClose(port);
#else
sceAudioSRCChRelease();
#endif
return;
}
static void *psp_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
psp_audio_t *psp = (psp_audio_t*)calloc(1, sizeof(psp_audio_t));
if (!psp)
return NULL;
(void)device;
(void)latency;
#ifdef ORBIS
psp->buffer = (uint32_t*)
malloc(AUDIO_BUFFER_SIZE * sizeof(uint32_t));
#else
/* Cache aligned, not necessary but helpful. */
psp->buffer = (uint32_t*)
memalign(64, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
#endif
memset(psp->buffer, 0, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
#ifdef ORBIS
psp->zeroBuffer = (uint32_t*)
malloc(AUDIO_OUT_COUNT * sizeof(uint32_t));
#else
psp->zeroBuffer = (uint32_t*)
memalign(64, AUDIO_OUT_COUNT * sizeof(uint32_t));
#endif
memset(psp->zeroBuffer, 0, AUDIO_OUT_COUNT * sizeof(uint32_t));
psp->read_pos = 0;
psp->write_pos = 0;
psp->rate = rate;
psp->fifo_lock = slock_new();
psp->cond_lock = slock_new();
psp->cond = scond_new();
psp->nonblocking = false;
psp->running = true;
psp->worker_thread = sthread_create(audioMainLoop, psp);
return psp;
}
static void psp_audio_free(void *data)
{
psp_audio_t* psp = (psp_audio_t*)data;
if(!psp)
return;
if(psp->running){
if (psp->worker_thread)
{
psp->running = false;
sthread_join(psp->worker_thread);
}
if (psp->cond)
scond_free(psp->cond);
if (psp->fifo_lock)
slock_free(psp->fifo_lock);
if (psp->cond_lock)
slock_free(psp->cond_lock);
}
free(psp->buffer);
psp->worker_thread = NULL;
free(psp->zeroBuffer);
free(psp);
}
static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
{
psp_audio_t* psp = (psp_audio_t*)data;
uint16_t write_pos = psp->write_pos;
uint16_t sampleCount = size / sizeof(uint32_t);
if (!psp->running)
return -1;
if (psp->nonblocking)
{
if (AUDIO_BUFFER_SIZE - ((uint16_t)
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
return 0;
}
slock_lock(psp->cond_lock);
while (AUDIO_BUFFER_SIZE - ((uint16_t)
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
scond_wait(psp->cond, psp->cond_lock);
slock_unlock(psp->cond_lock);
slock_lock(psp->fifo_lock);
if((write_pos + sampleCount) > AUDIO_BUFFER_SIZE)
{
memcpy(psp->buffer + write_pos, buf,
(AUDIO_BUFFER_SIZE - write_pos) * sizeof(uint32_t));
memcpy(psp->buffer, (uint32_t*) buf +
(AUDIO_BUFFER_SIZE - write_pos),
(write_pos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t));
}
else
memcpy(psp->buffer + write_pos, buf, size);
write_pos += sampleCount;
write_pos &= AUDIO_BUFFER_SIZE_MASK;
psp->write_pos = write_pos;
slock_unlock(psp->fifo_lock);
return size;
}
static bool psp_audio_alive(void *data)
{
psp_audio_t* psp = (psp_audio_t*)data;
if (!psp)
return false;
return psp->running;
}
static bool psp_audio_stop(void *data)
{
psp_audio_t* psp = (psp_audio_t*)data;
if (psp){
psp->running = false;
if (!psp->worker_thread)
return true;
sthread_join(psp->worker_thread);
psp->worker_thread = NULL;
}
return true;
}
static bool psp_audio_start(void *data, bool is_shutdown)
{
psp_audio_t* psp = (psp_audio_t*)data;
if(psp && psp->running)
return true;
if (!psp->worker_thread)
{
psp->running = true;
psp->worker_thread = sthread_create(audioMainLoop, psp);
}
return true;
}
static void psp_audio_set_nonblock_state(void *data, bool toggle)
{
psp_audio_t* psp = (psp_audio_t*)data;
if (psp)
psp->nonblocking = toggle;
}
static bool psp_audio_use_float(void *data)
{
(void)data;
return false;
}
static size_t psp_write_avail(void *data)
{
size_t val;
psp_audio_t* psp = (psp_audio_t*)data;
if (!psp||!psp->running)
return 0;
slock_lock(psp->fifo_lock);
val = AUDIO_BUFFER_SIZE - ((uint16_t)
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK);
slock_unlock(psp->fifo_lock);
return val;
}
static size_t psp_buffer_size(void *data)
{
/* TODO */
return AUDIO_BUFFER_SIZE /** sizeof(uint32_t)*/;
}
audio_driver_t audio_psp = {
psp_audio_init,
psp_audio_write,
psp_audio_stop,
psp_audio_start,
psp_audio_alive,
psp_audio_set_nonblock_state,
psp_audio_free,
psp_audio_use_float,
#if defined(VITA)
"vita",
#elif defined(ORBIS)
"orbis",
#else
"psp",
#endif
NULL,
NULL,
psp_write_avail,
psp_buffer_size
};

View File

@ -1,369 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdint.h>
#include <string.h>
#include <pulse/pulseaudio.h>
#include <boolean.h>
#include <retro_miscellaneous.h>
#include <retro_endianness.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
typedef struct
{
pa_threaded_mainloop *mainloop;
pa_context *context;
pa_stream *stream;
size_t buffer_size;
bool nonblock;
bool success;
bool is_paused;
} pa_t;
static void pulse_free(void *data)
{
pa_t *pa = (pa_t*)data;
if (!pa)
return;
if (pa->mainloop)
pa_threaded_mainloop_stop(pa->mainloop);
if (pa->stream)
{
pa_stream_disconnect(pa->stream);
pa_stream_unref(pa->stream);
}
if (pa->context)
{
pa_context_disconnect(pa->context);
pa_context_unref(pa->context);
}
if (pa->mainloop)
pa_threaded_mainloop_free(pa->mainloop);
free(pa);
}
static void stream_success_cb(pa_stream *s, int success, void *data)
{
pa_t *pa = (pa_t*)data;
(void)s;
pa->success = success;
pa_threaded_mainloop_signal(pa->mainloop, 0);
}
static void context_state_cb(pa_context *c, void *data)
{
pa_t *pa = (pa_t*)data;
switch (pa_context_get_state(c))
{
case PA_CONTEXT_READY:
case PA_CONTEXT_TERMINATED:
case PA_CONTEXT_FAILED:
pa_threaded_mainloop_signal(pa->mainloop, 0);
break;
default:
break;
}
}
static void stream_state_cb(pa_stream *s, void *data)
{
pa_t *pa = (pa_t*)data;
switch (pa_stream_get_state(s))
{
case PA_STREAM_READY:
case PA_STREAM_FAILED:
case PA_STREAM_TERMINATED:
pa_threaded_mainloop_signal(pa->mainloop, 0);
break;
default:
break;
}
}
static void stream_request_cb(pa_stream *s, size_t length, void *data)
{
pa_t *pa = (pa_t*)data;
(void)length;
(void)s;
pa_threaded_mainloop_signal(pa->mainloop, 0);
}
static void stream_latency_update_cb(pa_stream *s, void *data)
{
pa_t *pa = (pa_t*)data;
(void)s;
pa_threaded_mainloop_signal(pa->mainloop, 0);
}
static void underrun_update_cb(pa_stream *s, void *data)
{
#if 0
pa_t *pa = (pa_t*)data;
(void)s;
RARCH_LOG("[PulseAudio]: Underrun (Buffer: %u, Writable size: %u).\n",
(unsigned)pa->buffer_size,
(unsigned)pa_stream_writable_size(pa->stream));
#endif
}
static void buffer_attr_cb(pa_stream *s, void *data)
{
pa_t *pa = (pa_t*)data;
const pa_buffer_attr *server_attr = pa_stream_get_buffer_attr(s);
if (server_attr)
pa->buffer_size = server_attr->tlength;
#if 0
RARCH_LOG("[PulseAudio]: Got new buffer size %u.\n", (unsigned)pa->buffer_size);
#endif
}
static void *pulse_init(const char *device, unsigned rate,
unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
pa_sample_spec spec;
pa_buffer_attr buffer_attr = {0};
const pa_buffer_attr *server_attr = NULL;
pa_t *pa = (pa_t*)calloc(1, sizeof(*pa));
memset(&spec, 0, sizeof(spec));
if (!pa)
goto error;
pa->mainloop = pa_threaded_mainloop_new();
if (!pa->mainloop)
goto error;
pa->context = pa_context_new(pa_threaded_mainloop_get_api(pa->mainloop), "RetroArch");
if (!pa->context)
goto error;
pa_context_set_state_callback(pa->context, context_state_cb, pa);
if (pa_context_connect(pa->context, device, PA_CONTEXT_NOFLAGS, NULL) < 0)
goto error;
pa_threaded_mainloop_lock(pa->mainloop);
if (pa_threaded_mainloop_start(pa->mainloop) < 0)
goto error;
pa_threaded_mainloop_wait(pa->mainloop);
if (pa_context_get_state(pa->context) != PA_CONTEXT_READY)
goto unlock_error;
spec.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE;
spec.channels = 2;
spec.rate = rate;
pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
if (!pa->stream)
goto unlock_error;
pa_stream_set_state_callback(pa->stream, stream_state_cb, pa);
pa_stream_set_write_callback(pa->stream, stream_request_cb, pa);
pa_stream_set_latency_update_callback(pa->stream, stream_latency_update_cb, pa);
pa_stream_set_underflow_callback(pa->stream, underrun_update_cb, pa);
pa_stream_set_buffer_attr_callback(pa->stream, buffer_attr_cb, pa);
buffer_attr.maxlength = -1;
buffer_attr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &spec);
buffer_attr.prebuf = -1;
buffer_attr.minreq = -1;
buffer_attr.fragsize = -1;
if (pa_stream_connect_playback(pa->stream, NULL,
&buffer_attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0)
goto error;
pa_threaded_mainloop_wait(pa->mainloop);
if (pa_stream_get_state(pa->stream) != PA_STREAM_READY)
goto unlock_error;
server_attr = pa_stream_get_buffer_attr(pa->stream);
if (server_attr)
{
pa->buffer_size = server_attr->tlength;
RARCH_LOG("[PulseAudio]: Requested %u bytes buffer, got %u.\n",
(unsigned)buffer_attr.tlength,
(unsigned)pa->buffer_size);
}
else
pa->buffer_size = buffer_attr.tlength;
pa_threaded_mainloop_unlock(pa->mainloop);
return pa;
unlock_error:
pa_threaded_mainloop_unlock(pa->mainloop);
error:
pulse_free(pa);
return NULL;
}
static bool pulse_start(void *data, bool is_shutdown);
static ssize_t pulse_write(void *data, const void *buf_, size_t size)
{
pa_t *pa = (pa_t*)data;
const uint8_t *buf = (const uint8_t*)buf_;
size_t written = 0;
/* Workaround buggy menu code.
* If a write happens while we're paused, we might never progress. */
if (pa->is_paused)
if (!pulse_start(pa, false))
return -1;
pa_threaded_mainloop_lock(pa->mainloop);
while (size)
{
size_t writable = MIN(size, pa_stream_writable_size(pa->stream));
if (writable)
{
pa_stream_write(pa->stream, buf, writable, NULL, 0, PA_SEEK_RELATIVE);
buf += writable;
size -= writable;
written += writable;
}
else if (!pa->nonblock)
pa_threaded_mainloop_wait(pa->mainloop);
else
break;
}
pa_threaded_mainloop_unlock(pa->mainloop);
return written;
}
static bool pulse_stop(void *data)
{
bool ret;
pa_t *pa = (pa_t*)data;
if (pa->is_paused)
return true;
RARCH_LOG("[PulseAudio]: Pausing.\n");
pa->success = true; /* In case of spurious wakeup. Not critical. */
pa_threaded_mainloop_lock(pa->mainloop);
pa_stream_cork(pa->stream, true, stream_success_cb, pa);
pa_threaded_mainloop_wait(pa->mainloop);
ret = pa->success;
pa_threaded_mainloop_unlock(pa->mainloop);
pa->is_paused = true;
return ret;
}
static bool pulse_alive(void *data)
{
pa_t *pa = (pa_t*)data;
if (!pa)
return false;
return !pa->is_paused;
}
static bool pulse_start(void *data, bool is_shutdown)
{
bool ret;
pa_t *pa = (pa_t*)data;
if (!pa->is_paused)
return true;
RARCH_LOG("[PulseAudio]: Unpausing.\n");
pa->success = true; /* In case of spurious wakeup. Not critical. */
pa_threaded_mainloop_lock(pa->mainloop);
pa_stream_cork(pa->stream, false, stream_success_cb, pa);
pa_threaded_mainloop_wait(pa->mainloop);
ret = pa->success;
pa_threaded_mainloop_unlock(pa->mainloop);
pa->is_paused = false;
return ret;
}
static void pulse_set_nonblock_state(void *data, bool state)
{
pa_t *pa = (pa_t*)data;
if (pa)
pa->nonblock = state;
}
static bool pulse_use_float(void *data)
{
(void)data;
return true;
}
static size_t pulse_write_avail(void *data)
{
size_t length;
pa_t *pa = (pa_t*)data;
pa_threaded_mainloop_lock(pa->mainloop);
length = pa_stream_writable_size(pa->stream);
audio_driver_set_buffer_size(pa->buffer_size); /* Can change spuriously. */
pa_threaded_mainloop_unlock(pa->mainloop);
return length;
}
static size_t pulse_buffer_size(void *data)
{
pa_t *pa = (pa_t*)data;
return pa->buffer_size;
}
audio_driver_t audio_pulse = {
pulse_init,
pulse_write,
pulse_stop,
pulse_start,
pulse_alive,
pulse_set_nonblock_state,
pulse_free,
pulse_use_float,
"pulse",
NULL,
NULL,
pulse_write_avail,
pulse_buffer_size,
};

View File

@ -1,153 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <roaraudio.h>
#include <boolean.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
typedef struct
{
roar_vs_t *vss;
bool nonblocking;
bool is_paused;
} roar_t;
static void *ra_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames, unsigned *new_rate)
{
int err;
roar_vs_t *vss = NULL;
roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t));
if (!roar)
return NULL;
(void)latency;
if ((vss = roar_vs_new_simple(device, "RetroArch", rate, 2, ROAR_CODEC_PCM_S, 16, ROAR_DIR_PLAY, &err)) == NULL)
{
RARCH_ERR("RoarAudio: \"%s\"\n", roar_vs_strerr(err));
free(roar);
return NULL;
}
roar_vs_role(vss, ROAR_ROLE_GAME, NULL);
roar->vss = vss;
return roar;
}
static ssize_t ra_write(void *data, const void *buf, size_t size)
{
int err;
size_t written = 0;
roar_t *roar = (roar_t*)data;
if (size == 0)
return 0;
while (written < size)
{
ssize_t rc;
size_t write_amt = size - written;
if ((rc = roar_vs_write(roar->vss,
(const char*)buf + written, write_amt, &err)) < (ssize_t)write_amt)
{
if (roar->nonblocking)
return rc;
else if (rc < 0)
return -1;
}
written += rc;
}
return size;
}
static bool ra_stop(void *data)
{
roar_t *roar = (roar_t*)data;
if (roar)
roar->is_paused = true;
return true;
}
static bool ra_alive(void *data)
{
roar_t *roar = (roar_t*)data;
if (!roar)
return false;
return !roar->is_paused;
}
static void ra_set_nonblock_state(void *data, bool state)
{
roar_t *roar = (roar_t*)data;
if (roar_vs_blocking(roar->vss, (state) ? ROAR_VS_FALSE : ROAR_VS_TRUE, NULL) < 0)
fprintf(stderr, "RetroArch [ERROR]: Can't set nonblocking. Will not be able to fast-forward.\n");
roar->nonblocking = state;
}
static bool ra_start(void *data, bool is_shutdown)
{
roar_t *roar = (roar_t*)data;
if (roar)
roar->is_paused = false;
return true;
}
static void ra_free(void *data)
{
roar_t *roar = (roar_t*)data;
roar_vs_close(roar->vss, ROAR_VS_TRUE, NULL);
free(data);
}
static bool ra_use_float(void *data)
{
return false;
}
static size_t ra_write_avail(void *data)
{
(void)data;
return 0;
}
audio_driver_t audio_roar = {
ra_init,
ra_write,
ra_stop,
ra_start,
ra_alive,
ra_set_nonblock_state,
ra_free,
ra_use_float,
"roar",
NULL,
NULL,
ra_write_avail,
NULL
};

View File

@ -1,243 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <boolean.h>
#include <queues/fifo_queue.h>
#include <rthreads/rthreads.h>
#include "../../retroarch.h"
#include "rsound.h"
typedef struct rsd
{
rsound_t *rd;
bool nonblock;
bool is_paused;
volatile bool has_error;
fifo_buffer_t *buffer;
slock_t *cond_lock;
scond_t *cond;
} rsd_t;
static ssize_t rsound_audio_cb(void *data, size_t bytes, void *userdata)
{
rsd_t *rsd = (rsd_t*)userdata;
size_t avail = fifo_read_avail(rsd->buffer);
size_t write_size = bytes > avail ? avail : bytes;
fifo_read(rsd->buffer, data, write_size);
scond_signal(rsd->cond);
return write_size;
}
static void err_cb(void *userdata)
{
rsd_t *rsd = (rsd_t*)userdata;
rsd->has_error = true;
scond_signal(rsd->cond);
}
static void *rs_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
int channels, format;
rsound_t *rd = NULL;
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
if (!rsd)
return NULL;
if (rsd_init(&rd) < 0)
goto error;
rsd->cond_lock = slock_new();
rsd->cond = scond_new();
rsd->buffer = fifo_new(1024 * 4);
channels = 2;
format = RSD_S16_NE;
rsd_set_param(rd, RSD_CHANNELS, &channels);
rsd_set_param(rd, RSD_SAMPLERATE, &rate);
rsd_set_param(rd, RSD_LATENCY, &latency);
if (device)
rsd_set_param(rd, RSD_HOST, (void*)device);
rsd_set_param(rd, RSD_FORMAT, &format);
rsd_set_callback(rd, rsound_audio_cb, err_cb, 256, rsd);
if (rsd_start(rd) < 0)
{
free(rsd);
goto error;
}
rsd->rd = rd;
return rsd;
error:
rsd_free(rd);
return NULL;
}
static ssize_t rs_write(void *data, const void *buf, size_t size)
{
rsd_t *rsd = (rsd_t*)data;
if (rsd->has_error)
return -1;
if (rsd->nonblock)
{
size_t avail, write_amt;
rsd_callback_lock(rsd->rd);
avail = fifo_write_avail(rsd->buffer);
write_amt = avail > size ? size : avail;
fifo_write(rsd->buffer, buf, write_amt);
rsd_callback_unlock(rsd->rd);
return write_amt;
}
else
{
size_t written = 0;
while (written < size && !rsd->has_error)
{
size_t avail;
rsd_callback_lock(rsd->rd);
avail = fifo_write_avail(rsd->buffer);
if (avail == 0)
{
rsd_callback_unlock(rsd->rd);
if (!rsd->has_error)
{
slock_lock(rsd->cond_lock);
scond_wait(rsd->cond, rsd->cond_lock);
slock_unlock(rsd->cond_lock);
}
}
else
{
size_t write_amt = size - written > avail ? avail : size - written;
fifo_write(rsd->buffer, (const char*)buf + written, write_amt);
rsd_callback_unlock(rsd->rd);
written += write_amt;
}
}
return written;
}
}
static bool rs_stop(void *data)
{
rsd_t *rsd = (rsd_t*)data;
rsd_stop(rsd->rd);
rsd->is_paused = true;
return true;
}
static void rs_set_nonblock_state(void *data, bool state)
{
rsd_t *rsd = (rsd_t*)data;
rsd->nonblock = state;
}
static bool rs_alive(void *data)
{
rsd_t *rsd = (rsd_t*)data;
if (rsd)
return !rsd->is_paused;
return false;
}
static bool rs_start(void *data, bool is_shutdown)
{
rsd_t *rsd = (rsd_t*)data;
if (rsd_start(rsd->rd) < 0)
return false;
rsd->is_paused = false;
return true;
}
static void rs_free(void *data)
{
rsd_t *rsd = (rsd_t*)data;
rsd_stop(rsd->rd);
rsd_free(rsd->rd);
fifo_free(rsd->buffer);
slock_free(rsd->cond_lock);
scond_free(rsd->cond);
free(rsd);
}
static size_t rs_write_avail(void *data)
{
size_t val;
rsd_t *rsd = (rsd_t*)data;
if (rsd->has_error)
return 0;
rsd_callback_lock(rsd->rd);
val = fifo_write_avail(rsd->buffer);
rsd_callback_unlock(rsd->rd);
return val;
}
static size_t rs_buffer_size(void *data)
{
(void)data;
return 1024 * 4;
}
static bool rs_use_float(void *data)
{
(void)data;
return false;
}
audio_driver_t audio_rsound = {
rs_init,
rs_write,
rs_stop,
rs_start,
rs_alive,
rs_set_nonblock_state,
rs_free,
rs_use_float,
"rsound",
NULL,
NULL,
rs_write_avail,
rs_buffer_size,
};

View File

@ -1,323 +0,0 @@
/* RSound - A PCM audio client/server
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
*
* RSound 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.
*
* RSound 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 RSound.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __RSOUND_H
#define __RSOUND_H
#include <sys/types.h>
#include <unistd.h>
#include <rthreads/rthreads.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include <stddef.h>
#include <retro_common_api.h>
#include <queues/fifo_queue.h>
RETRO_BEGIN_DECLS
#ifdef _WIN32
#define RSD_DEFAULT_HOST "127.0.0.1" /* Stupid Windows. */
#else
#define RSD_DEFAULT_HOST "localhost"
#endif
#define RSD_DEFAULT_PORT "12345"
#define RSD_DEFAULT_UNIX_SOCK "/tmp/rsound"
#define RSD_DEFAULT_OBJECT "rsound"
#ifndef RSD_VERSION
#define RSD_VERSION "1.1"
#endif
/* Feature tests */
#define RSD_SAMPLERATE RSD_SAMPLERATE
#define RSD_CHANNELS RSD_CHANNELS
#define RSD_HOST RSD_HOST
#define RSD_PORT RSD_PORT
#define RSD_BUFSIZE RSD_BUFSIZE
#define RSD_LATENCY RSD_LATENCY
#define RSD_FORMAT RSD_FORMAT
#define RSD_IDENTITY RSD_IDENTITY
#define RSD_S16_LE RSD_S16_LE
#define RSD_S16_BE RSD_S16_BE
#define RSD_U16_LE RSD_U16_LE
#define RSD_U16_BE RSD_U16_BE
#define RSD_U8 RSD_U8
#define RSD_S8 RSD_S8
#define RSD_S16_NE RSD_S16_NE
#define RSD_U16_NE RSD_U16_NE
#define RSD_ALAW RSD_ALAW
#define RSD_MULAW RSD_MULAW
#define RSD_S32_LE RSD_S32_LE
#define RSD_S32_BE RSD_S32_BE
#define RSD_S32_NE RSD_S32_NE
#define RSD_U32_LE RSD_U32_LE
#define RSD_U32_BE RSD_U32_BE
#define RSD_U32_NE RSD_U32_NE
#define RSD_DELAY_MS RSD_DELAY_MS
#define RSD_SAMPLESIZE RSD_SAMPLESIZE
#define RSD_EXEC RSD_EXEC
#define RSD_SIMPLE_START RSD_SIMPLE_START
#define RSD_NO_FMT RSD_NO_FMT
#define RSD_USES_OPAQUE_TYPE RSD_USES_OPAQUE_TYPE
#define RSD_USES_SAMPLESIZE_MEMBER RSD_USES_SAMPLESIZE_MEMBER
#define RSD_AUDIO_CALLBACK_T RSD_AUDIO_CALLBACK_T
#define RSD_ERROR_CALLBACK_T RSD_ERROR_CALLBACK_T
#define RSD_SET_CALLBACK RSD_SET_CALLBACK
#define RSD_CALLBACK_LOCK RSD_CALLBACK_LOCK
#define RSD_CALLBACK_UNLOCK RSD_CALLBACK_UNLOCK
/* End feature tests */
/* Defines sample formats available. Defaults to S16_LE should it never be set. */
enum rsd_format
{
RSD_NO_FMT = 0x0000,
RSD_S16_LE = 0x0001,
RSD_S16_BE = 0x0002,
RSD_U16_LE = 0x0004,
RSD_U16_BE = 0x0008,
RSD_U8 = 0x0010,
RSD_S8 = 0x0020,
RSD_S16_NE = 0x0040,
RSD_U16_NE = 0x0080,
RSD_ALAW = 0x0100,
RSD_MULAW = 0x0200,
RSD_S32_LE = 0x0400,
RSD_S32_BE = 0x0800,
RSD_S32_NE = 0x1000,
RSD_U32_LE = 0x2000,
RSD_U32_BE = 0x4000,
RSD_U32_NE = 0x8000
};
/* Defines operations that can be used with rsd_set_param() */
enum rsd_settings
{
RSD_SAMPLERATE = 0,
RSD_CHANNELS,
RSD_HOST,
RSD_PORT,
RSD_BUFSIZE,
RSD_LATENCY,
RSD_FORMAT,
RSD_IDENTITY
};
/* Audio callback for rsd_set_callback. Return -1 to trigger an error in the stream. */
typedef ssize_t (*rsd_audio_callback_t)(void *data, size_t bytes, void *userdata);
/* Error callback. Signals caller that stream has been stopped,
* either by audio callback returning -1 or stream was hung up. */
typedef void (*rsd_error_callback_t)(void *userdata);
/* Defines the main structure for use with the API. */
typedef struct rsound
{
struct
{
volatile int socket;
volatile int ctl_socket;
} conn;
char *host;
char *port;
char *buffer; /* Obsolete, but kept for backwards header compatibility. */
int conn_type;
volatile int buffer_pointer; /* Obsolete, but kept for backwards header compatibility. */
size_t buffer_size;
fifo_buffer_t *fifo_buffer;
volatile int thread_active;
int64_t total_written;
int64_t start_time;
volatile int has_written;
int bytes_in_buffer;
int delay_offset;
int max_latency;
struct
{
uint32_t latency;
uint32_t chunk_size;
} backend_info;
volatile int ready_for_data;
uint32_t rate;
uint32_t channels;
uint16_t format;
int samplesize;
struct
{
sthread_t *thread;
slock_t *mutex;
slock_t *cond_mutex;
scond_t *cond;
} thread;
char identity[256];
rsd_audio_callback_t audio_callback;
rsd_error_callback_t error_callback;
size_t cb_max_size;
void *cb_data;
slock_t *cb_lock;
} rsound_t;
/* -- API --
All functions (except for rsd_write() return 0 for success, and -1 for error. errno is currently not set. */
/* Initializes an rsound_t structure. To make sure no memory leaks occur, you need to rsd_free() it after use.
A typical use of the API is as follows:
rsound_t *rd;
rsd_init(&rd);
rsd_set_param(rd, RSD_HOST, "foohost");
*sets more params*
rsd_start(rd);
rsd_write(rd, buf, size);
rsd_stop(rd);
rsd_free(rd);
*/
int rsd_init (rsound_t **rd);
/* This is a simpler function that initializes an rsound struct, sets params as given,
and starts the stream. Should this function fail, the structure will stay uninitialized.
Should NULL be passed in either host, port or ident, defaults will be used. */
int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const char* ident,
int rate, int channels, enum rsd_format format);
/* Sets params associated with an rsound_t. These options (int options) include:
RSD_HOST: Server to connect to. Expects (char *) in param.
If not set, will default to environmental variable RSD_SERVER or "localhost".
RSD_PORT: Set port. Expects (char *) in param.
If not set, will default to environmental variable RSD_PORT or "12345".
RSD_CHANNELS: Set number of audio channels. Expects (int *) in param. Mandatory.
RSD_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory.
RSD_BUFSIZE: Sets internal buffersize for the stream.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_LATENCY: Sets maximum audio latency in milliseconds,
(must be used with rsd_delay_wait() or this will have no effect).
Most applications do not need this.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_FORMAT: Sets sample format.
It defaults to S16_LE, so you probably will not use this.
Expects (int *) in param, with available values found in the format enum.
If invalid format is given, param might be changed to reflect the sample format the library will use.
RSD_IDENTITY: Sets an identity string associated with the client.
Takes a (char *) parameter with the stream name.
Will be truncated if longer than 256 bytes.
*/
int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param);
/* Enables use of the callback interface. This must be set when stream is not active.
When callback is active, use of the blocking interface is disabled.
Only valid functions to call after rsd_start() is stopping the stream with either rsd_pause() or rsd_stop(). Calling any other function is undefined.
The callback is called at regular intervals and is asynchronous, so thread safety must be ensured by the caller.
If not enough data can be given to the callback, librsound will fill the rest of the callback data with silence.
librsound will attempt to obey latency information given with RSD_LATENCY as given before calling rsd_start().
max_size signifies the maximum size that will ever be requested by librsound. Set this to 0 to let librsound decide the maximum size.
Should an error occur to the stream, err_callback will be called, and the stream will be stopped. The stream can be started again.
Callbacks can be disabled by setting callbacks to NULL. */
void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_callback_t err_callback, size_t max_size, void *userdata);
/* Lock and unlock the callback. When the callback lock is aquired, the callback is guaranteed to not be executing.
The lock has to be unlocked afterwards.
Attemping to call several rsd_callback_lock() in succession might cause a deadlock.
The lock should be held for as short period as possible.
Try to avoid calling code that may block when holding the lock. */
void rsd_callback_lock (rsound_t *rd);
void rsd_callback_unlock (rsound_t *rd);
/* Establishes connection to server. Might fail if connection can't be established or that one of
the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set
with rsd_set_param(), and before rsd_write(). */
int rsd_start (rsound_t *rd);
/* Shuts down the rsound data structures, but returns the file descriptor associated with the connection.
The control socket will be shut down. If this function returns a negative number, the exec failed,
but the data structures will not be teared down.
Should a valid file descriptor be returned, it will always be blocking.
This call will block until all internal buffers have been sent to the network. */
int rsd_exec (rsound_t *rd);
/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped.
To continue playing, you will need to rsd_start() again. */
int rsd_stop (rsound_t *rd);
/* Writes from buf to the internal buffer. Might fail if no connection is established,
or there was an unexpected error. This function will block until all data has
been written to the buffer. This function will return the number of bytes written to the buffer,
or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */
size_t rsd_write (rsound_t *rd, const void* buf, size_t size);
/* Gets the position of the buffer pointer.
Not really interesting for normal applications.
Might be useful for implementing rsound on top of other blocking APIs.
*NOTE* This function is deprecated, it should not be used in new applications. */
size_t rsd_pointer (rsound_t *rd);
/* Aquires how much data can be written to the buffer without blocking */
size_t rsd_get_avail (rsound_t *rd);
/* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */
size_t rsd_delay (rsound_t *rd);
/* Utility for returning latency in milliseconds. */
size_t rsd_delay_ms (rsound_t *rd);
/* Returns bytes per sample */
int rsd_samplesize(rsound_t *rd);
/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY
Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set
with RSD_LATENCY, this function will do nothing. */
void rsd_delay_wait(rsound_t *rd);
/* Pauses or unpauses a stream. pause -> enable = 1
This function essentially calls on start() and stop(). This behavior might be changed later. */
int rsd_pause (rsound_t *rd, int enable);
/* Frees an rsound_t struct. Make sure that the stream is properly closed down with rsd_stop() before calling rsd_free(). */
int rsd_free (rsound_t *rd);
RETRO_END_DECLS
#endif

View File

@ -1,118 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2015 - Michael Lelli
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <unistd.h>
#include <boolean.h>
#include "../../retroarch.h"
/* forward declarations */
unsigned RWebAudioSampleRate(void);
void *RWebAudioInit(unsigned latency);
ssize_t RWebAudioWrite(const void *buf, size_t size);
bool RWebAudioStop(void);
bool RWebAudioStart(void);
void RWebAudioSetNonblockState(bool state);
void RWebAudioFree(void);
size_t RWebAudioWriteAvail(void);
size_t RWebAudioBufferSize(void);
static bool rwebaudio_is_paused;
static void rwebaudio_free(void *data)
{
RWebAudioFree();
}
static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
void *data = RWebAudioInit(latency);
(void)device;
(void)rate;
if (data)
*new_rate = RWebAudioSampleRate();
return data;
}
static ssize_t rwebaudio_write(void *data, const void *buf, size_t size)
{
(void)data;
return RWebAudioWrite(buf, size);
}
static bool rwebaudio_stop(void *data)
{
(void)data;
rwebaudio_is_paused = true;
return RWebAudioStop();
}
static void rwebaudio_set_nonblock_state(void *data, bool state)
{
(void)data;
RWebAudioSetNonblockState(state);
}
static bool rwebaudio_alive(void *data)
{
(void)data;
return !rwebaudio_is_paused;
}
static bool rwebaudio_start(void *data, bool is_shutdown)
{
(void)data;
rwebaudio_is_paused = false;
return RWebAudioStart();
}
static size_t rwebaudio_write_avail(void *data)
{
(void)data;
return RWebAudioWriteAvail();
}
static size_t rwebaudio_buffer_size(void *data)
{
(void)data;
return RWebAudioBufferSize();
}
static bool rwebaudio_use_float(void *data)
{
(void)data;
return true;
}
audio_driver_t audio_rwebaudio = {
rwebaudio_init,
rwebaudio_write,
rwebaudio_stop,
rwebaudio_start,
rwebaudio_alive,
rwebaudio_set_nonblock_state,
rwebaudio_free,
rwebaudio_use_float,
"rwebaudio",
NULL,
NULL,
rwebaudio_write_avail,
rwebaudio_buffer_size,
};

View File

@ -1,275 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <boolean.h>
#include <rthreads/rthreads.h>
#include <queues/fifo_queue.h>
#include <retro_inline.h>
#include <retro_math.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
#include "SDL.h"
#include "SDL_audio.h"
typedef struct sdl_audio
{
bool nonblock;
bool is_paused;
#ifdef HAVE_THREADS
slock_t *lock;
scond_t *cond;
#endif
fifo_buffer_t *buffer;
} sdl_audio_t;
static void sdl_audio_cb(void *data, Uint8 *stream, int len)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
size_t avail = fifo_read_avail(sdl->buffer);
size_t write_size = len > (int)avail ? avail : len;
fifo_read(sdl->buffer, stream, write_size);
#ifdef HAVE_THREADS
scond_signal(sdl->cond);
#endif
/* If underrun, fill rest with silence. */
memset(stream + write_size, 0, len - write_size);
}
static INLINE int find_num_frames(int rate, int latency)
{
int frames = (rate * latency) / 1000;
/* SDL only likes 2^n sized buffers. */
return next_pow2(frames);
}
static void *sdl_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
int frames;
size_t bufsize;
SDL_AudioSpec out;
SDL_AudioSpec spec = {0};
void *tmp = NULL;
sdl_audio_t *sdl = NULL;
(void)device;
if (SDL_WasInit(0) == 0)
{
if (SDL_Init(SDL_INIT_AUDIO) < 0)
return NULL;
}
else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
return NULL;
sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl));
if (!sdl)
return NULL;
/* We have to buffer up some data ourselves, so we let SDL
* carry approximately half of the latency.
*
* SDL double buffers audio and we do as well. */
frames = find_num_frames(rate, latency / 4);
spec.freq = rate;
spec.format = AUDIO_S16SYS;
spec.channels = 2;
spec.samples = frames; /* This is in audio frames, not samples ... :( */
spec.callback = sdl_audio_cb;
spec.userdata = sdl;
if (SDL_OpenAudio(&spec, &out) < 0)
{
RARCH_ERR("[SDL audio]: Failed to open SDL audio: %s\n", SDL_GetError());
goto error;
}
*new_rate = out.freq;
#ifdef HAVE_THREADS
sdl->lock = slock_new();
sdl->cond = scond_new();
#endif
RARCH_LOG("[SDL audio]: Requested %u ms latency, got %d ms\n",
latency, (int)(out.samples * 4 * 1000 / (*new_rate)));
/* Create a buffer twice as big as needed and prefill the buffer. */
bufsize = out.samples * 4 * sizeof(int16_t);
tmp = calloc(1, bufsize);
sdl->buffer = fifo_new(bufsize);
if (tmp)
{
fifo_write(sdl->buffer, tmp, bufsize);
free(tmp);
}
SDL_PauseAudio(0);
return sdl;
error:
free(sdl);
return NULL;
}
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
{
ssize_t ret = 0;
sdl_audio_t *sdl = (sdl_audio_t*)data;
if (sdl->nonblock)
{
size_t avail, write_amt;
SDL_LockAudio();
avail = fifo_write_avail(sdl->buffer);
write_amt = avail > size ? size : avail;
fifo_write(sdl->buffer, buf, write_amt);
SDL_UnlockAudio();
ret = write_amt;
}
else
{
size_t written = 0;
while (written < size)
{
size_t avail;
SDL_LockAudio();
avail = fifo_write_avail(sdl->buffer);
if (avail == 0)
{
SDL_UnlockAudio();
#ifdef HAVE_THREADS
slock_lock(sdl->lock);
scond_wait(sdl->cond, sdl->lock);
slock_unlock(sdl->lock);
#endif
}
else
{
size_t write_amt = size - written > avail ? avail : size - written;
fifo_write(sdl->buffer, (const char*)buf + written, write_amt);
SDL_UnlockAudio();
written += write_amt;
}
}
ret = written;
}
return ret;
}
static bool sdl_audio_stop(void *data)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
sdl->is_paused = true;
SDL_PauseAudio(1);
return true;
}
static bool sdl_audio_alive(void *data)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
if (!sdl)
return false;
return !sdl->is_paused;
}
static bool sdl_audio_start(void *data, bool is_shutdown)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
sdl->is_paused = false;
SDL_PauseAudio(0);
return true;
}
static void sdl_audio_set_nonblock_state(void *data, bool state)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
if (sdl)
sdl->nonblock = state;
}
static void sdl_audio_free(void *data)
{
sdl_audio_t *sdl = (sdl_audio_t*)data;
SDL_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
if (sdl)
{
fifo_free(sdl->buffer);
#ifdef HAVE_THREADS
slock_free(sdl->lock);
scond_free(sdl->cond);
#endif
}
free(sdl);
}
static bool sdl_audio_use_float(void *data)
{
(void)data;
return false;
}
static size_t sdl_audio_write_avail(void *data)
{
/* stub */
(void)data;
return 0;
}
audio_driver_t audio_sdl = {
sdl_audio_init,
sdl_audio_write,
sdl_audio_stop,
sdl_audio_start,
sdl_audio_alive,
sdl_audio_set_nonblock_state,
sdl_audio_free,
sdl_audio_use_float,
#ifdef HAVE_SDL2
"sdl2",
#else
"sdl",
#endif
NULL,
NULL,
sdl_audio_write_avail,
NULL
};

View File

@ -1,364 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2018 - misson20000
* Copyright (C) 2018 - m4xw
*
* 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 <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdint.h>
#include "switch_audio_compat.h"
#include "../../retroarch.h"
#include "../../verbosity.h"
#ifdef HAVE_LIBNX
#define BUFFER_COUNT 5
#else
#define BUFFER_COUNT 3
#endif
static const int sample_rate = 48000;
static const int max_num_samples = sample_rate;
static const int num_channels = 2;
static const size_t sample_buffer_size = ((max_num_samples * num_channels * sizeof(uint16_t)) + 0xfff) & ~0xfff;
typedef struct
{
bool blocking;
bool is_paused;
uint64_t last_append;
unsigned latency;
compat_audio_out_buffer buffers[BUFFER_COUNT];
compat_audio_out_buffer *current_buffer;
#ifndef HAVE_LIBNX
audio_output_t output;
handle_t event;
#endif
} switch_audio_t;
static uint32_t switch_audio_data_size(void)
{
#ifdef HAVE_LIBNX
static const int framerate = 1000 / 30;
static const int samplecount = (sample_rate / framerate);
return (samplecount * num_channels * sizeof(uint16_t));
#else
return sample_buffer_size;
#endif
}
static size_t switch_audio_buffer_size(void *data)
{
(void) data;
#ifdef HAVE_LIBNX
return (switch_audio_data_size() + 0xfff) & ~0xfff;
#else
return sample_buffer_size;
#endif
}
static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
{
size_t to_write = size;
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa)
return -1;
if (!swa->current_buffer)
{
uint32_t num;
if (switch_audio_ipc_output_get_released_buffer(swa, num) != 0)
{
RARCH_LOG("Failed to get released buffer?\n");
return -1;
}
if (num < 1)
swa->current_buffer = NULL;
if (!swa->current_buffer)
{
if (swa->blocking)
{
while(swa->current_buffer == NULL)
{
uint32_t handle_idx = 0;
num = 0;
#ifdef HAVE_LIBNX
if (audoutWaitPlayFinish(&swa->current_buffer, &num, U64_MAX) != 0) { }
#else
svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333);
svcResetSignal(swa->event);
if (switch_audio_ipc_output_get_released_buffer(swa, num) != 0)
return -1;
#endif
}
}
else
/* no buffer, nonblocking... */
return 0;
}
swa->current_buffer->data_size = 0;
}
if (to_write > switch_audio_buffer_size(NULL) - swa->current_buffer->data_size)
to_write = switch_audio_buffer_size(NULL) - swa->current_buffer->data_size;
#ifndef HAVE_LIBNX
memcpy(((uint8_t*) swa->current_buffer->sample_data) + swa->current_buffer->data_size, buf, to_write);
#else
memcpy(((uint8_t*) swa->current_buffer->buffer) + swa->current_buffer->data_size, buf, to_write);
#endif
swa->current_buffer->data_size += to_write;
swa->current_buffer->buffer_size = switch_audio_buffer_size(NULL);
if (swa->current_buffer->data_size > (48000 * swa->latency) / 1000)
{
if (switch_audio_ipc_output_append_buffer(swa, swa->current_buffer) != 0)
return -1;
swa->current_buffer = NULL;
}
swa->last_append = svcGetSystemTick();
return to_write;
}
static bool switch_audio_stop(void *data)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa)
return false;
/* TODO/FIXME - fix libnx codepath */
#ifndef HAVE_LIBNX
if (!swa->is_paused)
if (switch_audio_ipc_output_stop(swa) != 0)
return false;
swa->is_paused = true;
#endif
return true;
}
static bool switch_audio_start(void *data, bool is_shutdown)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa)
return false;
/* TODO/FIXME - fix libnx codepath */
#ifndef HAVE_LIBNX
if (swa->is_paused)
if (switch_audio_ipc_output_start(swa) != 0)
return false;
swa->is_paused = false;
#endif
return true;
}
static bool switch_audio_alive(void *data)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa)
return false;
return !swa->is_paused;
}
static void switch_audio_free(void *data)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa)
return;
#ifdef HAVE_LIBNX
if (!swa->is_paused)
audoutStopAudioOut();
audoutExit();
int i;
for (i = 0; i < BUFFER_COUNT; i++)
free(swa->buffers[i].buffer);
#else
audio_ipc_output_close(&swa->output);
audio_ipc_finalize();
#endif
free(swa);
}
static bool switch_audio_use_float(void *data)
{
(void) data;
return false; /* force INT16 */
}
static size_t switch_audio_write_avail(void *data)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (!swa || !swa->current_buffer)
return 0;
return swa->current_buffer->buffer_size;
}
static void switch_audio_set_nonblock_state(void *data, bool state)
{
switch_audio_t *swa = (switch_audio_t*) data;
if (swa)
swa->blocking = !state;
}
static void *switch_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
unsigned i;
char names[8][0x20];
uint32_t num_names = 0;
switch_audio_t *swa = (switch_audio_t*) calloc(1, sizeof(*swa));
if (!swa)
return NULL;
if (switch_audio_ipc_init() != 0)
goto fail;
#ifdef HAVE_LIBNX
if (audoutStartAudioOut() != 0)
goto fail;
#else
if (audio_ipc_list_outputs(&names[0], 8, &num_names) != 0)
goto fail_audio_ipc;
if (num_names != 1)
{
RARCH_ERR("got back more than one AudioOut\n");
goto fail_audio_ipc;
}
if (audio_ipc_open_output(names[0], &swa->output) != 0)
goto fail_audio_ipc;
if (swa->output.sample_rate != sample_rate)
{
RARCH_ERR("expected sample rate of %d, got sample rate of %d\n",
sample_rate, swa->output.sample_rate);
goto fail_audio_output;
}
if (swa->output.num_channels != num_channels)
{
RARCH_ERR("expected %d channels, got %d\n", num_channels,
swa->output.num_channels);
goto fail_audio_output;
}
if (swa->output.sample_format != PCM_INT16)
{
RARCH_ERR("expected PCM_INT16, got %d\n", swa->output.sample_format);
goto fail_audio_output;
}
if (audio_ipc_output_register_buffer_event(&swa->output, &swa->event) != 0)
goto fail_audio_output;
#endif
for (i = 0; i < BUFFER_COUNT; i++)
{
swa->buffers[i].buffer_size = switch_audio_buffer_size(NULL);
swa->buffers[i].data_size = switch_audio_data_size();
#ifdef HAVE_LIBNX
swa->buffers[i].next = NULL; /* Unused */
swa->buffers[i].data_offset = 0;
swa->buffers[i].buffer = memalign(0x1000, switch_audio_buffer_size(NULL));
if (swa->buffers[i].buffer == NULL)
goto fail_audio_output;
memset(swa->buffers[i].buffer, 0, switch_audio_buffer_size(NULL));
#else
swa->buffers[i].ptr = &swa->buffers[i].sample_data;
swa->buffers[i].unknown = 0;
swa->buffers[i].sample_data = alloc_pages(sample_buffer_size, switch_audio_buffer_size(NULL), NULL);
if (swa->buffers[i].sample_data == NULL)
goto fail_audio_output;
#endif
if (switch_audio_ipc_output_append_buffer(swa, &swa->buffers[i]) != 0)
goto fail_audio_output;
}
#ifdef HAVE_LIBNX
*new_rate = audoutGetSampleRate();
#else
*new_rate = swa->output.sample_rate;
#endif
swa->current_buffer = NULL;
swa->latency = latency;
swa->last_append = svcGetSystemTick();
swa->blocking = block_frames;
swa->is_paused = true;
RARCH_LOG("[Audio]: Audio initialized\n");
return swa;
fail_audio_output:
/* TODO/FIXME - fix libnx codepath */
#ifndef HAVE_LIBNX
audio_ipc_output_close(&swa->output);
#endif
fail_audio_ipc:
/* TODO/FIXME - fix libnx codepath */
#ifndef HAVE_LIBNX
audio_ipc_finalize();
#endif
fail:
if (swa)
free(swa);
return NULL;
}
audio_driver_t audio_switch = {
switch_audio_init,
switch_audio_write,
switch_audio_stop,
switch_audio_start,
switch_audio_alive,
switch_audio_set_nonblock_state,
switch_audio_free,
switch_audio_use_float,
"switch",
NULL, /* device_list_new */
NULL, /* device_list_free */
switch_audio_write_avail,
switch_audio_buffer_size, /* buffer_size */
};

View File

@ -1,93 +0,0 @@
#ifndef _SWITCH_AUDIO_COMPAT_H
#define _SWITCH_AUDIO_COMPAT_H
#ifdef HAVE_LIBNX
#include <switch.h>
#else
#include <libtransistor/nx.h>
#endif
#ifdef HAVE_LIBNX
/* libnx definitions */
/* threading */
typedef Mutex compat_mutex;
typedef Thread compat_thread;
typedef CondVar compat_condvar;
#define compat_thread_create(thread, func, data, stack_size, prio, cpu) \
threadCreate(thread, func, data, stack_size, prio, cpu)
#define compat_thread_start(thread) \
threadStart(thread)
#define compat_thread_join(thread) \
threadWaitForExit(thread)
#define compat_thread_close(thread) \
threadClose(thread)
#define compat_mutex_create(mutex) \
mutexInit(mutex)
#define compat_mutex_lock(mutex) \
mutexLock(mutex)
#define compat_mutex_unlock(mutex) \
mutexUnlock(mutex)
#define compat_condvar_create(condvar) \
condvarInit(condvar)
#define compat_condvar_wait(condvar, mutex) \
condvarWait(condvar, mutex)
#define compat_condvar_wake_all(condvar) \
condvarWakeAll(condvar)
/* audio */
typedef AudioOutBuffer compat_audio_out_buffer;
#define switch_audio_ipc_init audoutInitialize
#define switch_audio_ipc_finalize audoutExit
#define switch_audio_ipc_output_get_released_buffer(a, b) audoutGetReleasedAudioOutBuffer(&a->current_buffer, &b)
#define switch_audio_ipc_output_append_buffer(a, b) audoutAppendAudioOutBuffer(b)
#define switch_audio_ipc_output_stop(a) audoutStopAudioOut()
#define switch_audio_ipc_output_start(a) audoutStartAudioOut()
#else
/* libtransistor definitions */
typedef result_t Result;
#define R_FAILED(r) ((r) != RESULT_OK)
/* threading */
typedef trn_mutex_t compat_mutex;
typedef trn_thread_t compat_thread;
typedef trn_condvar_t compat_condvar;
#define compat_thread_create(thread, func, data, stack_size, prio, cpu) \
trn_thread_create(thread, func, data, prio, cpu, stack_size, NULL)
#define compat_thread_start(thread) \
trn_thread_start(thread)
#define compat_thread_join(thread) \
trn_thread_join(thread, -1)
#define compat_thread_close(thread) \
trn_thread_destroy(thread)
#define compat_mutex_create(mutex) \
trn_mutex_create(mutex)
#define compat_mutex_lock(mutex) \
trn_mutex_lock(mutex)
#define compat_mutex_unlock(mutex) \
trn_mutex_unlock(mutex)
#define compat_condvar_create(condvar) \
trn_condvar_create(condvar)
#define compat_condvar_wait(condvar, mutex) \
trn_condvar_wait(condvar, mutex, -1)
#define compat_condvar_wake_all(condvar) \
trn_condvar_signal(condvar, -1)
/* audio */
typedef audio_output_buffer_t compat_audio_out_buffer;
#define switch_audio_ipc_init audio_ipc_init
#define switch_audio_ipc_finalize audio_ipc_finalize
#define switch_audio_ipc_output_get_released_buffer(a, b) audio_ipc_output_get_released_buffer(&a->output, &b, &a->current_buffer)
#define switch_audio_ipc_output_append_buffer(a, b) audio_ipc_output_append_buffer(&a->output, b)
#define switch_audio_ipc_output_stop(a) audio_ipc_output_stop(&a->output)
#define switch_audio_ipc_output_start(a) audio_ipc_output_start(&a->output)
#endif
#endif

View File

@ -1,447 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2018 - misson20000
* Copyright (C) 2018 - m4xw
* Copyright (C) 2018 - lifajucejo
*
* 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 <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdint.h>
#include <sys/unistd.h>
#ifdef HAVE_LIBNX
#include <switch.h>
#else
#include <libtransistor/nx.h>
#endif
#include <queues/fifo_queue.h>
#include "../../retroarch.h"
#include "../../verbosity.h"
#include "../../tasks/tasks_internal.h"
#include "switch_audio_compat.h"
static const size_t thread_stack_size = 1024 * 8;
static const int thread_preferred_cpu = 2;
static const int channel_count = 2;
static const size_t sample_size = sizeof(uint16_t);
static const size_t frame_size = channel_count * sample_size;
#define AUDIO_BUFFER_COUNT 2
typedef struct
{
fifo_buffer_t* fifo;
compat_mutex fifoLock;
compat_condvar cond;
compat_mutex condLock;
size_t fifoSize;
volatile bool running;
bool nonblocking;
bool is_paused;
compat_audio_out_buffer buffers[AUDIO_BUFFER_COUNT];
compat_thread thread;
unsigned latency;
uint32_t sampleRate;
#ifndef HAVE_LIBNX
audio_output_t output;
handle_t event;
#endif
} switch_thread_audio_t;
static void mainLoop(void* data)
{
Result rc;
uint32_t released_out_count = 0;
compat_audio_out_buffer *released_out_buffer = NULL;
switch_thread_audio_t *swa = (switch_thread_audio_t*)data;
if (!swa)
return;
RARCH_LOG("[Audio]: start mainLoop cpu %u tid %u\n", svcGetCurrentProcessorNumber(), swa->thread.handle);
while (swa->running)
{
size_t buf_avail, avail, to_write;
if (!released_out_buffer)
{
#ifdef HAVE_LIBNX
rc = audoutWaitPlayFinish(&released_out_buffer, &released_out_count, U64_MAX);
#else
uint32_t handle_idx = 0;
svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333);
svcResetSignal(swa->event);
rc = audio_ipc_output_get_released_buffer(&swa->output, &released_out_count, &released_out_buffer);
#endif
if (R_FAILED(rc))
{
swa->running = false;
RARCH_LOG("[Audio]: audoutGetReleasedAudioOutBuffer failed: %d\n", (int)rc);
break;
}
released_out_buffer->data_size = 0;
}
buf_avail = released_out_buffer->buffer_size - released_out_buffer->data_size;
compat_mutex_lock(&swa->fifoLock);
avail = fifo_read_avail(swa->fifo);
to_write = MIN(avail, buf_avail);
if (to_write > 0)
{
uint8_t *base;
#ifdef HAVE_LIBNX
base = (uint8_t*) released_out_buffer->buffer;
#else
base = (uint8_t*) released_out_buffer->sample_data;
#endif
fifo_read(swa->fifo, base + released_out_buffer->data_size, to_write);
}
compat_mutex_unlock(&swa->fifoLock);
compat_condvar_wake_all(&swa->cond);
released_out_buffer->data_size += to_write;
if (released_out_buffer->data_size >= released_out_buffer->buffer_size / 2)
{
rc = switch_audio_ipc_output_append_buffer(swa, released_out_buffer);
if (R_FAILED(rc))
{
RARCH_LOG("[Audio]: audoutAppendAudioOutBuffer failed: %d\n", (int)rc);
}
released_out_buffer = NULL;
}
else
svcSleepThread(16000000); /* 16ms */
}
}
static void *switch_thread_audio_init(const char *device, unsigned rate, unsigned latency, unsigned block_frames, unsigned *new_rate)
{
Result rc;
unsigned i;
uint32_t prio;
char names[8][0x20];
uint32_t num_names = 0;
switch_thread_audio_t *swa = (switch_thread_audio_t *)calloc(1, sizeof(*swa));
if (!swa)
return NULL;
swa->running = true;
swa->nonblocking = true;
swa->is_paused = true;
swa->latency = MAX(latency, 8);
rc = switch_audio_ipc_init();
if (R_FAILED(rc))
{
RARCH_LOG("[Audio]: audio init failed %d\n", (int)rc);
free(swa);
return NULL;
}
#ifdef HAVE_LIBNX
rc = audoutStartAudioOut();
if (R_FAILED(rc))
{
RARCH_LOG("[Audio]: audio start init failed: %d\n", (int)rc);
goto fail_audio_ipc;
}
swa->sampleRate = audoutGetSampleRate();
#else
if (audio_ipc_list_outputs(&names[0], 8, &num_names) != RESULT_OK)
goto fail_audio_ipc;
if (num_names != 1)
{
RARCH_ERR("[Audio]: got back more than one AudioOut\n");
goto fail_audio_ipc;
}
if (audio_ipc_open_output(names[0], &swa->output) != RESULT_OK)
goto fail_audio_ipc;
swa->sampleRate = swa->output.sample_rate;
if (swa->output.num_channels != 2)
{
RARCH_ERR("expected %d channels, got %d\n", 2,
swa->output.num_channels);
goto fail_audio_output;
}
if (swa->output.sample_format != PCM_INT16)
{
RARCH_ERR("expected PCM_INT16, got %d\n", swa->output.sample_format);
goto fail_audio_output;
}
if (audio_ipc_output_register_buffer_event(&swa->output, &swa->event) != 0)
goto fail_audio_output;
#endif
*new_rate = swa->sampleRate;
swa->fifoSize = (swa->sampleRate * sample_size * swa->latency) / 1000;
for (i = 0; i < AUDIO_BUFFER_COUNT; i++)
{
#ifdef HAVE_LIBNX
swa->buffers[i].next = NULL; /* Unused */
swa->buffers[i].data_offset = 0;
swa->buffers[i].buffer_size = swa->fifoSize;
swa->buffers[i].data_size = swa->buffers[i].buffer_size;
swa->buffers[i].buffer = memalign(0x1000, swa->buffers[i].buffer_size);
if (swa->buffers[i].buffer == NULL)
goto fail;
memset(swa->buffers[i].buffer, 0, swa->buffers[i].buffer_size);
#else
swa->buffers[i].ptr = &swa->buffers[i].sample_data;
swa->buffers[i].unknown = 0;
swa->buffers[i].buffer_size = swa->fifoSize;
swa->buffers[i].data_size = swa->buffers[i].buffer_size;
swa->buffers[i].sample_data = alloc_pages(swa->buffers[i].buffer_size, swa->buffers[i].buffer_size, NULL);
if (swa->buffers[i].sample_data == NULL)
goto fail_audio_output;
memset(swa->buffers[i].sample_data, 0, swa->buffers[i].buffer_size);
#endif
if (switch_audio_ipc_output_append_buffer(swa, &swa->buffers[i]) != 0)
goto fail_audio_output;
}
compat_mutex_create(&swa->fifoLock);
swa->fifo = fifo_new(swa->fifoSize);
compat_condvar_create(&swa->cond);
RARCH_LOG("[Audio]: switch_thread_audio_init device %s requested rate %hu rate %hu latency %hu block_frames %hu fifoSize %lu\n",
device, rate, swa->sampleRate, swa->latency, block_frames, swa->fifoSize);
svcGetThreadPriority(&prio, 0xffff8000);
rc = compat_thread_create(&swa->thread, &mainLoop, (void*)swa, thread_stack_size, prio - 1, thread_preferred_cpu);
if (R_FAILED(rc))
{
RARCH_LOG("[Audio]: thread creation failed create %u\n", swa->thread.handle);
swa->running = false;
return NULL;
}
if (R_FAILED(compat_thread_start(&swa->thread)))
{
RARCH_LOG("[Audio]: thread creation failed start %u\n", swa->thread.handle);
compat_thread_close(&swa->thread);
swa->running = false;
return NULL;
}
return swa;
fail_audio_output:
#ifndef HAVE_LIBNX
audio_ipc_output_close(&swa->output);
#endif
fail_audio_ipc:
switch_audio_ipc_finalize();
fail:
free(swa); // freeing a null ptr is valid
return NULL;
}
static bool switch_thread_audio_start(void *data, bool is_shutdown)
{
/* RARCH_LOG("[Audio]: switch_thread_audio_start\n"); */
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (!swa)
return false;
swa->is_paused = false;
return true;
}
static bool switch_thread_audio_stop(void *data)
{
switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
if (!swa)
return false;
swa->is_paused = true;
return true;
}
static void switch_thread_audio_free(void *data)
{
unsigned i;
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (!swa)
return;
if (swa->running)
{
swa->running = false;
compat_thread_join(&swa->thread);
compat_thread_close(&swa->thread);
}
switch_audio_ipc_output_stop(swa);
switch_audio_ipc_finalize();
if (swa->fifo)
{
fifo_free(swa->fifo);
swa->fifo = NULL;
}
for (i = 0; i < ARRAY_SIZE(swa->buffers); i++)
{
#ifdef HAVE_LIBNX
free(swa->buffers[i].buffer);
#else
free_pages(swa->buffers[i].sample_data);
#endif
}
free(swa);
swa = NULL;
}
static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t size)
{
size_t avail, written;
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (!swa || !swa->running)
return 0;
if (swa->nonblocking)
{
compat_mutex_lock(&swa->fifoLock);
avail = fifo_write_avail(swa->fifo);
written = MIN(avail, size);
if (written > 0)
fifo_write(swa->fifo, buf, written);
compat_mutex_unlock(&swa->fifoLock);
}
else
{
written = 0;
while (written < size && swa->running)
{
compat_mutex_lock(&swa->fifoLock);
avail = fifo_write_avail(swa->fifo);
if (avail == 0)
{
compat_mutex_unlock(&swa->fifoLock);
compat_mutex_lock(&swa->condLock);
if (swa->running)
compat_condvar_wait(&swa->cond, &swa->condLock);
compat_mutex_unlock(&swa->condLock);
}
else
{
size_t write_amt = MIN(size - written, avail);
fifo_write(swa->fifo, (const char*)buf + written, write_amt);
compat_mutex_unlock(&swa->fifoLock);
written += write_amt;
}
}
}
return written;
}
static bool switch_thread_audio_alive(void *data)
{
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (!swa)
return false;
return !swa->is_paused;
}
static void switch_thread_audio_set_nonblock_state(void *data, bool state)
{
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (swa)
swa->nonblocking = state;
}
static bool switch_thread_audio_use_float(void *data)
{
(void)data;
return false;
}
static size_t switch_thread_audio_write_avail(void *data)
{
size_t val;
switch_thread_audio_t* swa = (switch_thread_audio_t*)data;
compat_mutex_lock(&swa->fifoLock);
val = fifo_write_avail(swa->fifo);
compat_mutex_unlock(&swa->fifoLock);
return val;
}
size_t switch_thread_audio_buffer_size(void *data)
{
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (!swa)
return 0;
return swa->fifoSize;
}
audio_driver_t audio_switch_thread = {
switch_thread_audio_init,
switch_thread_audio_write,
switch_thread_audio_stop,
switch_thread_audio_start,
switch_thread_audio_alive,
switch_thread_audio_set_nonblock_state,
switch_thread_audio_free,
switch_thread_audio_use_float,
"switch_thread",
NULL, /* device_list_new */
NULL, /* device_list_free */
switch_thread_audio_write_avail,
switch_thread_audio_buffer_size
};
/* vim: set ts=3 sw=3 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,336 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Ali Bouhlel
* Copyright (C) 2016-2017 - FIX94
*
* 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 <string.h>
#include <malloc.h>
#include <stdint.h>
#include <wiiu/os.h>
#include <wiiu/ax.h>
#include "../../wiiu/wiiu_dbg.h"
#include "../../wiiu/system/memory.h"
#include "../../retroarch.h"
typedef struct
{
AXMVoice* mvoice;
uint16_t* buffer_l;
uint16_t* buffer_r;
bool nonblocking;
uint32_t pos;
uint32_t written;
OSSpinLock spinlock;
} ax_audio_t;
/* 3072 samples main buffer, 64ms total */
#define AX_AUDIO_COUNT 3072
#define AX_AUDIO_SIZE (AX_AUDIO_COUNT << 1u)
#define AX_AUDIO_SAMPLE_COUNT 144 /* 3ms */
#define AX_AUDIO_SAMPLE_MIN (AX_AUDIO_SAMPLE_COUNT * 3) /* 9ms */
#define AX_AUDIO_SAMPLE_LOAD (AX_AUDIO_SAMPLE_COUNT * 10)/* 30ms */
#define AX_AUDIO_MAX_FREE (AX_AUDIO_COUNT - (AX_AUDIO_SAMPLE_COUNT * 2))
#define AX_AUDIO_RATE 48000
#if 0
#define ax_audio_ticks_to_samples(ticks) (((ticks) * 64) / 82875)
#define ax_audio_samples_to_ticks(samples) (((samples) * 82875) / 64)
#endif
static volatile ax_audio_t *wiiu_cb_ax = NULL;
void wiiu_ax_callback(void)
{
/*possibly called before unregister */
if(wiiu_cb_ax == NULL)
return;
ax_audio_t *ax = (ax_audio_t*)wiiu_cb_ax;
if(AXIsMultiVoiceRunning(ax->mvoice))
{
if(OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
{
/* Buffer underrun, stop playback to let it fill up */
if(ax->written < AX_AUDIO_SAMPLE_MIN)
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
ax->written -= AX_AUDIO_SAMPLE_COUNT;
OSUninterruptibleSpinLock_Release(&ax->spinlock);
}
}
}
extern void AXRegisterFrameCallback(void *cb);
static void* ax_audio_init(const char* device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
AXVoiceOffsets offsets[2];
u16 setup_buf[0x30] = {0};
setup_buf[0x25] = 2; /* we request 2 channels */
AXInitParams init = {AX_INIT_RENDERER_48KHZ, 0, 0};
AXVoiceVeData ve = {0x8000, 0};
ax_audio_t* ax = (ax_audio_t*)calloc(1, sizeof(ax_audio_t));
if (!ax)
return NULL;
AXInitWithParams(&init);
AXAcquireMultiVoice(31, NULL, 0, setup_buf, &ax->mvoice);
if (!ax->mvoice || ax->mvoice->channels != 2)
{
free(ax);
return NULL;
}
ax->buffer_l = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
ax->buffer_r = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
memset(ax->buffer_l,0,AX_AUDIO_SIZE);
memset(ax->buffer_r,0,AX_AUDIO_SIZE);
DCFlushRange(ax->buffer_l,AX_AUDIO_SIZE);
DCFlushRange(ax->buffer_r,AX_AUDIO_SIZE);
/* shared by both voices */
offsets[0].currentOffset = 0;
offsets[0].loopOffset = 0;
offsets[0].endOffset = AX_AUDIO_COUNT - 1;
offsets[0].loopingEnabled = AX_VOICE_LOOP_ENABLED;
offsets[0].dataType = AX_VOICE_FORMAT_LPCM16;
memcpy(&offsets[1], &offsets[0], sizeof(AXVoiceOffsets));
/* different buffers per voice */
offsets[0].data = ax->buffer_l;
offsets[1].data = ax->buffer_r;
AXSetMultiVoiceOffsets(ax->mvoice, offsets);
AXSetMultiVoiceSrcType(ax->mvoice, AX_VOICE_SRC_TYPE_NONE);
AXSetMultiVoiceSrcRatio(ax->mvoice, 1.0f);
AXSetMultiVoiceVe(ax->mvoice, &ve);
AXSetMultiVoiceDeviceMix(ax->mvoice, AX_DEVICE_TYPE_DRC, 0, 0, 0x8000, 0);
AXSetMultiVoiceDeviceMix(ax->mvoice, AX_DEVICE_TYPE_TV, 0, 0, 0x8000, 0);
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
ax->pos = 0;
ax->written = 0;
*new_rate = AX_AUDIO_RATE;
OSInitSpinLock(&ax->spinlock);
wiiu_cb_ax = ax;
AXRegisterFrameCallback(wiiu_ax_callback);
return ax;
}
static void ax_audio_free(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
wiiu_cb_ax = NULL;
AXRegisterFrameCallback(NULL);
AXFreeMultiVoice(ax->mvoice);
AXQuit();
MEM1_free(ax->buffer_l);
MEM1_free(ax->buffer_r);
free(ax);
}
static bool ax_audio_stop(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
return true;
}
static int ax_audio_limit(int in)
{
if(in < 0)
in += AX_AUDIO_COUNT;
else if(in >= AX_AUDIO_COUNT)
in -= AX_AUDIO_COUNT;
return in;
}
static bool ax_audio_start(void* data, bool is_shutdown)
{
ax_audio_t* ax = (ax_audio_t*)data;
/* Prevents restarting audio when the menu
* is toggled off on shutdown */
if (is_shutdown)
return true;
/* Set back to playing on enough buffered data */
if(ax->written > AX_AUDIO_SAMPLE_LOAD)
{
AXSetMultiVoiceCurrentOffset(ax->mvoice, ax_audio_limit(ax->pos - ax->written));
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
}
return true;
}
static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
{
uint32_t i;
size_t countAvail = 0;
ax_audio_t* ax = (ax_audio_t*)data;
const uint16_t* src = buf;
size_t count = size >> 2;
if(!size || (size & 0x3))
return 0;
if(count > AX_AUDIO_MAX_FREE)
count = AX_AUDIO_MAX_FREE;
countAvail = ((ax->written > AX_AUDIO_MAX_FREE) ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
if (ax->nonblocking)
{
/* Not enough available for 3ms of data */
if(countAvail < AX_AUDIO_SAMPLE_COUNT)
count = 0;
}
else if(countAvail < count)
{
/* Sync, wait for free memory */
while(AXIsMultiVoiceRunning(ax->mvoice) && (countAvail < count))
{
OSYieldThread(); /* Gives threads with same priority time to run */
countAvail = (ax->written > AX_AUDIO_MAX_FREE ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
}
}
/* Over available space, do as much as possible */
if(count > countAvail)
count = countAvail;
/* make sure we have input size */
if(count > 0)
{
/* write in new data */
size_t startPos = ax->pos;
int flushP2needed = 0;
int flushP2 = 0;
for (i = 0; i < (count << 1); i += 2)
{
ax->buffer_l[ax->pos] = src[i];
ax->buffer_r[ax->pos] = src[i + 1];
ax->pos = ax_audio_limit(ax->pos + 1);
/* wrapped around, make sure to store cache */
if(ax->pos == 0)
{
flushP2needed = 1;
flushP2 = ((count << 1) - i);
DCStoreRangeNoSync(ax->buffer_l+startPos, (AX_AUDIO_COUNT-startPos) << 1);
DCStoreRangeNoSync(ax->buffer_r+startPos, (AX_AUDIO_COUNT-startPos) << 1);
}
}
/* standard cache store case */
if(!flushP2needed)
{
DCStoreRangeNoSync(ax->buffer_l+startPos, count << 1);
DCStoreRange(ax->buffer_r+startPos, count << 1);
}
/* store the rest after wrap */
else if(flushP2 > 0)
{
DCStoreRangeNoSync(ax->buffer_l, flushP2);
DCStoreRange(ax->buffer_r, flushP2);
}
/* add in new audio data */
if(OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
{
ax->written += count;
OSUninterruptibleSpinLock_Release(&ax->spinlock);
}
}
/* Possibly buffer underrun
*
* checks if it can be started
*/
if(!AXIsMultiVoiceRunning(ax->mvoice))
ax_audio_start(ax, false);
/* return what was actually copied */
return (count << 2);
}
static bool ax_audio_alive(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
return AXIsMultiVoiceRunning(ax->mvoice);
}
static void ax_audio_set_nonblock_state(void* data, bool state)
{
ax_audio_t* ax = (ax_audio_t*)data;
if (ax)
ax->nonblocking = state;
}
static bool ax_audio_use_float(void* data)
{
(void)data;
return false;
}
static size_t ax_audio_write_avail(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
size_t ret = AX_AUDIO_COUNT - ax->written;
return (ret < AX_AUDIO_SAMPLE_COUNT ? 0 : ret);
}
static size_t ax_audio_buffer_size(void* data)
{
(void)data;
return AX_AUDIO_COUNT;
}
audio_driver_t audio_ax =
{
ax_audio_init,
ax_audio_write,
ax_audio_stop,
ax_audio_start,
ax_audio_alive,
ax_audio_set_nonblock_state,
ax_audio_free,
ax_audio_use_float,
"AX",
NULL, /* device_list_new */
NULL, /* device_list_free */
NULL, /* write_avail */
NULL, /* buffer_size */
};

View File

@ -1,431 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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/>.
*/
#if !defined(_XBOX) && (_MSC_VER == 1310)
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif
#endif
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <boolean.h>
#include <compat/msvc.h>
#include <retro_miscellaneous.h>
#if defined(_MSC_VER) && (_WIN32_WINNT <= _WIN32_WINNT_WIN2K)
/* needed for CoInitializeEx */
#define _WIN32_DCOM
#endif
#include "xaudio.h"
#include "../../retroarch.h"
#include "../../verbosity.h"
typedef struct xaudio2 xaudio2_t;
#define MAX_BUFFERS 16
#define MAX_BUFFERS_MASK (MAX_BUFFERS - 1)
#ifndef COINIT_MULTITHREADED
#define COINIT_MULTITHREADED 0x00
#endif
#define XAUDIO2_WRITE_AVAILABLE(handle) ((handle)->bufsize * (MAX_BUFFERS - (handle)->buffers - 1))
typedef struct
{
xaudio2_t *xa;
bool nonblock;
bool is_paused;
size_t bufsize;
} xa_t;
#if defined(__cplusplus) && !defined(CINTERFACE)
struct xaudio2 : public IXAudio2VoiceCallback
#else
struct xaudio2
#endif
{
#if defined(__cplusplus) && !defined(CINTERFACE)
xaudio2() :
buf(0), pXAudio2(0), pMasterVoice(0),
pSourceVoice(0), hEvent(0), buffers(0), bufsize(0),
bufptr(0), write_buffer(0)
{}
virtual ~xaudio2() {}
STDMETHOD_(void, OnBufferStart) (void *) {}
STDMETHOD_(void, OnBufferEnd) (void *)
{
InterlockedDecrement((LONG volatile*)&buffers);
SetEvent(hEvent);
}
STDMETHOD_(void, OnLoopEnd) (void *) {}
STDMETHOD_(void, OnStreamEnd) () {}
STDMETHOD_(void, OnVoiceError) (void *, HRESULT) {}
STDMETHOD_(void, OnVoiceProcessingPassEnd) () {}
STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {}
#else
const IXAudio2VoiceCallbackVtbl *lpVtbl;
#endif
uint8_t *buf;
IXAudio2 *pXAudio2;
IXAudio2MasteringVoice *pMasterVoice;
IXAudio2SourceVoice *pSourceVoice;
HANDLE hEvent;
unsigned long volatile buffers;
unsigned bufsize;
unsigned bufptr;
unsigned write_buffer;
};
#if !defined(__cplusplus) || defined(CINTERFACE)
static void WINAPI voice_on_buffer_end(IXAudio2VoiceCallback *handle_, void *data)
{
xaudio2_t *handle = (xaudio2_t*)handle_;
(void)data;
InterlockedDecrement((LONG volatile*)&handle->buffers);
SetEvent(handle->hEvent);
}
static void WINAPI dummy_voidp(IXAudio2VoiceCallback *handle, void *data) { (void)handle; (void)data; }
static void WINAPI dummy_nil(IXAudio2VoiceCallback *handle) { (void)handle; }
static void WINAPI dummy_uint32(IXAudio2VoiceCallback *handle, UINT32 dummy) { (void)handle; (void)dummy; }
static void WINAPI dummy_voidp_hresult(IXAudio2VoiceCallback *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; }
const struct IXAudio2VoiceCallbackVtbl voice_vtable = {
dummy_uint32,
dummy_nil,
dummy_nil,
dummy_voidp,
voice_on_buffer_end,
dummy_voidp,
dummy_voidp_hresult,
};
#endif
#if 0
static void xaudio2_enumerate_devices(xaudio2_t *xa)
{
uint32_t dev_count = 0;
unsigned i = 0;
(void)xa;
(void)i;
(void)dev_count;
#ifndef _XBOX
IXAudio2_GetDeviceCount(xa->pXAudio2, &dev_count);
fprintf(stderr, "XAudio2 devices:\n");
for (i = 0; i < dev_count; i++)
{
XAUDIO2_DEVICE_DETAILS dev_detail;
IXAudio2_GetDeviceDetails(xa->pXAudio2, i, &dev_detail);
fwprintf(stderr, L"\t%u: %s\n", i, dev_detail.DisplayName);
}
#endif
}
#endif
static void xaudio2_set_wavefmt(WAVEFORMATEX *wfx,
unsigned channels, unsigned samplerate)
{
wfx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
wfx->nBlockAlign = channels * sizeof(float);
wfx->wBitsPerSample = sizeof(float) * 8;
wfx->nChannels = channels;
wfx->nSamplesPerSec = samplerate;
wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
wfx->cbSize = 0;
}
static void xaudio2_free(xaudio2_t *handle)
{
if (!handle)
return;
if (handle->pSourceVoice)
{
IXAudio2SourceVoice_Stop(handle->pSourceVoice,
0, XAUDIO2_COMMIT_NOW);
IXAudio2SourceVoice_DestroyVoice(handle->pSourceVoice);
}
if (handle->pMasterVoice)
{
IXAudio2MasteringVoice_DestroyVoice(handle->pMasterVoice);
}
if (handle->pXAudio2)
{
IXAudio2_Release(handle->pXAudio2);
}
if (handle->hEvent)
CloseHandle(handle->hEvent);
free(handle->buf);
#if defined(__cplusplus) && !defined(CINTERFACE)
delete handle;
#else
free(handle);
#endif
}
static xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels,
size_t size, unsigned device)
{
xaudio2_t *handle = NULL;
WAVEFORMATEX wfx = {0};
#if defined(__cplusplus) && !defined(CINTERFACE)
handle = new xaudio2;
#else
handle = (xaudio2_t*)calloc(1, sizeof(*handle));
#endif
if (!handle)
goto error;
#if !defined(__cplusplus) || defined(CINTERFACE)
handle->lpVtbl = &voice_vtable;
#endif
if (FAILED(XAudio2Create(&handle->pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)))
goto error;
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, (LPCWSTR)(uintptr_t)device, NULL, AudioCategory_GameEffects)))
goto error;
#else
if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, device, NULL)))
goto error;
#endif
xaudio2_set_wavefmt(&wfx, channels, samplerate);
if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2,
&handle->pSourceVoice, &wfx,
XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO,
(IXAudio2VoiceCallback*)handle, 0, 0)))
goto error;
handle->hEvent = CreateEvent(0, FALSE, FALSE, 0);
if (!handle->hEvent)
goto error;
handle->bufsize = size / MAX_BUFFERS;
handle->buf = (uint8_t*)calloc(1, handle->bufsize * MAX_BUFFERS);
if (!handle->buf)
goto error;
if (FAILED(IXAudio2SourceVoice_Start(handle->pSourceVoice, 0,
XAUDIO2_COMMIT_NOW)))
goto error;
return handle;
error:
xaudio2_free(handle);
return NULL;
}
static size_t xaudio2_write(xaudio2_t *handle, const uint8_t *buffer, size_t bytes_)
{
unsigned bytes = bytes_;
while (bytes)
{
unsigned need = MIN(bytes, handle->bufsize - handle->bufptr);
memcpy(handle->buf + handle->write_buffer *
handle->bufsize + handle->bufptr,
buffer, need);
handle->bufptr += need;
buffer += need;
bytes -= need;
if (handle->bufptr == handle->bufsize)
{
XAUDIO2_BUFFER xa2buffer;
while (handle->buffers == MAX_BUFFERS - 1)
WaitForSingleObject(handle->hEvent, INFINITE);
xa2buffer.Flags = 0;
xa2buffer.AudioBytes = handle->bufsize;
xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize;
xa2buffer.PlayBegin = 0;
xa2buffer.PlayLength = 0;
xa2buffer.LoopBegin = 0;
xa2buffer.LoopLength = 0;
xa2buffer.LoopCount = 0;
xa2buffer.pContext = NULL;
if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(
handle->pSourceVoice, &xa2buffer, NULL)))
return 0;
InterlockedIncrement((LONG volatile*)&handle->buffers);
handle->bufptr = 0;
handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK;
}
}
return bytes_;
}
static void *xa_init(const char *device, unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
size_t bufsize;
unsigned device_index = 0;
xa_t *xa = (xa_t*)calloc(1, sizeof(*xa));
if (!xa)
return NULL;
if (latency < 8)
latency = 8; /* Do not allow shenanigans. */
bufsize = latency * rate / 1000;
RARCH_LOG("[XAudio2]: Requesting %u ms latency, using %d ms latency.\n",
latency, (int)bufsize * 1000 / rate);
xa->bufsize = bufsize * 2 * sizeof(float);
if (device)
device_index = strtoul(device, NULL, 0);
xa->xa = xaudio2_new(rate, 2, xa->bufsize, device_index);
if (!xa->xa)
{
RARCH_ERR("Failed to init XAudio2.\n");
free(xa);
return NULL;
}
return xa;
}
static ssize_t xa_write(void *data, const void *buf, size_t size)
{
size_t ret;
xa_t *xa = (xa_t*)data;
if (xa->nonblock)
{
size_t avail = XAUDIO2_WRITE_AVAILABLE(xa->xa);
if (avail == 0)
return 0;
if (avail < size)
size = avail;
}
ret = xaudio2_write(xa->xa, (const uint8_t*)buf, size);
if (ret == 0 && size > 0)
return -1;
return ret;
}
static bool xa_stop(void *data)
{
xa_t *xa = (xa_t*)data;
xa->is_paused = true;
return true;
}
static bool xa_alive(void *data)
{
xa_t *xa = (xa_t*)data;
if (!xa)
return false;
return !xa->is_paused;
}
static void xa_set_nonblock_state(void *data, bool state)
{
xa_t *xa = (xa_t*)data;
if (xa)
xa->nonblock = state;
}
static bool xa_start(void *data, bool is_shutdown)
{
xa_t *xa = (xa_t*)data;
xa->is_paused = false;
return true;
}
static bool xa_use_float(void *data)
{
(void)data;
return true;
}
static void xa_free(void *data)
{
xa_t *xa = (xa_t*)data;
if (!xa)
return;
if (xa->xa)
xaudio2_free(xa->xa);
free(xa);
}
static size_t xa_write_avail(void *data)
{
xa_t *xa = (xa_t*)data;
return XAUDIO2_WRITE_AVAILABLE(xa->xa);
}
static size_t xa_buffer_size(void *data)
{
xa_t *xa = (xa_t*)data;
return xa->bufsize;
}
audio_driver_t audio_xa = {
xa_init,
xa_write,
xa_stop,
xa_start,
xa_alive,
xa_set_nonblock_state,
xa_free,
xa_use_float,
"xaudio",
NULL,
NULL,
xa_write_avail,
xa_buffer_size,
};

View File

@ -1,26 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2018 - Krzysztof Haładyn
*
* 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/>.
*/
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
/* XAudio 2.7 it part of the old DirectX SDKs. XAudio 2.8+ is part of the
* Windows OS itself (starting from Windows 8). Since UWP lets you access
* only libraries that are built-in to the OS, the headers had to be
* upgraded to the newer version to get audio support working. */
#include "xaudio29.h"
#else
/* The old version still has to be there since XAudio 2.8 is not available
* on Windows 7 and earlier */
#include "xaudio27.h"
#endif

View File

@ -1,362 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2010-2014 - OV2
*
* 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/>.
*/
/* Kinda stripped down. Only contains the bare essentials used in RetroArch. */
#ifndef XAUDIO2_STRIPPED_H
#define XAUDIO2_STRIPPED_H
#include <retro_inline.h>
#include <retro_environment.h>
/* All structures defined in this file use tight field packing */
#pragma pack(push, 1)
#if defined(__cplusplus) && !defined(CINTERFACE)
#define X2DEFAULT(x) = (x)
#else
#define X2DEFAULT(x)
#endif
#ifdef _XBOX
#include <xtl.h>
#ifndef __cplusplus
#define OPAQUE interface
#endif
#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
DEFINE_CLSID(XAudio2, 3eda9b49, 2085, 498b, 9b, b2, 39, a6, 77, 84, 93, de);
DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e);
DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
#include <audiodefs.h> /* Basic audio data types and constants */
#else
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <basetyps.h>
#include <objbase.h>
#include <mmreg.h>
#ifndef __cplusplus
#undef OPAQUE
#define OPAQUE struct
#endif
#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#ifndef __cplusplus
#ifndef INTERFACE
#define INTERFACE void
#endif
#endif
DEFINE_CLSID_X(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af); /* 2.7 */
DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
#endif
#ifdef _XBOX
#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f
#else
#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f
#endif
#define XAUDIO2_COMMIT_NOW 0
#define XAUDIO2_DEFAULT_CHANNELS 0
#define XAUDIO2_DEFAULT_SAMPLERATE 0
#define XAUDIO2_DEBUG_ENGINE 0x0001
#define XAUDIO2_VOICE_NOSRC 0x0004
typedef enum XAUDIO2_DEVICE_ROLE
{
NotDefaultDevice = 0x0,
DefaultConsoleDevice = 0x1,
DefaultMultimediaDevice = 0x2,
DefaultCommunicationsDevice = 0x4,
DefaultGameDevice = 0x8,
GlobalDefaultDevice = 0xf,
InvalidDeviceRole = ~GlobalDefaultDevice
} XAUDIO2_DEVICE_ROLE;
#ifdef _XBOX
typedef enum XAUDIO2_XBOX_HWTHREAD_SPECIFIER
{
XboxThread0 = 0x01,
XboxThread1 = 0x02,
XboxThread2 = 0x04,
XboxThread3 = 0x08,
XboxThread4 = 0x10,
XboxThread5 = 0x20,
XAUDIO2_ANY_PROCESSOR = XboxThread4,
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
} XAUDIO2_XBOX_HWTHREAD_SPECIFIER, XAUDIO2_PROCESSOR;
#else
typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER
{
#if defined(__STDC_C89__)
XAUDIO2_ANY_PROCESSOR = 0xffff,
#else
XAUDIO2_ANY_PROCESSOR = 0xffffffff,
#endif
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR;
#endif
typedef enum XAUDIO2_FILTER_TYPE {
LowPassFilter,
BandPassFilter,
HighPassFilter
} XAUDIO2_FILTER_TYPE;
typedef struct XAUDIO2_DEVICE_DETAILS
{
WCHAR DeviceID[256];
WCHAR DisplayName[256];
XAUDIO2_DEVICE_ROLE Role;
WAVEFORMATEXTENSIBLE OutputFormat;
} XAUDIO2_DEVICE_DETAILS;
/* Forward declarations. */
#ifdef __cplusplus
struct XAUDIO2_VOICE_DETAILS;
struct XAUDIO2_VOICE_SENDS;
struct XAUDIO2_EFFECT_DESCRIPTOR;
struct XAUDIO2_EFFECT_CHAIN;
struct XAUDIO2_FILTER_PARAMETERS;
struct XAUDIO2_BUFFER_WMA;
struct XAUDIO2_VOICE_STATE;
struct XAUDIO2_PERFORMANCE_DATA;
struct XAUDIO2_DEBUG_CONFIGURATION;
struct IXAudio2EngineCallback;
struct IXAudio2SubmixVoice;
#else
typedef OPAQUE XAUDIO2_VOICE_DETAILS XAUDIO2_VOICE_DETAILS;
typedef OPAQUE XAUDIO2_VOICE_SENDS XAUDIO2_VOICE_SENDS;
typedef OPAQUE XAUDIO2_EFFECT_DESCRIPTOR XAUDIO2_EFFECT_DESCRIPTOR;
typedef OPAQUE XAUDIO2_EFFECT_CHAIN XAUDIO2_EFFECT_CHAIN;
typedef OPAQUE XAUDIO2_FILTER_PARAMETERS XAUDIO2_FILTER_PARAMETERS;
typedef OPAQUE XAUDIO2_BUFFER_WMA XAUDIO2_BUFFER_WMA;
typedef OPAQUE XAUDIO2_VOICE_STATE XAUDIO2_VOICE_STATE;
typedef OPAQUE XAUDIO2_PERFORMANCE_DATA XAUDIO2_PERFORMANCE_DATA;
typedef OPAQUE XAUDIO2_DEBUG_CONFIGURATION XAUDIO2_DEBUG_CONFIGURATION;
typedef OPAQUE IXAudio2EngineCallback IXAudio2EngineCallback;
typedef OPAQUE IXAudio2SubmixVoice IXAudio2SubmixVoice;
#endif
typedef struct XAUDIO2_BUFFER
{
UINT32 Flags;
UINT32 AudioBytes;
const BYTE* pAudioData;
UINT32 PlayBegin;
UINT32 PlayLength;
UINT32 LoopBegin;
UINT32 LoopLength;
UINT32 LoopCount;
void *pContext;
} XAUDIO2_BUFFER;
#undef INTERFACE
#define INTERFACE IXAudio2VoiceCallback
DECLARE_INTERFACE(IXAudio2VoiceCallback)
{
STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
STDMETHOD_(void, OnBufferStart) (THIS_ void *pBufferContext) PURE;
STDMETHOD_(void, OnBufferEnd) (THIS_ void *pBufferContext) PURE;
STDMETHOD_(void, OnLoopEnd) (THIS_ void *pBufferContext) PURE;
STDMETHOD_(void, OnVoiceError) (THIS_ void *pBufferContext, HRESULT Error) PURE;
};
#undef INTERFACE
#define INTERFACE IXAudio2Voice
DECLARE_INTERFACE(IXAudio2Voice)
{
#define Declare_IXAudio2Voice_Methods() \
STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \
STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
const void *pParameters, \
UINT32 ParametersByteSize, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void *pParameters, \
UINT32 ParametersByteSize) PURE; \
STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
STDMETHOD_(void, SetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, const XAUDIO2_FILTER_PARAMETERS* param, \
UINT32 op X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, XAUDIO2_FILTER_PARAMETERS* param) PURE; \
STDMETHOD(SetVolume) (THIS_ float Volume, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \
STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \
STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
UINT32 SourceChannels, UINT32 DestinationChannels, \
const float* pLevelMatrix, \
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
UINT32 SourceChannels, UINT32 DestinationChannels, \
float* pLevelMatrix) PURE; \
STDMETHOD_(void, DestroyVoice) (THIS) PURE
Declare_IXAudio2Voice_Methods();
};
#undef INTERFACE
#define INTERFACE IXAudio2MasteringVoice
DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice)
{
Declare_IXAudio2Voice_Methods();
};
#undef INTERFACE
#define INTERFACE IXAudio2SourceVoice
DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice)
{
Declare_IXAudio2Voice_Methods();
STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
STDMETHOD(FlushSourceBuffers) (THIS) PURE;
STDMETHOD(Discontinuity) (THIS) PURE;
STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE;
STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE;
};
#undef INTERFACE
#define INTERFACE IXAudio2
DECLARE_INTERFACE_(IXAudio2, IUnknown)
{
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE;
STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice,
const WAVEFORMATEX* pSourceFormat,
UINT32 Flags X2DEFAULT(0),
float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice,
UINT32 InputChannels, UINT32 InputSampleRate,
UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice,
UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
STDMETHOD(StartEngine) (THIS) PURE;
STDMETHOD_(void, StopEngine) (THIS) PURE;
STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE;
STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
void *pReserved X2DEFAULT(NULL)) PURE;
};
#if defined(__cplusplus) && !defined(CINTERFACE)
/* C++ hooks */
#define IXAudio2_Initialize(handle,a,b) handle->Initialize(a, b)
#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, a, b) handle->SubmitSourceBuffer(a, b)
#define IXAudio2SourceVoice_Stop(handle, a, b) handle->Stop(a, b)
#define IXAudio2SourceVoice_DestroyVoice(handle) handle->DestroyVoice()
#define IXAudio2MasteringVoice_DestroyVoice(handle) handle->DestroyVoice()
#define IXAudio2_Release(handle) handle->Release()
#define IXAudio2_CreateSourceVoice(handle, a, b, c, d, e, f, g) handle->CreateSourceVoice(a, b, c, d, e, f, g)
#define IXAudio2_CreateMasteringVoice(handle, a, b, c, d, e, f) handle->CreateMasteringVoice(a, b, c, d, e, f)
#define IXAudio2SourceVoice_Start(handle, a, b) handle->Start(a, b)
#else
/* C hooks */
#define IXAudio2_Initialize(handle,a,b) (handle)->lpVtbl->Initialize(handle, a, b)
#define IXAudio2_Release(handle) (handle)->lpVtbl->Release(handle)
#define IXAudio2_CreateSourceVoice(handle,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) (handle)->lpVtbl->CreateSourceVoice(handle, ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain)
#define IXAudio2_CreateMasteringVoice(handle,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) (handle)->lpVtbl->CreateMasteringVoice(handle, ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain)
#define IXAudio2_GetDeviceCount(handle, puCount) (handle)->lpVtbl->GetDeviceCount(handle, puCount)
#define IXAudio2_GetDeviceDetails(handle, Index,pDeviceDetails) (handle)->lpVtbl->GetDeviceDetails(handle, Index, pDeviceDetails)
#define IXAudio2SourceVoice_Start(handle, Flags, OperationSet) (handle)->lpVtbl->Start(handle, Flags, OperationSet)
#define IXAudio2SourceVoice_Stop(handle, Flags, OperationSet) (handle)->lpVtbl->Stop(handle, Flags, OperationSet)
#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, pBuffer, pBufferWMA) (handle)->lpVtbl->SubmitSourceBuffer(handle, pBuffer, pBufferWMA)
#define IXAudio2SourceVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle)
#define IXAudio2MasteringVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle)
#endif
#ifdef _XBOX
STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0),
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR));
#else
static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_PROCESSOR proc)
{
IXAudio2 *pXAudio2 = NULL;
#ifdef __cplusplus
HRESULT hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2);
#else
HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2);
#endif
if (SUCCEEDED(hr))
{
hr = IXAudio2_Initialize(pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (SUCCEEDED(hr))
*ppXAudio2 = pXAudio2;
else
IXAudio2_Release(pXAudio2);
}
return hr;
}
#endif
/* Undo the #pragma pack(push, 1) directive at the top of this file */
#pragma pack(pop)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <boolean.h>
#include <xenon_sound/sound.h>
#include <retro_inline.h>
#include "../../retroarch.h"
#define SOUND_FREQUENCY 48000
#define MAX_BUFFER 2048
typedef struct
{
uint32_t buffer[2048];
bool nonblock;
bool is_paused;
} xenon_audio_t;
static void *xenon360_audio_init(const char *device,
unsigned rate, unsigned latency,
unsigned block_frames,
unsigned *new_rate)
{
static bool inited = false;
if (!inited)
{
xenon_sound_init();
inited = true;
}
*new_rate = SOUND_FREQUENCY;
return calloc(1, sizeof(xenon_audio_t));
}
static INLINE uint32_t bswap_32(uint32_t val)
{
return (val >> 24) | (val << 24) |
((val >> 8) & 0xff00) | ((val << 8) & 0xff0000);
}
static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
{
size_t written = 0, i;
const uint32_t *in_buf = buf;
xenon_audio_t *xa = data;
for (i = 0; i < (size >> 2); i++)
xa->buffer[i] = bswap_32(in_buf[i]);
if (!xa->nonblock)
{
while (xenon_sound_get_unplayed() >= MAX_BUFFER)
{
/* libxenon doesn't have proper
* synchronization primitives for this... */
udelay(50);
}
xenon_sound_submit(xa->buffer, size);
written = size;
}
else
{
if (xenon_sound_get_unplayed() < MAX_BUFFER)
{
xenon_sound_submit(xa->buffer, size);
written = size;
}
}
return written;
}
static bool xenon360_audio_stop(void *data)
{
xenon_audio_t *xa = data;
xa->is_paused = true;
return true;
}
static bool xenon360_audio_alive(void *data)
{
xenon_audio_t *xa = data;
if (!xa)
return false;
return !xa->is_paused;
}
static void xenon360_audio_set_nonblock_state(void *data, bool state)
{
xenon_audio_t *xa = data;
if (xa)
xa->nonblock = state;
}
static bool xenon360_audio_start(void *data, bool is_shutdown)
{
xenon_audio_t *xa = data;
xa->is_paused = false;
return true;
}
static void xenon360_audio_free(void *data)
{
if (data)
free(data);
}
static bool xenon360_use_float(void *data)
{
(void)data;
return false;
}
static size_t xenon360_write_avail(void *data)
{
(void)data;
return 0;
}
audio_driver_t audio_xenon360 = {
xenon360_audio_init,
xenon360_audio_write,
xenon360_audio_stop,
xenon360_audio_start,
xenon360_audio_alive,
xenon360_audio_set_nonblock_state,
xenon360_audio_free,
xenon360_use_float,
"xenon360",
NULL,
NULL,
xenon360_write_avail,
NULL
};

View File

@ -1,548 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Ali Bouhlel ( aliaspider@gmail.com )
*
* 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/>.
*/
/* Convoluted Cosine Resampler */
#include <stdint.h>
#include <stdlib.h>
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#include <retro_inline.h>
#include <retro_miscellaneous.h>
#include <memalign.h>
#include <math/float_minmax.h>
#include <audio/audio_resampler.h>
/* Since SSE and NEON don't provide support for trigonometric functions
* we approximate those with polynoms
*
* CC_RESAMPLER_PRECISION defines how accurate the approximation is
* a setting of 5 or more means full precison.
* setting 0 doesn't use a polynom
* setting 1 uses P(X) = X - (3/4)*X^3 + (1/4)*X^5
*
* only 0 and 1 are implemented for SSE and NEON currently
*
* the MIPS_ARCH_ALLEGREX target doesnt require this setting since it has
* native support for the required functions so it will always use full precision.
*/
#ifndef CC_RESAMPLER_PRECISION
#define CC_RESAMPLER_PRECISION 1
#endif
typedef struct rarch_CC_resampler
{
audio_frame_float_t buffer[4];
float distance;
void (*process)(void *re, struct resampler_data *data);
} rarch_CC_resampler_t;
#ifdef _MIPS_ARCH_ALLEGREX
static void resampler_CC_process(void *re_, struct resampler_data *data)
{
float ratio, fraction;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
(void)re_;
__asm__ (
".set push\n"
".set noreorder\n"
"mtv %2, s700 \n" /* 700 = data->ratio = b */
/* "vsat0.s s700, s700 \n" */
"vrcp.s s701, s700 \n" /* 701 = 1.0 / b */
"vadd.s s702, s700, s700 \n" /* 702 = 2 * b */
"vmul.s s703, s700, s710 \n" /* 703 = b * pi */
"mfv %0, s701 \n"
"mfv %1, s730 \n"
".set pop\n"
: "=r"(ratio), "=r"(fraction)
: "r"((float)data->ratio)
);
for (;;)
{
while (fraction < ratio)
{
if (inp == inp_max)
goto done;
__asm__ (
".set push \n"
".set noreorder \n"
"lv.s s620, 0(%1) \n"
"lv.s s621, 4(%1) \n"
"vsub.s s731, s701, s730 \n"
"vadd.q c600, c730[-X,Y,-X,Y], c730[1/2,1/2,-1/2,-1/2]\n"
"vmul.q c610, c600, c700[Z,Z,Z,Z] \n" /* *2*b */
"vmul.q c600, c600, c700[W,W,W,W] \n" /* *b*pi */
"vsin.q c610, c610 \n"
"vadd.q c600, c600, c610 \n"
"vmul.q c600[-1:1,-1:1,-1:1,-1:1], c600, c710[Y,Y,Y,Y] \n"
"vsub.p c600, c600, c602 \n"
"vmul.q c620, c620[X,Y,X,Y], c600[X,X,Y,Y] \n"
"vadd.q c720, c720, c620 \n"
"vadd.s s730, s730, s730[1] \n"
"mfv %0, s730 \n"
".set pop \n"
: "=r"(fraction)
: "r"(inp));
inp++;
}
__asm__ (
".set push \n"
".set noreorder \n"
"vmul.p c720, c720, c720[1/2,1/2] \n"
"sv.s s720, 0(%1) \n"
"sv.s s721, 4(%1) \n"
"vmov.q c720, c720[Z,W,0,0] \n"
"vsub.s s730, s730, s701 \n"
"mfv %0, s730 \n"
".set pop \n"
: "=r"(fraction)
: "r"(outp));
outp++;
}
/* The VFPU state is assumed to remain intact
* in-between calls to resampler_CC_process. */
done:
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
}
static void *resampler_CC_init(const struct resampler_config *config,
double bandwidth_mod,
enum resampler_quality quality,
resampler_simd_mask_t mask)
{
(void)mask;
(void)bandwidth_mod;
(void)config;
__asm__ (
".set push\n"
".set noreorder\n"
"vcst.s s710, VFPU_PI \n" /* 710 = pi */
"vcst.s s711, VFPU_1_PI \n" /* 711 = 1.0 / (pi) */
"vzero.q c720 \n"
"vzero.q c730 \n"
".set pop\n");
return (void*)-1;
}
#else
#if defined(__SSE__)
#define CC_RESAMPLER_IDENT "SSE"
static void resampler_CC_downsample(void *re_, struct resampler_data *data)
{
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
float ratio = 1.0 / data->ratio;
float b = data->ratio; /* cutoff frequency. */
__m128 vec_previous = _mm_loadu_ps((float*)&re->buffer[0]);
__m128 vec_current = _mm_loadu_ps((float*)&re->buffer[2]);
while (inp != inp_max)
{
__m128 vec_ww1, vec_ww2;
__m128 vec_w_previous;
__m128 vec_w_current;
__m128 vec_in;
__m128 vec_ratio =
_mm_mul_ps(_mm_set_ps1(ratio), _mm_set_ps(3.0, 2.0, 1.0, 0.0));
__m128 vec_w = _mm_sub_ps(_mm_set_ps1(re->distance), vec_ratio);
__m128 vec_w1 = _mm_add_ps(vec_w , _mm_set_ps1(0.5));
__m128 vec_w2 = _mm_sub_ps(vec_w , _mm_set_ps1(0.5));
__m128 vec_b = _mm_set_ps1(b);
vec_w1 = _mm_mul_ps(vec_w1, vec_b);
vec_w2 = _mm_mul_ps(vec_w2, vec_b);
(void)vec_ww1;
(void)vec_ww2;
#if (CC_RESAMPLER_PRECISION > 0)
vec_ww1 = _mm_mul_ps(vec_w1, vec_w1);
vec_ww2 = _mm_mul_ps(vec_w2, vec_w2);
vec_ww1 = _mm_mul_ps(vec_ww1, _mm_sub_ps(_mm_set_ps1(3.0),vec_ww1));
vec_ww2 = _mm_mul_ps(vec_ww2, _mm_sub_ps(_mm_set_ps1(3.0),vec_ww2));
vec_ww1 = _mm_mul_ps(_mm_set_ps1(1.0/4.0), vec_ww1);
vec_ww2 = _mm_mul_ps(_mm_set_ps1(1.0/4.0), vec_ww2);
vec_w1 = _mm_mul_ps(vec_w1, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww1));
vec_w2 = _mm_mul_ps(vec_w2, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww2));
#endif
vec_w1 = _mm_min_ps(vec_w1, _mm_set_ps1( 0.5));
vec_w2 = _mm_min_ps(vec_w2, _mm_set_ps1( 0.5));
vec_w1 = _mm_max_ps(vec_w1, _mm_set_ps1(-0.5));
vec_w2 = _mm_max_ps(vec_w2, _mm_set_ps1(-0.5));
vec_w = _mm_sub_ps(vec_w1, vec_w2);
vec_w_previous =
_mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(1, 1, 0, 0));
vec_w_current =
_mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(3, 3, 2, 2));
vec_in = _mm_loadl_pi(_mm_setzero_ps(),(__m64*)inp);
vec_in = _mm_shuffle_ps(vec_in,vec_in,_MM_SHUFFLE(1, 0, 1, 0));
vec_previous =
_mm_add_ps(vec_previous, _mm_mul_ps(vec_in, vec_w_previous));
vec_current =
_mm_add_ps(vec_current, _mm_mul_ps(vec_in, vec_w_current));
re->distance++;
inp++;
if (re->distance > (ratio + 0.5))
{
_mm_storel_pi((__m64*)outp, vec_previous);
vec_previous =
_mm_shuffle_ps(vec_previous,vec_current,_MM_SHUFFLE(1, 0, 3, 2));
vec_current =
_mm_shuffle_ps(vec_current,_mm_setzero_ps(),_MM_SHUFFLE(1, 0, 3, 2));
re->distance -= ratio;
outp++;
}
}
_mm_storeu_ps((float*)&re->buffer[0], vec_previous);
_mm_storeu_ps((float*)&re->buffer[2], vec_current);
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
}
static void resampler_CC_upsample(void *re_, struct resampler_data *data)
{
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
float b = float_min(data->ratio, 1.00); /* cutoff frequency. */
float ratio = 1.0 / data->ratio;
__m128 vec_previous = _mm_loadu_ps((float*)&re->buffer[0]);
__m128 vec_current = _mm_loadu_ps((float*)&re->buffer[2]);
while (inp != inp_max)
{
__m128 vec_in = _mm_loadl_pi(_mm_setzero_ps(),(__m64*)inp);
vec_previous =
_mm_shuffle_ps(vec_previous,vec_current,_MM_SHUFFLE(1, 0, 3, 2));
vec_current =
_mm_shuffle_ps(vec_current,vec_in,_MM_SHUFFLE(1, 0, 3, 2));
while (re->distance < 1.0)
{
__m128 vec_w_previous, vec_w_current, vec_out;
#if (CC_RESAMPLER_PRECISION > 0)
__m128 vec_ww1, vec_ww2;
#endif
__m128 vec_w =
_mm_add_ps(_mm_set_ps1(re->distance), _mm_set_ps(-2.0, -1.0, 0.0, 1.0));
__m128 vec_w1 = _mm_add_ps(vec_w , _mm_set_ps1(0.5));
__m128 vec_w2 = _mm_sub_ps(vec_w , _mm_set_ps1(0.5));
__m128 vec_b = _mm_set_ps1(b);
vec_w1 = _mm_mul_ps(vec_w1, vec_b);
vec_w2 = _mm_mul_ps(vec_w2, vec_b);
#if (CC_RESAMPLER_PRECISION > 0)
vec_ww1 = _mm_mul_ps(vec_w1, vec_w1);
vec_ww2 = _mm_mul_ps(vec_w2, vec_w2);
vec_ww1 = _mm_mul_ps(vec_ww1,_mm_sub_ps(_mm_set_ps1(3.0),vec_ww1));
vec_ww2 = _mm_mul_ps(vec_ww2,_mm_sub_ps(_mm_set_ps1(3.0),vec_ww2));
vec_ww1 = _mm_mul_ps(_mm_set_ps1(1.0 / 4.0), vec_ww1);
vec_ww2 = _mm_mul_ps(_mm_set_ps1(1.0 / 4.0), vec_ww2);
vec_w1 = _mm_mul_ps(vec_w1, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww1));
vec_w2 = _mm_mul_ps(vec_w2, _mm_sub_ps(_mm_set_ps1(1.0), vec_ww2));
#endif
vec_w1 = _mm_min_ps(vec_w1, _mm_set_ps1( 0.5));
vec_w2 = _mm_min_ps(vec_w2, _mm_set_ps1( 0.5));
vec_w1 = _mm_max_ps(vec_w1, _mm_set_ps1(-0.5));
vec_w2 = _mm_max_ps(vec_w2, _mm_set_ps1(-0.5));
vec_w = _mm_sub_ps(vec_w1, vec_w2);
vec_w_previous = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(1, 1, 0, 0));
vec_w_current = _mm_shuffle_ps(vec_w,vec_w,_MM_SHUFFLE(3, 3, 2, 2));
vec_out = _mm_mul_ps(vec_previous, vec_w_previous);
vec_out = _mm_add_ps(vec_out, _mm_mul_ps(vec_current, vec_w_current));
vec_out =
_mm_add_ps(vec_out, _mm_shuffle_ps(vec_out,vec_out,_MM_SHUFFLE(3, 2, 3, 2)));
_mm_storel_pi((__m64*)outp,vec_out);
re->distance += ratio;
outp++;
}
re->distance -= 1.0;
inp++;
}
_mm_storeu_ps((float*)&re->buffer[0], vec_previous);
_mm_storeu_ps((float*)&re->buffer[2], vec_current);
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
}
#elif defined (__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#define CC_RESAMPLER_IDENT "NEON"
size_t resampler_CC_downsample_neon(float *outp, const float *inp,
rarch_CC_resampler_t* re_, size_t input_frames, float ratio);
size_t resampler_CC_upsample_neon (float *outp, const float *inp,
rarch_CC_resampler_t* re_, size_t input_frames, float ratio);
static void resampler_CC_downsample(void *re_, struct resampler_data *data)
{
data->output_frames = resampler_CC_downsample_neon(
data->data_out, data->data_in, re_, data->input_frames, data->ratio);
}
static void resampler_CC_upsample(void *re_, struct resampler_data *data)
{
data->output_frames = resampler_CC_upsample_neon(
data->data_out, data->data_in, re_, data->input_frames, data->ratio);
}
#else
/* C reference version. Not optimized. */
#define CC_RESAMPLER_IDENT "C"
#if (CC_RESAMPLER_PRECISION > 4)
static INLINE float cc_int(float x, float b)
{
float val = x * b * M_PI + sinf(x * b * M_PI);
return (val > M_PI) ? M_PI : (val < -M_PI) ? -M_PI : val;
}
#define cc_kernel(x, b) ((cc_int((x) + 0.5, (b)) - cc_int((x) - 0.5, (b))) / (2.0 * M_PI))
#else
static INLINE float cc_int(float x, float b)
{
float val = x * b;
#if (CC_RESAMPLER_PRECISION > 0)
val = val*(1 - 0.25 * val * val * (3.0 - val * val));
#endif
return (val > 0.5) ? 0.5 : (val < -0.5) ? -0.5 : val;
}
#define cc_kernel(x, b) ((cc_int((x) + 0.5, (b)) - cc_int((x) - 0.5, (b))))
#endif
static INLINE void add_to(const audio_frame_float_t *source,
audio_frame_float_t *target, float ratio)
{
target->l += source->l * ratio;
target->r += source->r * ratio;
}
static void resampler_CC_downsample(void *re_, struct resampler_data *data)
{
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
float ratio = 1.0 / data->ratio;
float b = data->ratio; /* cutoff frequency. */
while (inp != inp_max)
{
add_to(inp, re->buffer + 0, cc_kernel(re->distance, b));
add_to(inp, re->buffer + 1, cc_kernel(re->distance - ratio, b));
add_to(inp, re->buffer + 2, cc_kernel(re->distance - ratio - ratio, b));
re->distance++;
inp++;
if (re->distance > (ratio + 0.5))
{
*outp = re->buffer[0];
re->buffer[0] = re->buffer[1];
re->buffer[1] = re->buffer[2];
re->buffer[2].l = 0.0;
re->buffer[2].r = 0.0;
re->distance -= ratio;
outp++;
}
}
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
}
static void resampler_CC_upsample(void *re_, struct resampler_data *data)
{
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
audio_frame_float_t *inp_max = (audio_frame_float_t*)
(inp + data->input_frames);
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
float b = float_min(data->ratio, 1.00); /* cutoff frequency. */
float ratio = 1.0 / data->ratio;
while (inp != inp_max)
{
re->buffer[0] = re->buffer[1];
re->buffer[1] = re->buffer[2];
re->buffer[2] = re->buffer[3];
re->buffer[3] = *inp;
while (re->distance < 1.0)
{
int i;
outp->l = 0.0;
outp->r = 0.0;
for (i = 0; i < 4; i++)
{
float temp = cc_kernel(re->distance + 1.0 - i, b);
outp->l += re->buffer[i].l * temp;
outp->r += re->buffer[i].r * temp;
}
re->distance += ratio;
outp++;
}
re->distance -= 1.0;
inp++;
}
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
}
#endif
static void resampler_CC_process(void *re_, struct resampler_data *data)
{
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
if (re)
re->process(re_, data);
}
static void *resampler_CC_init(const struct resampler_config *config,
double bandwidth_mod,
enum resampler_quality quality,
resampler_simd_mask_t mask)
{
int i;
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)
memalign_alloc(32, sizeof(rarch_CC_resampler_t));
/* TODO: lookup if NEON support can be detected at
* runtime and a funcptr set at runtime for either
* C codepath or NEON codepath. This will help out
* Android. */
(void)mask;
(void)config;
if (!re)
return NULL;
for (i = 0; i < 4; i++)
{
re->buffer[i].l = 0.0;
re->buffer[i].r = 0.0;
}
/* Variations of data->ratio around 0.75 are safer
* than around 1.0 for both up/downsampler. */
if (bandwidth_mod < 0.75)
{
re->process = resampler_CC_downsample;
re->distance = 0.0;
}
else
{
re->process = resampler_CC_upsample;
re->distance = 2.0;
}
return re;
}
#endif
static void resampler_CC_free(void *re_)
{
#ifndef _MIPS_ARCH_ALLEGREX
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)re_;
if (re)
memalign_free(re);
#endif
(void)re_;
}
retro_resampler_t CC_resampler = {
resampler_CC_init,
resampler_CC_process,
resampler_CC_free,
RESAMPLER_API_VERSION,
"CC",
"cc"
};

View File

@ -1,370 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Ali Bouhlel ( aliaspider@gmail.com )
*
* 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/>.
*/
#if defined(__ARM_NEON__)
#ifndef CC_RESAMPLER_PRECISION
#define CC_RESAMPLER_PRECISION 1
#endif
#ifndef __MACH__
.arm
#endif
.align 4
.globl resampler_CC_downsample_neon
#ifndef __MACH__
.type resampler_CC_downsample_neon, %function
#endif
.globl _resampler_CC_downsample_neon
#ifndef __MACH__
.type _resampler_CC_downsample_neon, %function
#endif
# size_t resampler_CC_downsample_neon(float *outp, const float *inp,
# rarch_CC_resampler_t* re_, size_t input_frames, float ratio);
# r0: outp initial (and output_frames return value)
# r1: inp initial/current
# r2: re_ [r2+0] --> {q14,q15}=buffer , [r2+32] --> s5=distance
# r3: input_frames/inp_max
# r4: outp current
# r5:
# r6:
# r7:
# q0: d0: s0: 0.0 # q4: d8: s16: min(ratio, 1.0)
# s1: 1.0 # s17: min(ratio, 1.0)
# d1: s2: 2.0 # d9: s18: min(ratio, 1.0)
# s3: 3.0 # s19: min(ratio, 1.0)
# q1: d2: s4: ratio # q5: d10: s20: 1.0
# s5: distance # s21: 1.0
# d3: s6: (1.0/ratio) # d11: s22: 1.0
# s7: (1.0/ratio)+0.5 # s23: 1.0
# q2: d4: s8: 0.5 # q6: d12: s24: 3.0
# s9: 0.5 # s25: 3.0
# d5: s10: 0.5 # d13: s26: 3.0
# s11: 0.5 # s27: 3.0
# q3: d6: s12: -0.5 # q7: d14: s28: 0.25
# s13: -0.5 # s29: 0.25
# d7: s14: -0.5 # d15: s30: 0.25
# s15: -0.5 # s31: 0.25
# q8: d16: (temp) # q12: d24: (temp)
# (temp) # (temp)
# d17: (temp) # d25: (temp)
# (temp) # (temp)
# q9: d18: (temp) # q13: d26: (temp)
# (temp) # (temp)
# d19: (temp) # d27: (temp)
# (temp) # (temp)
# q10: d20: (temp) # q14: d28: buffer[0]
# (temp) # buffer[1]
# d21: (temp) # d29: buffer[2]
# (temp) # buffer[3]
# q11: d22: (temp) # q15: d30: buffer[4]
# (temp) # buffer[5]
# d23: (temp) # d31: buffer[6]
# (temp) # buffer[7]
resampler_CC_downsample_neon:
_resampler_CC_downsample_neon:
vld1.f32 {q14-q15}, [r2, :256]
vldr s4, [sp]
vpush {q4,q5,q6,q7}
push {r4}
mov r4, r0
veor q0, q0, q0
vmov.f32 s1, #1.0
vmov.f32 s2, #2.0
vmov.f32 s3, #3.0
vmov.f32 q2, #0.5
vmov.f32 q3, #-0.5
vmov.f32 q5, #1.0
vmov.f32 q6, #3.0
vmov.f32 q7, #0.25
vldr s5, [r2, #32]
vdiv.f32 s6, s20, s4
vadd.f32 s7, s6, s8
vdup.f32 q4, d2[0]
vmin.f32 q4, q4, q5
lsl r3, #3
add r3, r3, r1
cmp r3, r1
beq 3f
1:
vdup.f32 q8, d3[0]
vmul.f32 q8, q8, q0
vdup.f32 q9, d2[1]
vsub.f32 q8, q9, q8
vadd.f32 q10, q8, q2
vsub.f32 q11, q8, q2
vmul.f32 q10, q10, q4
vmul.f32 q11, q11, q4
#if (CC_RESAMPLER_PRECISION > 0)
vmul.f32 q8, q10, q10
vmul.f32 q9, q11, q11
vsub.f32 q12, q6, q8
vsub.f32 q13, q6, q9
vmul.f32 q12, q12, q8
vmul.f32 q13, q13, q9
vmul.f32 q12, q12, q7
vmul.f32 q13, q13, q7
vsub.f32 q12, q5, q12
vsub.f32 q13, q5, q13
vmul.f32 q10, q10, q12
vmul.f32 q11, q11, q13
#endif
vmin.f32 q10, q10, q2
vmin.f32 q11, q11, q2
vmax.f32 q10, q10, q3
vmax.f32 q11, q11, q3
vsub.f32 q10, q10, q11
vmov.f32 q11, q10
vzip.f32 q10, q11
vld1.f32 d16, [r1, :64]!
vmov.f32 d17, d16
vmul.f32 q10, q10, q8
vmul.f32 q11, q11, q8
vadd.f32 q14, q14, q10
vadd.f32 q15, q15, q11
# distance++
vadd.f32 s5, s5, s20
vcmpe.f32 s5, s7
vmrs APSR_nzcv, fpscr
ble 2f
vst1.f32 d28, [r4, :64]!
vmov.f32 d28, d29
vmov.f32 d29, d30
vmov.f32 d30, d31
vmov.f32 d31, #0.0
vsub.f32 s5, s5, s6
2:
cmp r3, r1
bne 1b
3:
vst1.f32 {q14-q15}, [r2, :256]
vstr s5, [r2, #32]
sub r0, r4, r0
lsr r0, r0, #3
pop {r4}
vpop {q4,q5,q6,q7}
bx lr
.align 4
.globl resampler_CC_upsample_neon
#ifndef __MACH__
.type resampler_CC_upsample_neon, %function
#endif
.globl _resampler_CC_upsample_neon
#ifndef __MACH__
.type _resampler_CC_upsample_neon, %function
#endif
# size_t resampler_CC_upsample_neon(float *outp, const float *inp,
# rarch_CC_resampler_t* re_, size_t input_frames, float ratio);
# r0: outp initial (and output_frames return value)
# r1: inp initial/current
# r2: re_ [r2+0] --> {q14,q15}=buffer , [r2+32] --> s5=distance
# r3: input_frames/inp_max
# r4: outp current
# r5:
# r6:
# r7:
# q0: d0: s0: 1.0 # q4: d8: s16: min(ratio, 1.0)
# s1: 0.0 # s17: min(ratio, 1.0)
# d1: s2: -1.0 # d9: s18: min(ratio, 1.0)
# s3: -2.0 # s19: min(ratio, 1.0)
# q1: d2: s4: ratio # q5: d10: s20: 1.0
# s5: distance # s21: 1.0
# d3: s6: (1.0/ratio) # d11: s22: 1.0
# s7: (1.0/ratio)+0.5 # s23: 1.0
# q2: d4: s8: 0.5 # q6: d12: s24: 3.0
# s9: 0.5 # s25: 3.0
# d5: s10: 0.5 # d13: s26: 3.0
# s11: 0.5 # s27: 3.0
# q3: d6: s12: -0.5 # q7: d14: s28: 0.25
# s13: -0.5 # s29: 0.25
# d7: s14: -0.5 # d15: s30: 0.25
# s15: -0.5 # s31: 0.25
# q8: d16: (temp) # q12: d24: (temp)
# (temp) # (temp)
# d17: (temp) # d25: (temp)
# (temp) # (temp)
# q9: d18: (temp) # q13: d26: (temp)
# (temp) # (temp)
# d19: (temp) # d27: (temp)
# (temp) # (temp)
# q10: d20: (temp) # q14: d28: buffer[0]
# (temp) # buffer[1]
# d21: (temp) # d29: buffer[2]
# (temp) # buffer[3]
# q11: d22: (temp) # q15: d30: buffer[4]
# (temp) # buffer[5]
# d23: (temp) # d31: buffer[6]
# (temp) # buffer[7]
resampler_CC_upsample_neon:
_resampler_CC_upsample_neon:
vld1.f32 {q14-q15}, [r2, :256]
vldr s4, [sp]
vpush {q4,q5,q6,q7}
push {r4}
mov r4, r0
veor q0, q0, q0
vmov.f32 s0, #1.0
vmov.f32 s2, #-1.0
vmov.f32 s3, #-2.0
vmov.f32 q2, #0.5
vmov.f32 q3, #-0.5
vmov.f32 q5, #1.0
vmov.f32 q6, #3.0
vmov.f32 q7, #0.25
vldr s5, [r2, #32]
vdiv.f32 s6, s20, s4
vadd.f32 s7, s6, s8
vdup.f32 q4, d2[0]
vmin.f32 q4, q4, q5
lsl r3, #3
add r3, r3, r1
cmp r3, r1
beq 4f
1:
vld1.f32 d16, [r1, :64]!
vmov.f32 d28, d29
vmov.f32 d29, d30
vmov.f32 d30, d31
vmov.f32 d31, d16
vcmpe.f32 s5, s20
vmrs APSR_nzcv, fpscr
bge 3f
2:
vdup.f32 q8, d2[1]
vadd.f32 q8, q8, q0
vadd.f32 q10, q8, q2
vsub.f32 q11, q8, q2
vmul.f32 q10, q10, q4
vmul.f32 q11, q11, q4
#if (CC_RESAMPLER_PRECISION > 0)
vmul.f32 q8, q10, q10
vmul.f32 q9, q11, q11
vsub.f32 q12, q6, q8
vsub.f32 q13, q6, q9
vmul.f32 q12, q12, q8
vmul.f32 q13, q13, q9
vmul.f32 q12, q12, q7
vmul.f32 q13, q13, q7
vsub.f32 q12, q5, q12
vsub.f32 q13, q5, q13
vmul.f32 q10, q10, q12
vmul.f32 q11, q11, q13
#endif
vmin.f32 q10, q10, q2
vmin.f32 q11, q11, q2
vmax.f32 q10, q10, q3
vmax.f32 q11, q11, q3
vsub.f32 q10, q10, q11
vmov.f32 q11, q10
vzip.f32 q10, q11
vmul.f32 q10, q10, q14
vmul.f32 q11, q11, q15
vadd.f32 q10, q10, q11
vadd.f32 d20, d20, d21
vst1.f32 d20, [r4, :64]!
vadd.f32 s5, s5, s6
vcmpe.f32 s5, s20
vmrs APSR_nzcv, fpscr
blt 2b
3:
# distance--
vsub.f32 s5, s5, s20
cmp r3, r1
bne 1b
4:
vst1.f32 {q14-q15}, [r2, :256]
vstr s5, [r2, #32]
sub r0, r4, r0
lsr r0, r0, #3
pop {r4}
vpop {q4,q5,q6,q7}
bx lr
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
*
* 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 __RARCH_AUTOSAVE_H
#define __RARCH_AUTOSAVE_H
#include <stddef.h>
#include <retro_common_api.h>
RETRO_BEGIN_DECLS
/**
* autosave_lock:
*
* Lock autosave.
**/
void autosave_lock(void);
/**
* autosave_unlock:
*
* Unlocks autosave.
**/
void autosave_unlock(void);
bool autosave_init(void);
void autosave_deinit(void);
RETRO_END_DECLS
#endif

View File

@ -1,277 +0,0 @@
/*
* Linkscript for GC
*
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
OUTPUT_ARCH(powerpc:common);
EXTERN(_start);
ENTRY(_start);
PHDRS
{
stub PT_LOAD FLAGS(5);
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
bss PT_LOAD;
}
SECTIONS
{
/* default base address */
/* use -Wl,--section-start,.init=0xADDRESS to change */
. = 0x80003100;
/* Program */
.init :
{
KEEP (*crt0.o(*.init))
KEEP (*(.init))
} :text = 0
.plt : { *(.plt) }
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rela.got1 : { *(.rela.got1) }
.rela.got2 : { *(.rela.got2) }
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.text :
{
*(.text)
*(.text.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
.fini :
{
KEEP (*(.fini))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data
.rodata1 : { *(.rodata1) }
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.data1 : { *(.data1) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.fixup : { *(.fixup) }
.got1 : { *(.got1) }
.got2 : { *(.got2) }
.dynamic : { *(.dynamic) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
_edata = .;
PROVIDE (edata = .);
.sbss :
{
__sbss_start = .;
PROVIDE (__sbss_start = .);
PROVIDE (___sbss_start = .);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
PROVIDE (__sbss_end = .);
PROVIDE (___sbss_end = .);
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
__sbss_end = .;
} :bss
.bss :
{
__bss_start = .;
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32);
PROVIDE (__bss_end = .);
__bss_end = .;
}
_end = .;
PROVIDE(end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}
__isIPL = 0;
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x80000 + 7) & (-8);
__stack_end = (__bss_start + SIZEOF(.bss));
__intrstack_addr = (__stack_addr + 0x4000);
__intrstack_end = (__stack_addr);
__Arena1Lo = (__intrstack_addr + 31) & (-32);
__Arena1Hi = (0x817FEFF0);
__gxregs = (__Arena1Hi + 31) & (-32);
/* for backward compatibility with old crt0 */
PROVIDE (__stack = (0x817FEFF0));
PROVIDE(__isIPL = __isIPL);
PROVIDE(__stack_addr = __stack_addr);
PROVIDE(__stack_end = __stack_end);
PROVIDE(__intrstack_addr = __intrstack_addr);
PROVIDE(__intrstack_end = __intrstack_end);
PROVIDE(__Arena1Lo = __Arena1Lo);
PROVIDE(__Arena1Hi = __Arena1Hi);
PROVIDE(__gxregs = __gxregs);

View File

@ -1,297 +0,0 @@
/*
* Linkscript for Wii
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
OUTPUT_ARCH(powerpc:common);
EXTERN(_start);
ENTRY(_start);
PHDRS
{
stub PT_LOAD FLAGS(5);
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
bss1 PT_LOAD;
bss2 PT_LOAD;
}
SECTIONS
{
/* stub is loaded at physical address 0x00003400 (though both 0x80003400 and 0x00003400 are equivalent for IOS) */
/* This can also be used to load an arbitrary standalone stub at an arbitrary address in memory, for any purpose */
/* Use -Wl,--section-start,.stub=0xADDRESS to change */
. = 0x00003400;
.stub :
{
KEEP(*(.stub))
} :stub = 0
/* default base address */
/* use -Wl,--section-start,.init=0xADDRESS to change */
. = 0x80004000;
/* Program */
.init :
{
KEEP (*crt0.o(*.init))
KEEP (*(.init))
} :text = 0
.plt : { *(.plt) }
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rela.got1 : { *(.rela.got1) }
.rela.got2 : { *(.rela.got2) }
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.text :
{
*(.text)
*(.text.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
.fini :
{
KEEP (*(.fini))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data
.rodata1 : { *(.rodata1) }
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.data1 : { *(.data1) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.fixup : { *(.fixup) }
.got1 : { *(.got1) }
.got2 : { *(.got2) }
.dynamic : { *(.dynamic) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
_edata = .;
PROVIDE (edata = .);
.sbss :
{
__sbss_start = .;
PROVIDE (__sbss_start = .);
PROVIDE (___sbss_start = .);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
PROVIDE (__sbss_end = .);
PROVIDE (___sbss_end = .);
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
__sbss_end = .;
} :bss1
.bss :
{
__bss_start = .;
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32);
PROVIDE (__bss_end = .);
__bss_end = .;
} :bss2
_end = .;
PROVIDE(end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}
__isIPL = 0;
__stack_addr = (__bss_start + SIZEOF(.bss) + 0x80000 + 7) & (-8);
__stack_end = (__bss_start + SIZEOF(.bss));
__intrstack_addr = (__stack_addr + 0x4000);
__intrstack_end = (__stack_addr);
__Arena1Lo = (__intrstack_addr + 31) & (-32);
__Arena1Hi = (0x817FEFF0);
__Arena2Lo = (0x90002000);
__Arena2Hi = (0x933E0000);
__gxregs = (__Arena1Hi + 31) & (-32);
__ipcbufferLo = (0x933e0000);
__ipcbufferHi = (0x93400000);
/* for backward compatibility with old crt0 */
PROVIDE (__stack = (0x817FEFF0));
PROVIDE(__isIPL = __isIPL);
PROVIDE(__stack_addr = __stack_addr);
PROVIDE(__stack_end = __stack_end);
PROVIDE(__intrstack_addr = __intrstack_addr);
PROVIDE(__intrstack_end = __intrstack_end);
PROVIDE(__Arena1Lo = __Arena1Lo);
PROVIDE(__Arena1Hi = __Arena1Hi);
PROVIDE(__Arena2Lo = __Arena2Lo);
PROVIDE(__Arena2Hi = __Arena2Hi);
PROVIDE(__ipcbufferLo = __ipcbufferLo);
PROVIDE(__ipcbufferHi = __ipcbufferHi);
PROVIDE(__gxregs = __gxregs);

View File

@ -1,30 +0,0 @@
TARGET = kernel_functions
OBJS = main.o
PSP_FW_VERSION = 150
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
BUILD_PRX = 1
PRX_EXPORTS = $(TARGET).exp
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
LIBDIR =
LDFLAGS = -nostartfiles
LIBS = -lpspdebug -lpspge -lpspsdk -lc -lpspuser
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
all:
psp-build-exports -s $(PRX_EXPORTS)
cp $(TARGET).prx ../../../$(TARGET).prx
cp $(TARGET).S ../$(TARGET).S
cp $(TARGET).h ../$(TARGET).h
rm -f $(TARGET).prx
rm -f $(TARGET).S
rm -f *.o
rm -f *.elf

Some files were not shown because too many files have changed in this diff Show More