mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-10 03:21:30 -10:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28c7ae5007 | ||
|
|
0a613c04a6 | ||
|
|
f12092a09f | ||
|
|
21aa1cdbe6 | ||
|
|
5e18a5513c | ||
|
|
1188650a3f | ||
|
|
f64a01c5d4 | ||
|
|
42e803435f | ||
|
|
5e1486d92a | ||
|
|
f03a0cedca | ||
|
|
75a134a578 | ||
|
|
a9b9435e0b | ||
|
|
b674457671 | ||
|
|
7752c73abc |
No files matched your search
@@ -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
|
||||
File renamed without changes.
@@ -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]
|
||||
@@ -1,22 +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]
|
||||
-78
@@ -7,17 +7,10 @@
|
||||
*.elf
|
||||
*.dol
|
||||
*.map
|
||||
*.swp
|
||||
.tmp
|
||||
.tmp.c
|
||||
.tmp.cxx
|
||||
config.log
|
||||
/.project
|
||||
/.externalToolBuilders/
|
||||
/retroarch
|
||||
/retroarch.cfg
|
||||
/retroarch.exe
|
||||
/retroarch_debug.exe
|
||||
/config.h
|
||||
/config.mk
|
||||
/tools/retroarch-joyconfig
|
||||
@@ -68,41 +61,10 @@ menu/driverspzarch.c
|
||||
.pc
|
||||
/media/shaders_glsl/
|
||||
/obj-w32/
|
||||
.cproject
|
||||
.settings
|
||||
libretro-super
|
||||
run.sh
|
||||
convert_rumble.awk
|
||||
*~
|
||||
|
||||
# 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/
|
||||
@@ -120,46 +82,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
||||
|
||||
pkg/apple/iOS/build/
|
||||
pkg/apple/iOS/modules/
|
||||
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
|
||||
*.bc
|
||||
*.wasm
|
||||
|
||||
# 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
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "deps/glslang/glslang"]
|
||||
path = deps/glslang/glslang
|
||||
url = git://github.com/KhronosGroup/glslang.git
|
||||
@@ -5,23 +5,7 @@
|
||||
<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>
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
# Use 'generic' to be able to override CC/CXX for clang
|
||||
language: generic
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: mingw-x86
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-mingw-w64-i686
|
||||
- mingw-w64-i686-dev
|
||||
script:
|
||||
- CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501" ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1
|
||||
- compiler: mingw-x64
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-mingw-w64-x86-64
|
||||
- mingw-w64-x86-64-dev
|
||||
script:
|
||||
- CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501" ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 && make HAVE_ZLIB=1 HAVE_BUILTINZLIB=1 HAVE_RPNG=1
|
||||
- compiler: gcc
|
||||
- compiler: clang
|
||||
addons:
|
||||
# Install a more recent clang than the default
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
packages:
|
||||
- clang-3.8
|
||||
env: COMPILER_NAME=clang-3.8 CXX=clang++-3.8 CC=clang-3.8
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
script:
|
||||
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
|
||||
- os: osx
|
||||
osx_image: xcode9.3
|
||||
script:
|
||||
- cd ~/
|
||||
- brew install --force-bottle qt5
|
||||
- git clone --depth=50 https://github.com/libretro/libretro-super
|
||||
- cd libretro-super/travis
|
||||
- ./build-retroarch-metal.sh
|
||||
deploy:
|
||||
skip_cleanup: true
|
||||
provider: script
|
||||
script: cd ../retroarch; bash travis_metal_deploy.sh
|
||||
on:
|
||||
branch: master
|
||||
|
||||
script:
|
||||
- ./configure
|
||||
- make
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j2"
|
||||
- secure: "qc91ReC3OlzSh2gFaSH6TYzC2qIQvgA2AZff6J13eaH8xijAhuMzttZ0rMQJ0DWCIhPeUb0kIzVyaGoe4MwPALzpw1C1AznIWiZJ53HN+hWCOcS/af7YVPk6HPySnwqrS+Wv3AIIvIKFV2mxv21F/JbT/N+pArlRrp904Xj+KPo="
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- curl
|
||||
- pkg-config
|
||||
- libglu1-mesa-dev
|
||||
- freeglut3-dev
|
||||
- mesa-common-dev
|
||||
- libsdl1.2-dev
|
||||
- libsdl-image1.2-dev
|
||||
- libsdl-mixer1.2-dev
|
||||
- libsdl-ttf2.0-dev
|
||||
- libusb-1.0-0-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "RetroArch"
|
||||
description: "RetroArch is the official reference frontend for the libretro API."
|
||||
notification_email: [email protected]
|
||||
build_command_prepend: "./configure; make clean"
|
||||
build_command: "make"
|
||||
branch_pattern: coverity_scan
|
||||
notifications:
|
||||
email: false
|
||||
Vendored
-128
@@ -1,128 +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}"
|
||||
],
|
||||
"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}"
|
||||
],
|
||||
"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": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
-45
@@ -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": false,
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
Vendored
-25
@@ -1,25 +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.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"
|
||||
},
|
||||
"C_Cpp.dimInactiveRegions": false,
|
||||
}
|
||||
Vendored
-91
@@ -1,91 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "msys2-mingw64 rebuild",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "msys2-mingw64 clean",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make clean",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "msys2-mingw64 run",
|
||||
"type": "shell",
|
||||
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true },
|
||||
|
||||
"command": "./retroarch -v",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,273 +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 Mechtley (amechtley)
|
||||
Adolfo Ketzer (reztek)
|
||||
AdrianoML
|
||||
ajefr
|
||||
Alberto Simon (asimonf)
|
||||
Alcaro
|
||||
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)
|
||||
AridRayne
|
||||
Arto Vainiolehto (arakerlu)
|
||||
asako (asakous)
|
||||
Ash (QuarkTheAwesome)
|
||||
Ashura (CoalaJoe)
|
||||
Autechre64
|
||||
Avton1
|
||||
barbudreadmon
|
||||
bearoso
|
||||
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)
|
||||
chu (9chu)
|
||||
CidVonHighwind
|
||||
clienthax
|
||||
Conn O'Griofa (psyke83)
|
||||
cpsw
|
||||
Cray Elliott (MP2E)
|
||||
Cristian Sandu (crazyquark)
|
||||
ctult
|
||||
cubtekki
|
||||
cucholix
|
||||
cudencuden
|
||||
cxd4
|
||||
dalter
|
||||
Dan Weiss (Dwedit)
|
||||
danieljg
|
||||
Daniil Zhilin (GeneralFailer)
|
||||
dankcushions
|
||||
Danny Glover (DannyGlover)
|
||||
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
|
||||
Dudu Akiva (duduke)
|
||||
duganchen
|
||||
duskgao
|
||||
ekipan
|
||||
ensra
|
||||
erbridge
|
||||
esoptron
|
||||
Ethan Lee (flibitijibibo)
|
||||
Ezio-PS
|
||||
Fabio (Oibaf66)
|
||||
Fabio Ritrovato (Sephiroth87)
|
||||
Fayne Aldan (FayneAldan)
|
||||
FIX94
|
||||
Flame Sage (chris062689)
|
||||
flyinghead
|
||||
Francisco José García García (frangarcj)
|
||||
GameDragon2k
|
||||
Garrett Brown (garbear)
|
||||
gblues
|
||||
Geoffrey Plitt (GeoffreyPlitt)
|
||||
Glenn Hevey (hevey)
|
||||
Googer
|
||||
gouchi
|
||||
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)
|
||||
hizzlekizzle
|
||||
Hugo B. (777sha)
|
||||
hunterk
|
||||
Hyllian
|
||||
i30817
|
||||
iAmGhost
|
||||
Jack (jakcron)
|
||||
James Le Cuirot (chewi)
|
||||
James Sexton (Bezier89)
|
||||
Jan Holthuis (Holzhaus)
|
||||
Jay McCarthy (jeapostrophe)
|
||||
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)
|
||||
Joseph Carter (iKarith)
|
||||
Joseph Conan Montgomery (Grotke)
|
||||
Josh Palmer (ShiftyAxel)
|
||||
JuanVCS
|
||||
Justin Jacobs (dorkster)
|
||||
Justin Weiss (justinweiss)
|
||||
Ken Rossato (rossato)
|
||||
kurumushi
|
||||
kwyxz
|
||||
l3iggs
|
||||
lasers
|
||||
Lawrence Kesteloot (lkesteloot)
|
||||
liffy (lifning)
|
||||
Lionel Flandrin (simias)
|
||||
littleguy77
|
||||
Logan (loganmc10)
|
||||
lordashram
|
||||
Lothar Serra Mari (lotharsm)
|
||||
Lubosz Sarnecki (lubosz)
|
||||
lucianposton
|
||||
lxerandrew
|
||||
Mahyar Koshkouei (deltabeard)
|
||||
Marcelo Munhoz Pélos (mpelos)
|
||||
markwkidd
|
||||
Maschell
|
||||
Mat M. (lioncash)
|
||||
Matt Sephton (gingerbeardman)
|
||||
Maxime Gauduin (alucryd)
|
||||
mcrisostomo
|
||||
meancoot
|
||||
meepingsnesroms
|
||||
meleu
|
||||
Michael K. (kuxii2016)
|
||||
Michał Durak (micechal)
|
||||
Mico Chopitea (micochops)
|
||||
miguelpinheiro
|
||||
Mike Swanson (chungy)
|
||||
miqlas (extrowerk)
|
||||
misson20000
|
||||
Monroe88
|
||||
mprobinson
|
||||
MrHuu
|
||||
muzuiget
|
||||
mwtremblay
|
||||
Nathan S. (natinusala)
|
||||
nattycleopatra
|
||||
netux79
|
||||
nfnty
|
||||
Nicolas Adenis-Lamarre (nadenislamarre)
|
||||
Nicolas Guillaumin (nguillaumin)
|
||||
Nicolas Lopez Fernandez (pyroesp)
|
||||
Nikita Vakhrushev (JesterIOS)
|
||||
Nikola Kocic (nikola-kocic)
|
||||
Niouby
|
||||
nosh01
|
||||
not6 (r-type)
|
||||
notaz
|
||||
nstCactus
|
||||
nurupo
|
||||
Oggom
|
||||
Oleg Shevchenko (olsh)
|
||||
opendata26
|
||||
orbea
|
||||
OV2
|
||||
pamapa
|
||||
Paolo Bonzini (bonzini)
|
||||
Paul McCarty (a-shark)
|
||||
Pedro Ribeiro (pedrib)
|
||||
pinumbernumber
|
||||
pponso1
|
||||
Ramiro Morales (ramiro)
|
||||
retro-wertz
|
||||
Richard Howell (rmaz)
|
||||
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)
|
||||
Scheiker
|
||||
Sebastien Ronsse (sronsse)
|
||||
Sergi Granell (xerpi)
|
||||
Sergio Padrino (sergiou87)
|
||||
sergio-br2 (sergiobenrocha2)
|
||||
Seth Kingsley (sethk)
|
||||
Shane Mouton (ismouton)
|
||||
Shizeeg Unadequatov (shizeeg)
|
||||
Skarsnik
|
||||
slotek
|
||||
sparklewind
|
||||
spec-chum
|
||||
Stefan (gizmo98)
|
||||
stefan-gr
|
||||
Steven M. Vascellaro (stevoisiak)
|
||||
Stuart Carnie (stuartcarnie)
|
||||
Sunguk Lee (d3m3vilurr)
|
||||
Supernature2k
|
||||
Sven (RetroSven)
|
||||
Swizzy
|
||||
Tatsuya79
|
||||
Terry Lewis (terry-au)
|
||||
The Last Cabra (vanfanel)
|
||||
thedax
|
||||
theheroGAC
|
||||
TheOfficialFloW
|
||||
thiolliere
|
||||
Toad King (ToadKing)
|
||||
Tobias Jakobi (tobiasjakobi)
|
||||
Tomáš Kelemen (ToKe79)
|
||||
Torsten Paul (t-paul)
|
||||
TotalCaesar659
|
||||
TroggleMonkey
|
||||
Twinaphex
|
||||
URBANsUNITED
|
||||
vgmoose
|
||||
Vicky C Lau (vickychenglau)
|
||||
Vladimir Panteleev (CyberShadow)
|
||||
Víctor "IlDucci" (IlDucci)
|
||||
Wang Vincent (susemm)
|
||||
webgeek1234
|
||||
Wiktor Strzębała (wiktorek140)
|
||||
xhp-creations
|
||||
Yarsan Hoessain (hyarsan)
|
||||
Yongwoon Cho (ssangkong)
|
||||
yoshisuga
|
||||
zeromus
|
||||
zlice
|
||||
Zoran Vuckovic (casdevel)
|
||||
)";
|
||||
-487
@@ -1,487 +0,0 @@
|
||||
# 1.7.5 (future)
|
||||
- CAMERA: Fix Video4Linux2 driver that broke years ago.
|
||||
- CHEEVOS: Support headerless NES hashing.
|
||||
- CRT: New porches and interlaced bug fix.
|
||||
- COMMON: Support for "OEM-102" key (usually '\' on Euro keyboards).
|
||||
- DISCORD: Add 'Ask To Join' Feature.
|
||||
- LOCALIZATION: Update Portuguese / Brazilian translation.
|
||||
- LOCALIZATION: Update Japanese translation.
|
||||
- LOCALIZATION: Update Polish translation.
|
||||
- LOCALIZATION: Update Spanish translation.
|
||||
- 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.
|
||||
- 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.
|
||||
- SWITCH: Merging of RetroNX Nintendo Switch port, based on libnx SDK.
|
||||
- VULKAN: Fix race condition in threaded mailbox emulation.
|
||||
- VULKAN: Maintenance fixes.
|
||||
|
||||
# 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
|
||||
@@ -1,6 +1,4 @@
|
||||
HAVE_FILE_LOGGER=1
|
||||
HAVE_CC_RESAMPLER=1
|
||||
NEED_CXX_LINKER=0
|
||||
MISSING_DECLS =0
|
||||
|
||||
ifneq ($(C90_BUILD),)
|
||||
@@ -9,56 +7,33 @@ endif
|
||||
|
||||
include config.mk
|
||||
|
||||
# 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
|
||||
|
||||
TARGET = retroarch
|
||||
|
||||
OBJDIR_BASE := obj-unix
|
||||
OBJDIR := obj-unix
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OBJDIR := $(OBJDIR_BASE)/debug
|
||||
else
|
||||
OBJDIR := $(OBJDIR_BASE)/release
|
||||
ifeq ($(GLOBAL_CONFIG_DIR),)
|
||||
GLOBAL_CONFIG_DIR = /etc
|
||||
endif
|
||||
|
||||
OBJ :=
|
||||
OBJ :=
|
||||
LIBS :=
|
||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
|
||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -DHAVE_OVERLAY
|
||||
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
||||
|
||||
ifneq ($(findstring BSD,$(OS)),)
|
||||
CFLAGS += -DBSD
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
endif
|
||||
|
||||
ifneq ($(findstring DOS,$(OS)),)
|
||||
CFLAGS += -march=i386
|
||||
LDFLAGS += -lemu
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
LDFLAGS += -static-libgcc -lwinmm
|
||||
LDFLAGS += -static-libgcc
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
||||
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang"),1)
|
||||
DEFINES += -Wno-invalid-source-encoding -Wno-incompatible-ms-struct
|
||||
endif
|
||||
|
||||
ifeq ($(shell $(CC) -v 2>&1 | grep -c "tcc"),1)
|
||||
MD = -MD
|
||||
else
|
||||
MD = -MMD
|
||||
DEFINES += -Wno-invalid-source-encoding
|
||||
endif
|
||||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
ifeq ($(MISSING_DECLS), 1)
|
||||
DEFINES += -Werror=missing-declarations
|
||||
DEFINES += -Werror=missing-declarations
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
@@ -77,37 +52,30 @@ endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTIMIZE_FLAG = -O0 -g
|
||||
DEFINES += -DDEBUG -D_DEBUG
|
||||
else
|
||||
OPTIMIZE_FLAG = -O3 -ffast-math
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
LDFLAGS += -mwindows
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall $(OPTIMIZE_FLAG) $(INCLUDE_DIRS) -I. -Ideps -Ideps/stb
|
||||
CFLAGS += -Wall $(OPTIMIZE_FLAG) $(INCLUDE_DIRS) $(DEBUG_FLAG) -I.
|
||||
|
||||
APPEND_CFLAGS := $(CFLAGS)
|
||||
CXXFLAGS += $(APPEND_CFLAGS) -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
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
LINK = $(CXX)
|
||||
CFLAGS := $(CXXFLAGS) -xc++
|
||||
else
|
||||
LINK = $(CC)
|
||||
endif
|
||||
ifeq ($(findstring Win32,$(OS)),)
|
||||
LINK = $(CC)
|
||||
else
|
||||
# directx-related code is c++
|
||||
LINK = $(CXX)
|
||||
endif
|
||||
|
||||
ifneq ($(CXX_BUILD), 1)
|
||||
ifneq ($(GNU90_BUILD), 1)
|
||||
ifneq ($(findstring icc,$(CC)),)
|
||||
CFLAGS += -std=c99 -D_GNU_SOURCE
|
||||
@@ -132,16 +100,10 @@ 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)
|
||||
CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS)
|
||||
CXXFLAGS := -fsanitize=$(SANITIZER) $(CXXFLAGS)
|
||||
LDFLAGS := -fsanitize=$(SANITIZER) $(LDLAGS)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(GPERFTOOLS),profiler),)
|
||||
@@ -151,37 +113,12 @@ 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)$(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)
|
||||
config.mk: configure qb/*
|
||||
@echo "config.mk is outdated or non-existing. Run ./configure again."
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
retroarch: $(RARCH_OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
@@ -190,12 +127,12 @@ retroarch: $(RARCH_OBJ)
|
||||
$(OBJDIR)/%.o: %.c config.h config.mk
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) $(MD) -c -o $@ $<
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -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 $@ $<
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.m
|
||||
@mkdir -p $(dir $@)
|
||||
@@ -221,57 +158,31 @@ $(OBJDIR)/%.o: %.rc $(HEADERS)
|
||||
|
||||
install: $(TARGET)
|
||||
rm -f $(OBJDIR)/git_version.o
|
||||
mkdir -p $(DESTDIR)$(BIN_DIR) 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin 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; then \
|
||||
echo "Installing media assets..."; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets/xmb; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets/glui; \
|
||||
cp -r media/assets/xmb/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
cp -r media/assets/glui/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
cp media/assets/COPYING $(DESTDIR)$(DOC_DIR)/COPYING.assets; \
|
||||
echo "Asset copying done."; \
|
||||
fi
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/share/applications 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(MAN_DIR) 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/share/pixmaps 2>/dev/null || /bin/true
|
||||
install -m755 $(TARGET) $(DESTDIR)$(PREFIX)/bin
|
||||
install -m755 tools/cg2glsl.py $(DESTDIR)$(PREFIX)/bin/retroarch-cg2glsl
|
||||
install -m644 retroarch.cfg $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
|
||||
install -m644 retroarch.desktop $(DESTDIR)$(PREFIX)/share/applications
|
||||
install -m644 docs/retroarch.1 $(DESTDIR)$(MAN_DIR)
|
||||
install -m644 docs/retroarch-cg2glsl.1 $(DESTDIR)$(MAN_DIR)
|
||||
install -m644 media/retroarch.svg $(DESTDIR)$(PREFIX)/share/pixmaps
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/retroarch
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/retroarch
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/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)
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/applications/retroarch.desktop
|
||||
rm -f $(DESTDIR)$(MAN_DIR)/retroarch.1
|
||||
rm -f $(DESTDIR)$(MAN_DIR)/retroarch-cg2glsl.1
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/pixmaps/retroarch.svg
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -rf $(OBJDIR)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
|
||||
.PHONY: all install uninstall clean
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
||||
@@ -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 '$*=$($*)'
|
||||
+360
-1116
File diff suppressed because it is too large.
Load diff
+249
-117
@@ -5,94 +5,240 @@ DEBUG = 0
|
||||
GRIFFIN_BUILD = 1
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
BUILD_3DSX = 1
|
||||
BUILD_3DS = 0
|
||||
BUILD_3DS = 1
|
||||
BUILD_CIA = 1
|
||||
LIBCTRU_NO_DEPRECATION = 1
|
||||
|
||||
APP_TITLE = RetroArch 3DS
|
||||
APP_DESCRIPTION = RetroArch 3DS
|
||||
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_ICON = ctr/assets/default.png
|
||||
APP_BANNER = ctr/assets/libretro_banner.png
|
||||
APP_AUDIO = ctr/assets/silent.wav
|
||||
APP_RSF = 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
|
||||
include 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
|
||||
OBJS :=
|
||||
OBJS += gfx/drivers/ctr_sprite.o
|
||||
OBJS += ctr/ctr_system.o
|
||||
OBJS += ctr/ctr_memory.o
|
||||
OBJS += ctr/ctr_linear.o
|
||||
OBJS += ctr/ctr_svchax.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 -DHAVE_SOCKET_LEGACY -DHAVE_THREADS
|
||||
#-DHAVE_SSL -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
|
||||
OBJS += griffin/griffin.o
|
||||
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_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
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
|
||||
|
||||
include Makefile.common
|
||||
BLACKLIST :=
|
||||
BLACKLIST += input/input_overlay.o
|
||||
BLACKLIST += tasks/task_overlay.o
|
||||
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
|
||||
OBJS += libretro-common/file/file_extract.o
|
||||
OBJS += verbosity.o
|
||||
OBJS += performance.o
|
||||
OBJS += libretro-common/compat/compat_getopt.o
|
||||
OBJS += libretro-common/compat/compat_strcasestr.o
|
||||
OBJS += libretro-common/compat/compat_strl.o
|
||||
OBJS += libretro-common/compat/compat_fnmatch.o
|
||||
OBJS += libretro-common/memmap/memalign.o
|
||||
OBJS += libretro-common/file/config_file.o
|
||||
OBJS += libretro-common/file/config_file_userdata.o
|
||||
OBJS += core_options.o
|
||||
OBJS += cheats.o
|
||||
OBJS += libretro-common/hash/rhash.o
|
||||
OBJS += gfx/video_context_driver.o
|
||||
OBJS += gfx/drivers_context/gfx_null_ctx.o
|
||||
OBJS += gfx/image/image.o
|
||||
OBJS += libretro-common/formats/tga/rtga.o
|
||||
OBJS += libretro-common/formats/png/rpng.o
|
||||
OBJS += libretro-common/formats/png/rpng_encode.o
|
||||
OBJS += libretro-common/formats/bmp/rbmp_encode.o
|
||||
OBJS += libretro-common/gfx/math/matrix_4x4.o
|
||||
OBJS += libretro-common/gfx/math/matrix_3x3.o
|
||||
OBJS += gfx/drivers/ctr_gfx.o
|
||||
OBJS += gfx/drivers/nullgfx.o
|
||||
OBJS += gfx/font_driver.o
|
||||
OBJS += gfx/drivers_font_renderer/bitmapfont.o
|
||||
OBJS += input/input_autodetect.o
|
||||
OBJS += input/input_joypad_driver.o
|
||||
OBJS += input/input_hid_driver.o
|
||||
OBJS += input/input_config.o
|
||||
OBJS += input/input_keymaps.o
|
||||
OBJS += input/input_remapping.o
|
||||
OBJS += input/input_keyboard.o
|
||||
OBJS += input/drivers/ctr_input.o
|
||||
OBJS += input/drivers_joypad/ctr_joypad.o
|
||||
OBJS += input/autoconf/builtin_ctr.o
|
||||
OBJS += input/drivers/nullinput.o
|
||||
OBJS += input/drivers_joypad/null_joypad.o
|
||||
OBJS += input/drivers_joypad/hid_joypad.o
|
||||
OBJS += input/drivers_hid/null_hid.o
|
||||
OBJS += gfx/video_state_tracker.o
|
||||
OBJS += libretro-common/queues/fifo_buffer.o
|
||||
OBJS += audio/audio_resampler_driver.o
|
||||
OBJS += audio/drivers_resampler/sinc.o
|
||||
OBJS += audio/drivers_resampler/nearest.o
|
||||
OBJS += audio/drivers_resampler/cc_resampler.o
|
||||
OBJS += camera/drivers/nullcamera.o
|
||||
OBJS += location/drivers/nulllocation.o
|
||||
OBJS += audio/drivers/ctr_csnd_audio.o
|
||||
OBJS += audio/drivers/ctr_dsp_audio.o
|
||||
OBJS += audio/drivers/nullaudio.o
|
||||
OBJS += gfx/video_driver.o
|
||||
OBJS += gfx/video_common.o
|
||||
OBJS += input/input_driver.o
|
||||
OBJS += audio/audio_driver.o
|
||||
OBJS += camera/camera_driver.o
|
||||
OBJS += location/location_driver.o
|
||||
OBJS += driver.o
|
||||
OBJS += libretro-common/gfx/scaler/scaler_filter.o
|
||||
OBJS += libretro-common/gfx/scaler/pixconv.o
|
||||
OBJS += libretro-common/gfx/scaler/scaler.o
|
||||
OBJS += libretro-common/gfx/scaler/scaler_int.o
|
||||
OBJS += gfx/video_filters/2xsai.o
|
||||
OBJS += gfx/video_filters/super2xsai.o
|
||||
OBJS += gfx/video_filters/supereagle.o
|
||||
OBJS += gfx/video_filters/2xbr.o
|
||||
OBJS += gfx/video_filters/darken.o
|
||||
OBJS += gfx/video_filters/epx.o
|
||||
OBJS += gfx/video_filters/scale2x.o
|
||||
OBJS += gfx/video_filters/blargg_ntsc_snes.o
|
||||
OBJS += gfx/video_filters/lq2x.o
|
||||
OBJS += gfx/video_filters/phosphor2x.o
|
||||
OBJS += audio/audio_filters/echo.o
|
||||
OBJS += audio/audio_filters/eq.o
|
||||
OBJS += audio/audio_filters/chorus.o
|
||||
OBJS += audio/audio_filters/iir.o
|
||||
OBJS += audio/audio_filters/panning.o
|
||||
OBJS += audio/audio_filters/phaser.o
|
||||
OBJS += audio/audio_filters/reverb.o
|
||||
OBJS += audio/audio_filters/wahwah.o
|
||||
OBJS += libretro-common/dynamic/dylib.o
|
||||
OBJS += dynamic.o
|
||||
OBJS += gfx/video_filter.o
|
||||
OBJS += audio/audio_dsp_filter.o
|
||||
OBJS += cores/dynamic_dummy.o
|
||||
OBJS += content.o
|
||||
OBJS += libretro-common/file/file_path.o
|
||||
OBJS += file_path_special.o
|
||||
OBJS += libretro-common/file/dir_list.o
|
||||
OBJS += libretro-common/file/retro_dirent.o
|
||||
OBJS += libretro-common/file/retro_file.o
|
||||
OBJS += libretro-common/file/retro_stat.o
|
||||
OBJS += dir_list_special.o
|
||||
OBJS += string_list_special.o
|
||||
OBJS += libretro-common/string/string_list.o
|
||||
OBJS += libretro-common/string/stdstring.o
|
||||
OBJS += file_ops.o
|
||||
OBJS += libretro-common/file/nbio/nbio_stdio.o
|
||||
OBJS += libretro-common/file/file_list.o
|
||||
OBJS += libretro-common/queues/message_queue.o
|
||||
OBJS += patch.o
|
||||
OBJS += configuration.o
|
||||
OBJS += rewind.o
|
||||
OBJS += frontend/frontend_driver.o
|
||||
OBJS += frontend/drivers/platform_ctr.o
|
||||
OBJS += frontend/drivers/platform_null.o
|
||||
OBJS += core_info.o
|
||||
OBJS += ui/ui_companion_driver.o
|
||||
OBJS += ui/drivers/ui_null.o
|
||||
OBJS += frontend/frontend.o
|
||||
OBJS += libretro_version_1.o
|
||||
OBJS += retroarch.o
|
||||
OBJS += runloop.o
|
||||
OBJS += tasks/tasks.o
|
||||
OBJS += msg_hash.o
|
||||
OBJS += intl/msg_hash_de.o
|
||||
OBJS += intl/msg_hash_es.o
|
||||
OBJS += intl/msg_hash_eo.o
|
||||
OBJS += intl/msg_hash_fr.o
|
||||
OBJS += intl/msg_hash_it.o
|
||||
OBJS += intl/msg_hash_nl.o
|
||||
OBJS += intl/msg_hash_pt.o
|
||||
OBJS += intl/msg_hash_pl.o
|
||||
OBJS += intl/msg_hash_us.o
|
||||
OBJS += movie.o
|
||||
OBJS += record/record_driver.o
|
||||
OBJS += record/drivers/record_null.o
|
||||
OBJS += tasks/task_decompress.o
|
||||
OBJS += tasks/task_file_transfer.o
|
||||
OBJS += screenshot.o
|
||||
OBJS += playlist.o
|
||||
OBJS += menu/menu_driver.o
|
||||
OBJS += menu/menu_hash.o
|
||||
OBJS += menu/menu_input.o
|
||||
OBJS += menu/menu_entry.o
|
||||
OBJS += menu/menu_entries.o
|
||||
OBJS += menu/menu_setting.o
|
||||
OBJS += menu/menu_cbs.o
|
||||
OBJS += menu/cbs/menu_cbs_ok.o
|
||||
OBJS += menu/cbs/menu_cbs_cancel.o
|
||||
OBJS += menu/cbs/menu_cbs_select.o
|
||||
OBJS += menu/cbs/menu_cbs_start.o
|
||||
OBJS += menu/cbs/menu_cbs_info.o
|
||||
OBJS += menu/cbs/menu_cbs_refresh.o
|
||||
OBJS += menu/cbs/menu_cbs_left.o
|
||||
OBJS += menu/cbs/menu_cbs_right.o
|
||||
OBJS += menu/cbs/menu_cbs_title.o
|
||||
OBJS += menu/cbs/menu_cbs_deferred_push.o
|
||||
OBJS += menu/cbs/menu_cbs_scan.o
|
||||
OBJS += menu/cbs/menu_cbs_get_value.o
|
||||
OBJS += menu/cbs/menu_cbs_up.o
|
||||
OBJS += menu/cbs/menu_cbs_down.o
|
||||
OBJS += menu/cbs/menu_cbs_contentlist_switch.o
|
||||
OBJS += menu/menu_shader.o
|
||||
OBJS += menu/menu_navigation.o
|
||||
OBJS += menu/menu_display.o
|
||||
OBJS += menu/menu_displaylist.o
|
||||
OBJS += menu/menu_animation.o
|
||||
OBJS += menu/intl/menu_hash_de.o
|
||||
OBJS += menu/intl/menu_hash_es.o
|
||||
OBJS += menu/intl/menu_hash_eo.o
|
||||
OBJS += menu/intl/menu_hash_fr.o
|
||||
OBJS += menu/intl/menu_hash_it.o
|
||||
OBJS += menu/intl/menu_hash_nl.o
|
||||
OBJS += menu/intl/menu_hash_pl.o
|
||||
OBJS += menu/intl/menu_hash_pt.o
|
||||
OBJS += menu/intl/menu_hash_us.o
|
||||
OBJS += menu/drivers/null.o
|
||||
OBJS += menu/drivers/menu_generic.o
|
||||
OBJS += menu/drivers_display/menu_display_null.o
|
||||
OBJS += menu/drivers/rgui.o
|
||||
OBJS += command_event.o
|
||||
OBJS += deps/zlib/adler32.o
|
||||
OBJS += deps/zlib/compress.o
|
||||
OBJS += deps/zlib/crc32.o
|
||||
OBJS += deps/zlib/deflate.o
|
||||
OBJS += deps/zlib/gzclose.o
|
||||
OBJS += deps/zlib/gzlib.o
|
||||
OBJS += deps/zlib/gzread.o
|
||||
OBJS += deps/zlib/gzwrite.o
|
||||
OBJS += deps/zlib/inffast.o
|
||||
OBJS += deps/zlib/inflate.o
|
||||
OBJS += deps/zlib/inftrees.o
|
||||
OBJS += deps/zlib/trees.o
|
||||
OBJS += deps/zlib/uncompr.o
|
||||
OBJS += deps/zlib/zutil.o
|
||||
OBJS += deps/zlib/ioapi.o
|
||||
OBJS += deps/zlib/unzip.o
|
||||
OBJS += audio/audio_utils.o
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitpro")
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(CTRULIB)),)
|
||||
CTRULIB = $(DEVKITPRO)/libctru
|
||||
$(error "Please set CTRULIB in your environment. export CTRULIB=<path to>ctrulib")
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(AEMSTRO)),)
|
||||
$(error "Please set AEMSTRO in your environment. export AEMSTRO=<path to>aemstro")
|
||||
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)
|
||||
@@ -130,38 +276,33 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
WHOLE_END := -Wl,--no-whole-archive
|
||||
endif
|
||||
|
||||
CFLAGS += -I. -Ideps -Ideps/libz -Ideps/7zip -Ideps/stb -Ilibretro-common/include
|
||||
CFLAGS += -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include
|
||||
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
|
||||
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE -DSINC_LOWEST_QUALITY
|
||||
CFLAGS += -DHAVE_GRIFFIN=1 -DHAVE_FILTERS_BUILTIN -DHAVE_MENU -DHAVE_RGUI
|
||||
CFLAGS += -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -DHAVE_BUILTIN_AUTOCONFIG
|
||||
|
||||
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)
|
||||
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
|
||||
LIBS := $(WHOLE_START) -lretro_ctr $(WHOLE_END) -lctru -lm
|
||||
|
||||
|
||||
ifeq ($(BUILD_3DSX), 1)
|
||||
TARGET_3DSX := $(TARGET).3dsx $(TARGET).smdh
|
||||
TARGET_3DSX := $(TARGET).3dsx $(TARGET).smdh
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_3DS), 1)
|
||||
TARGET_3DS := $(TARGET).3ds
|
||||
TARGET_3DS := $(TARGET).3ds
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_CIA), 1)
|
||||
TARGET_CIA := $(TARGET).cia
|
||||
TARGET_CIA := $(TARGET).cia
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
@@ -170,7 +311,12 @@ all: $(TARGET)
|
||||
|
||||
$(TARGET): $(TARGET_3DSX) $(TARGET_3DS) $(TARGET_CIA)
|
||||
$(TARGET).3dsx: $(TARGET).elf
|
||||
$(TARGET).elf: $(OBJ) libretro_ctr.a
|
||||
$(TARGET).elf: $(OBJS) libretro_ctr.a
|
||||
|
||||
ctr_sprite_shader_shbin.h: gfx/drivers/ctr_sprite.o
|
||||
gfx/drivers/ctr_gfx.c: ctr_sprite_shader_shbin.h
|
||||
griffin/griffin.o: gfx/drivers/ctr_gfx.c
|
||||
|
||||
|
||||
PREFIX := $(DEVKITARM)/bin/arm-none-eabi-
|
||||
|
||||
@@ -183,39 +329,25 @@ 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
|
||||
ifneq ($(findstring Linux,$(shell uname -a)),)
|
||||
MAKEROM = ctr/tools/makerom-linux
|
||||
BANNERTOOL = ctr/tools/bannertool-linux
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
MAKEROM = ctr/tools/makerom-mac
|
||||
BANNERTOOL = ctr/tools/bannertool-mac
|
||||
else
|
||||
BANNERTOOL = $(CTRBANNERTOOL)
|
||||
MAKEROM = ctr/tools/makerom.exe
|
||||
BANNERTOOL = ctr/tools/bannertool.exe
|
||||
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: %.shader
|
||||
python $(AEMSTRO)/aemstro_as.py $< $(notdir $<).shbin
|
||||
$(DEVKITARM)/bin/bin2s $(notdir $<).shbin | $(PREFIX)as -o $@
|
||||
echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
rm $(notdir $<).shbin
|
||||
|
||||
%.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)
|
||||
@@ -235,18 +367,18 @@ endif
|
||||
%.vsh:
|
||||
|
||||
$(TARGET).smdh: $(APP_ICON)
|
||||
$(DEVKITARM)/bin/smdhtool --create "$(APP_TITLE)" "$(APP_DESCRIPTION)" "$(APP_AUTHOR)" $(APP_ICON) $@
|
||||
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
|
||||
cp ctr/big_text_section.xml $(TARGET).xml
|
||||
else
|
||||
rm -f $(TARGET).xml
|
||||
endif
|
||||
$(DEVKITARM)/bin/3dsxtool $< $@ $(_3DSXFLAGS)
|
||||
-3dsxtool $< $@ $(_3DSXFLAGS)
|
||||
|
||||
$(TARGET).elf: ctr/3dsx_custom_crt0.o
|
||||
$(LD) $(LDFLAGS) $(OBJ) $(LIBDIRS) $(LIBS) -o $@
|
||||
$(LD) $(LDFLAGS) $(OBJS) $(LIBDIRS) $(LIBS) -o $@
|
||||
$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(TARGET).bnr: $(APP_BANNER) $(APP_AUDIO)
|
||||
@@ -263,7 +395,7 @@ $(TARGET).cia: $(TARGET).elf $(TARGET).bnr $(TARGET).icn $(APP_RSF)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ)
|
||||
rm -f $(OBJS)
|
||||
rm -f $(TARGET).3dsx
|
||||
rm -f $(TARGET).elf
|
||||
rm -f $(TARGET).3ds
|
||||
@@ -271,9 +403,9 @@ clean:
|
||||
rm -f $(TARGET).smdh
|
||||
rm -f $(TARGET).bnr
|
||||
rm -f $(TARGET).icn
|
||||
rm -f *_shader_shbin.h
|
||||
rm -f ctr/ctr_config_*.o
|
||||
rm -f ctr/3dsx_custom_crt0.o
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
||||
@@ -1,224 +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/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
|
||||
|
||||
|
||||
+66
-51
@@ -1,62 +1,58 @@
|
||||
TARGET := retroarch.js
|
||||
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
|
||||
DEFINES := -DRARCH_INTERNAL -DHAVE_OVERLAY -DHAVE_MAIN
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL -DHAVE_FILTERS_BUILTIN
|
||||
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
HAVE_EGL = 1
|
||||
HAVE_OPENGLES = 1
|
||||
HAVE_RJPEG = 0
|
||||
HAVE_RPNG = 1
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_GLES = 1
|
||||
HAVE_EMSCRIPTEN = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_SDL = 0
|
||||
HAVE_SDL2 = 0
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_FBO = 1
|
||||
WANT_ZLIB = 1
|
||||
HAVE_SHADERPIPELINE = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
MEMORY = 536870912
|
||||
|
||||
PRECISE_F32 = 1
|
||||
|
||||
OBJDIR := obj-emscripten
|
||||
MEMORY = 268435456
|
||||
LTO = 0
|
||||
# XXX: setting this to 1/2 currently crashes Firefox nightly
|
||||
PRECISE_F32 = 2
|
||||
|
||||
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\" \
|
||||
LIBS :=
|
||||
LDFLAGS := -L. --no-heap-copy -s USE_ZLIB=1 -s TOTAL_MEMORY=$(MEMORY) -s OUTLINING_LIMIT=50000 \
|
||||
-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_rwebinput.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 += -Ideps/libz -Ideps -Ideps/stb
|
||||
OBJ += gfx/video_filters/2xsai.o
|
||||
OBJ += gfx/video_filters/super2xsai.o
|
||||
OBJ += gfx/video_filters/supereagle.o
|
||||
OBJ += gfx/video_filters/2xbr.o
|
||||
OBJ += gfx/video_filters/darken.o
|
||||
OBJ += gfx/video_filters/epx.o
|
||||
OBJ += gfx/video_filters/scale2x.o
|
||||
OBJ += gfx/video_filters/blargg_ntsc_snes.o
|
||||
OBJ += gfx/video_filters/lq2x.o
|
||||
OBJ += gfx/video_filters/phosphor2x.o
|
||||
|
||||
OBJ += audio/audio_filters/echo.o
|
||||
OBJ += audio/audio_filters/eq.o
|
||||
OBJ += audio/audio_filters/chorus.o
|
||||
OBJ += audio/audio_filters/iir.o
|
||||
OBJ += audio/audio_filters/panning.o
|
||||
OBJ += audio/audio_filters/phaser.o
|
||||
OBJ += audio/audio_filters/reverb.o
|
||||
OBJ += audio/audio_filters/wahwah.o
|
||||
|
||||
CFLAGS += -Ideps/zlib/
|
||||
libretro = libretro_emscripten.bc
|
||||
|
||||
ifneq ($(V), 1)
|
||||
@@ -67,7 +63,7 @@ ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -O0 -g
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
LDFLAGS += -O2 -s WASM=1
|
||||
LDFLAGS += -O2
|
||||
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
||||
LDFLAGS += -s PRECISE_F32=$(PRECISE_F32)
|
||||
ifeq ($(LTO), 1)
|
||||
@@ -76,29 +72,48 @@ else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
CFLAGS += -DHAVE_RPNG -Wall -I. -Ilibretro-common/include -std=gnu99 -s USE_ZLIB=1 \
|
||||
CFLAGS += -DWANT_RPNG -Wall -Wno-unused-result -Wno-unused-variable -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)
|
||||
$(TARGET): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) -o $@ $(RARCH_OBJ) $(libretro) $(LIBS) $(LDFLAGS)
|
||||
$(Q)$(LD) -o $@ $(OBJ) $(libretro) $(LIBS) $(LDFLAGS)
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) $(EOPTS) -c -o $@ $<
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) $(EOPTS) -c -o $@ $<
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR)
|
||||
rm -f *.o
|
||||
rm -f deps/zlib/*.o
|
||||
rm -f frontend/*.o
|
||||
rm -f menu/*.o
|
||||
rm -f menu/disp/*.o
|
||||
rm -f audio/*.o
|
||||
rm -f compat/*.o
|
||||
rm -f compat/rxml/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/scaler/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/d3d/*.o
|
||||
rm -f gfx/drivers_context/*.o
|
||||
rm -f gfx/math/*.o
|
||||
rm -f gfx/drivers_font/*.o
|
||||
rm -f gfx/drivers_font_renderer/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f gfx/rpng/*.o
|
||||
rm -f gfx/glsym/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f libretro-common/*/*.o
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
|
||||
.PHONY: all clean
|
||||
+223
-856
File diff suppressed because it is too large.
Load diff
-222
@@ -1,222 +0,0 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.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 :=
|
||||
|
||||
# For threading we need to overwrite some vars with global defines because devkitPro's includes
|
||||
# make it hard for us. This works for the pthread wrapper
|
||||
DEFINES_THREAD := -Dpthread_t=Thread -Dpthread_mutex_t=Mutex -Dpthread_mutexattr_t='void*' -Dpthread_attr_t=int -Dpthread_cond_t=CondVar -Dpthread_condattr_t='int' -D_SYS__PTHREADTYPES_H_
|
||||
DEFINES := -U__linux__ -U__linux -DRARCH_INTERNAL -DGLOBAL_CONFIG_DIR='"/switch"' $(DEFINES_THREAD)
|
||||
|
||||
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_ZARCH = 0
|
||||
HAVE_MATERIALUI = 0
|
||||
HAVE_XMB = 0
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_RUNAHEAD = 1
|
||||
|
||||
# RetroArch libnx useful flags
|
||||
HAVE_OVERLAY = 0
|
||||
HAVE_THREADS = 1
|
||||
HAVE_PTHREADS = 1
|
||||
HAVE_FREETYPE = 0
|
||||
HAVE_SWITCH = 1
|
||||
HAVE_LIBNX = 1
|
||||
|
||||
include Makefile.common
|
||||
BLACKLIST :=
|
||||
#BLACKLIST += input/input_overlay.o
|
||||
#BLACKLIST += tasks/task_overlay.o
|
||||
|
||||
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 := 1.0.0
|
||||
APP_AUTHOR := libretro Team
|
||||
NO_ICON := 1
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 -Ideps/stb -I$(LIBNX)/include -include $(LIBNX)/include/switch.h #$(shell $(DEVKITPRO)/portlibs/switch/bin/freetype-config --cflags)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DSWITCH=1 -DHAVE_LIBNX=1 -DNXLINK=1
|
||||
|
||||
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 := -lnx -lm -lstdc++ -lbz2 -lpng -lz
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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) libretro_switch.a
|
||||
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 := $(OFILES:.o=.d)
|
||||
|
||||
.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 $(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
|
||||
#---------------------------------------------------------------------------------------
|
||||
-358
@@ -1,358 +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
|
||||
-273
@@ -1,273 +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_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_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_LANGEXTRA := 1
|
||||
HAVE_CHEEVOS := 1
|
||||
HAVE_SHADERPIPELINE := 1
|
||||
HAVE_IMAGEVIEWER := 1
|
||||
|
||||
include Makefile.common
|
||||
INCLUDE_DIRS := $(patsubst -isystem%,-I%,$(INCLUDE_DIRS))
|
||||
CFLAGS := $(filter-out -Wno-unknown-pragmas,$(CFLAGS))
|
||||
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)))
|
||||
@@ -1,62 +0,0 @@
|
||||
# Hakchi version added to ease confusion amongst Hakchi community due to messy past...
|
||||
#
|
||||
# Make sure you have readelf installed (sudo apt-get install readelf) to patch the binary
|
||||
# Might not be needed for your build but it's a useful tool and for safety it should be
|
||||
# run anyway to ensure the SDL2 link isn't broken...
|
||||
|
||||
HAKCHI_VER := Hakchi_Retroarch_Neo_v1_7_3b
|
||||
HAKCHI_NAME := "Hakchi RetroArch 'Neo' v1.7.3b
|
||||
MOD_CREATOR := TheOtherGuys
|
||||
MOD_CATEGORY := RetroArch
|
||||
|
||||
HAKCHI_DIR := hakchi
|
||||
TARGET := retroarch
|
||||
GIT_COMMIT := $(shell echo "`git rev-parse --short HEAD``git diff-index --quiet HEAD -- || echo '-dirty'`")
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
retroarch:
|
||||
readelf -v #Check if you have readelf installed... (sudo apt-get install readelf)
|
||||
./configure --host=arm-linux-gnueabihf --disable-freetype --enable-opengles --enable-udev --enable-alsa --enable-neon --enable-floathard
|
||||
make -f Makefile -j HAVE_HAKCHI=1
|
||||
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...
|
||||
#/usr/bin/arm-linux-gnueabihf-strip retroarch
|
||||
rm -f $(HAKCHI_DIR)/bin/retroarch
|
||||
cp retroarch $(HAKCHI_DIR)/bin/retroarch
|
||||
echo $$(echo "Built by: " $$USER @ $$(date) \\\\\\ Git Commit: $(GIT_COMMIT)) > $(HAKCHI_DIR)/etc/libretro/retroarch_version
|
||||
cp $(HAKCHI_DIR)/readme.md $(HAKCHI_DIR)/readme_COPY.md
|
||||
printf "%s\n" \
|
||||
"---" \
|
||||
"Name: $(HAKCHI_VER)" \
|
||||
"Creator: $(MOD_CREATOR)" \
|
||||
"Category: $(MOD_CATEGORY)" \
|
||||
"Version: $(HAKCHI_VER)" \
|
||||
"Built on: $(shell date)" \
|
||||
"Git commit: $(GIT_COMMIT)" \
|
||||
"---" > $(HAKCHI_DIR)/readme.md
|
||||
cat $(HAKCHI_DIR)/readme_COPY.md >> $(HAKCHI_DIR)/readme.md
|
||||
rm $(HAKCHI_DIR)/readme_COPY.md
|
||||
@echo "** BUILDING HAKCHI $(HAKCHI_VER) HMOD PACKAGE **"
|
||||
cd $(HAKCHI_DIR)/; tar -czvf "$(HAKCHI_VER).hmod" *
|
||||
mv $(HAKCHI_DIR)/$(HAKCHI_VER).hmod .
|
||||
@echo "** BUILT HAKCHI $(HAKCHI_VER) HMOD PACKAGE **"
|
||||
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
|
||||
rm -f $(HAKCHI_DIR)/bin/retroarch
|
||||
rm -f $(HAKCHI_VER).hmod
|
||||
rm -f $(HAKCHI_DIR)/etc/libretro/retroarch_version
|
||||
@@ -1,4 +1,4 @@
|
||||
include version.all
|
||||
RARCH_VERSION = "0.9.9.3"
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
@@ -10,12 +10,12 @@ 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
|
||||
OBJ = griffin/griffin.o audio/resamplers/sinc_resampler_neon.o audio/audio_utils_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_ALSA -DHAVE_ZLIB -D__linux__
|
||||
DEFINES += -D__ARM_ARCH_6__ -DSINC_LOWER_QUALITY -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_GLSL -DHAVE_DYNAMIC -DWANT_RPNG -DWANT_ZLIB -DHAVE_OVERLAY -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
|
||||
|
||||
+17
-25
@@ -1,10 +1,10 @@
|
||||
include version.all
|
||||
RARCH_VERSION = "0.9.9.3"
|
||||
|
||||
#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
|
||||
CELL_PSGL_VERSION = ultra-opt
|
||||
|
||||
ASSETS_DIR := media/assets
|
||||
|
||||
@@ -15,6 +15,7 @@ DEBUG = 0
|
||||
HAVE_GCMGL = 0
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FREETYPE = 0
|
||||
HAVE_RLAUNCH = 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
|
||||
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
|
||||
@@ -33,7 +34,7 @@ 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/libz -Ilibretro-common/include -Ideps -Ideps/stb
|
||||
INCDIRS = -I. -Idefines -Ideps/zlib -Ilibretro-common/include
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
@@ -63,19 +64,11 @@ endif
|
||||
|
||||
PPU_SRCS = griffin/griffin.c
|
||||
|
||||
DEFINES += -DHAVE_MENU -DHAVE_RGUI -DHAVE_XMB -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
|
||||
ifeq ($(HAVE_RLAUNCH), 1)
|
||||
DEFINES += -DHAVE_RLAUNCH
|
||||
endif
|
||||
|
||||
ifeq ($(CEX_BUILD), 1)
|
||||
DEFINES += -DCEX_BUILD
|
||||
endif
|
||||
|
||||
ifeq ($(ODE_BUILD), 1)
|
||||
DEFINES += -DODE_BUILD
|
||||
endif
|
||||
DEFINES += -DHAVE_MENU -DHAVE_RGUI -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY
|
||||
|
||||
ifeq ($(HAVE_GCMGL), 1)
|
||||
DEFINES += -DHAVE_GCMGL
|
||||
@@ -96,7 +89,8 @@ 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)
|
||||
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
|
||||
@@ -112,14 +106,12 @@ PPU_LDLIBS = $(FONT_LIBS) $(GL_LIBS) $(WHOLE_START) -lretro_ps3 $(WHOLE_END) -l
|
||||
|
||||
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
|
||||
|
||||
#DEFINES += -DHAVE_IMAGEVIEWER
|
||||
DEFINES += -DHAVE_THREADS -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_FBO -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RSOUND -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_7Z -DWANT_ZLIB -DSINC_LOWER_QUALITY -D__CELLOS_LV2__ -DHAVE_NETPLAY=1 -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_BUILTIN_AUTOCONFIG
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
PPU_OPTIMIZE_LV := -O2 -g
|
||||
PPU_OPTIMIZE_LV := -O3 -g
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
@@ -174,20 +166,20 @@ pkg: $(PPU_TARGET) create-shaders copy-media-files create-npdrm-salamander crea
|
||||
$(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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
|
||||
clean-selfs:
|
||||
ifeq ($(EBOOT_EXISTS),1)
|
||||
|
||||
+17
-23
@@ -1,8 +1,8 @@
|
||||
include version.all
|
||||
RARCH_VERSION = "0.9.9.3"
|
||||
|
||||
#which compiler to build with - GCC or SNC
|
||||
#set to GCC for debug builds for use with debugger
|
||||
CELL_BUILD_TOOLS = GCC
|
||||
CELL_BUILD_TOOLS = SNC
|
||||
CELL_GPU_TYPE = RSX
|
||||
CELL_PSGL_VERSION = ultra-opt
|
||||
|
||||
@@ -13,6 +13,7 @@ DEBUG = 0
|
||||
HAVE_GCMGL = 1
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FREETYPE = 0
|
||||
HAVE_RLAUNCH = 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
|
||||
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
|
||||
@@ -31,7 +32,7 @@ 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
|
||||
INCDIRS = -I. -Idefines
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
@@ -61,20 +62,12 @@ endif
|
||||
|
||||
PPU_SRCS = griffin/griffin.c
|
||||
|
||||
ifeq ($(HAVE_RLAUNCH), 1)
|
||||
DEFINES += -DHAVE_RLAUNCH
|
||||
endif
|
||||
|
||||
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
|
||||
@@ -94,7 +87,8 @@ 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)
|
||||
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
|
||||
@@ -110,7 +104,7 @@ PPU_LDLIBS = $(FONT_LIBS) $(GL_LIBS) $(WHOLE_START) -lretro_ps3 $(WHOLE_END) -l
|
||||
|
||||
PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe
|
||||
|
||||
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
|
||||
DEFINES += -DHAVE_THREADS -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_HEADSET -DHAVE_OPENGLES -DHAVE_OPENGLES1 -DHAVE_PSGL -DHAVE_CG -DHAVE_CG_RUNTIME_COMPILER -DHAVE_FBO -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RSOUND -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -DSINC_LOWER_QUALITY -D__CELLOS_LV2__ -DHAVE_NETPLAY=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)
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
@@ -170,20 +164,20 @@ pkg: $(PPU_TARGET) create-shaders copy-media-files create-npdrm-salamander crea
|
||||
$(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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
|
||||
clean-selfs:
|
||||
ifeq ($(EBOOT_EXISTS),1)
|
||||
|
||||
+9
-35
@@ -1,4 +1,4 @@
|
||||
CELL_BUILD_TOOLS = GCC
|
||||
CELL_BUILD_TOOLS = SNC
|
||||
CELL_SDK ?= /usr/local/cell
|
||||
HAVE_LOGGER = 0
|
||||
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
|
||||
@@ -16,56 +16,28 @@ 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_CFLAGS += -I. -Ilibretro-common/include -Ideps/zlib -D__CELLOS_LV2__ -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_SYSUTILS -DHAVE_SYSMODULES -DHAVE_RARCH_EXEC
|
||||
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/dir_list.c \
|
||||
libretro-common/file/retro_dirent.c \
|
||||
libretro-common/file/retro_stat.c \
|
||||
libretro-common/hash/rhash.c \
|
||||
libretro-common/string/stdstring.c \
|
||||
libretro-common/encodings/encoding_utf.c \
|
||||
libretro-common/string/string_list.c \
|
||||
libretro-common/compat/compat_strl.c \
|
||||
libretro-common/compat/compat_strcasestr.c \
|
||||
libretro-common/streams/file_stream.c \
|
||||
libretro-common/vfs/vfs_implementation.c \
|
||||
libretro-common/file/retro_file.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
|
||||
PPU_SRCS += netlogger.c
|
||||
endif
|
||||
|
||||
PPU_TARGET = retroarch-salamander_ps3.elf
|
||||
@@ -85,6 +57,8 @@ endif
|
||||
|
||||
PPU_LDLIBS += -lm -lnet_stub -lnetctl_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lsysutil_game_stub -lfs_stub -lsysutil_np_stub
|
||||
|
||||
PPU_OPTIMIZE_LV := -O2
|
||||
|
||||
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
include version.all
|
||||
RARCH_VERSION = "0.9.9.3"
|
||||
|
||||
DEBUG = 0
|
||||
HAVE_LOGGER = 0
|
||||
@@ -17,7 +17,7 @@ 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
|
||||
INCLUDE := -I. -I$(PS3DEV)/ppu/include -Ideps/zlib -Ips3/gcmgl/include/export -Ips3/include
|
||||
LIBDIRS := -L$(PS3DEV)/ppu/lib -L$(PS3DEV)/portlibs/ppu/lib -L.
|
||||
|
||||
MACHDEP := -D__CELLOS_LV2__ -D__PSL1GHT__
|
||||
@@ -83,13 +83,14 @@ OBJ = griffin/griffin.o
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_LOGGER
|
||||
CFLAGS += -Ilogger/netlogger
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FILE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_FILE_LOGGER
|
||||
endif
|
||||
|
||||
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
|
||||
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_FBO -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_MOUSE -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -DHAVE_GRIFFIN=1 -DHAVE_NETPLAY=1 -DHAVE_SOCKET_LEGACY=1 -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -Wno-char-subscripts
|
||||
CFLAGS += -std=gnu99 $(SHARED_FLAGS)
|
||||
CXXFLAGS += $(SHARED_FLAGS)
|
||||
|
||||
@@ -121,7 +122,7 @@ 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
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) pkg/ps3 retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
|
||||
clean:
|
||||
rm -f $(ELF_TARGET)
|
||||
|
||||
+6
-8
@@ -1,10 +1,8 @@
|
||||
BUILD_PRX = 0
|
||||
PSP_LARGE_MEMORY = 1
|
||||
BUILD_PRX = 1
|
||||
DEBUG = 0
|
||||
HAVE_KERNEL_PRX = 1
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 0
|
||||
HAVE_THREADS = 1
|
||||
HAVE_THREADS = 0
|
||||
BIG_STACK = 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
|
||||
@@ -13,7 +11,7 @@ TARGET = retroarchpsp
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
OPTIMIZE_LV := -O3
|
||||
OPTIMIZE_LV := -O3 -g
|
||||
endif
|
||||
|
||||
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
@@ -21,11 +19,11 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
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
|
||||
CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math -fsingle-precision-constant
|
||||
INCDIR = deps/zlib deps/7zip libretro-common/include
|
||||
CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math
|
||||
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
|
||||
RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_ZLIB -DHAVE_RPNG -DWANT_ZLIB -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DWANT_RPNG -DSINC_LOWEST_QUALITY -DHAVE_BUILTIN_AUTOCONFIG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP
|
||||
|
||||
LIBDIR =
|
||||
LDFLAGS =
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
BUILD_PRX = 0
|
||||
PSP_LARGE_MEMORY = 1
|
||||
BUILD_PRX = 1
|
||||
HAVE_FILE_LOGGER = 0
|
||||
DEBUG = 0
|
||||
|
||||
@@ -8,7 +7,7 @@ TARGET = retroarchpsp_salamander
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
OPTIMIZE_LV := -O2
|
||||
OPTIMIZE_LV := -O2 -g
|
||||
endif
|
||||
|
||||
INCDIR = $(PSPPATH)/include libretro-common/include
|
||||
@@ -25,7 +24,7 @@ ifeq ($(HAVE_FILE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_FILE_LOGGER
|
||||
endif
|
||||
|
||||
CFLAGS += $(RARCH_DEFINES)
|
||||
CFLAGS += $(RARCH_DEFINES)
|
||||
|
||||
EXTRA_TARGETS = EBOOT.PBP
|
||||
PSP_EBOOT_TITLE = RetroArch
|
||||
@@ -38,17 +37,14 @@ OBJS = frontend/frontend_salamander.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/string/string_list.o \
|
||||
libretro-common/file/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/file/config_file.o \
|
||||
libretro-common/streams/file_stream.o \
|
||||
libretro-common/vfs/vfs_implementation.o \
|
||||
libretro-common/file/retro_file.o \
|
||||
libretro-common/file/retro_stat.o \
|
||||
libretro-common/hash/rhash.o \
|
||||
file_path_str.o \
|
||||
verbosity.o \
|
||||
bootstrap/psp1/kernel_functions.o
|
||||
|
||||
|
||||
@@ -1,71 +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_ZARCH = 0
|
||||
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
|
||||
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 -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
|
||||
-183
@@ -1,183 +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
|
||||
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_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
|
||||
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 -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)
|
||||
@@ -1,84 +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 -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/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."
|
||||
+7
-37
@@ -6,7 +6,6 @@
|
||||
DEBUG = 0
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 0
|
||||
EXTERNAL_LIBOGC = 0
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
@@ -30,23 +29,13 @@ 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
|
||||
INCLUDE := -I. -I$(DEVKITPRO)/libogc/include -Ilibretro-common/include -Ideps/zlib
|
||||
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
|
||||
LIBS := -lwiiuse -logc -lbte
|
||||
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
LIBS += -lfat
|
||||
endif
|
||||
LIBS := -lfat -lwiiuse -logc -lbte
|
||||
|
||||
APP_BOOTER_DIR = wii/app_booter
|
||||
|
||||
@@ -58,39 +47,20 @@ OBJ = frontend/frontend_salamander.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/string/string_list.o \
|
||||
libretro-common/file/dir_list.o \
|
||||
libretro-common/file/retro_file.o \
|
||||
libretro-common/file/retro_dirent.o \
|
||||
libretro-common/encodings/encoding_utf.o \
|
||||
libretro-common/file/retro_stat.o \
|
||||
libretro-common/compat/compat_strl.o \
|
||||
libretro-common/compat/compat_strcasestr.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
|
||||
OBJ += logger/netlogger.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FILE_LOGGER), 1)
|
||||
|
||||
-328
@@ -1,328 +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
|
||||
|
||||
OBJ :=
|
||||
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
|
||||
|
||||
DEFINES :=
|
||||
|
||||
ifeq ($(WIIU_LOG_RPX),1)
|
||||
defines += -DWIIU_LOG_RPX
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
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/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
|
||||
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
|
||||
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
|
||||
# DEFINES += -DWANT_IFADDRS
|
||||
# DEFINES += -DHAVE_FREETYPE
|
||||
DEFINES += -DHAVE_XMB -DHAVE_MATERIALUI
|
||||
else
|
||||
HAVE_MENU_COMMON = 1
|
||||
HAVE_RTGA = 1
|
||||
HAVE_RPNG = 1
|
||||
HAVE_RJPEG = 1
|
||||
HAVE_RBMP = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 0
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_STB_FONT = 1
|
||||
# HAVE_FREETYPE = 1
|
||||
HAVE_LANGEXTRA = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
# WANT_IFADDRS = 1
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
HAVE_STATIC_AUDIO_FILTERS = 1
|
||||
WANT_LIBFAT = 1
|
||||
WANT_IOSUHAX = 1
|
||||
|
||||
include Makefile.common
|
||||
BLACKLIST := $(LIBRETRO_COMM_DIR)/net/net_ifinfo.o
|
||||
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
|
||||
|
||||
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
|
||||
|
||||
OBJ += audio/drivers/wiiu_audio.o
|
||||
OBJ += frontend/drivers/platform_wiiu.o
|
||||
endif
|
||||
endif
|
||||
|
||||
OBJ := $(addprefix $(BUILD_DIR)/,$(OBJ))
|
||||
|
||||
#todo: remove -DWIIU and use the built-in macros instead (HW_WUP or __wiiu__).
|
||||
DEFINES += -DWIIU -DMSB_FIRST -D__WUT__
|
||||
#DEFINES += -D_GNU_SOURCE
|
||||
DEFINES += -DHAVE_MAIN
|
||||
DEFINES += -DRARCH_CONSOLE
|
||||
|
||||
ifneq ($(PC_DEVELOPMENT_TCP_PORT),)
|
||||
DEFINES += -DPC_DEVELOPMENT_TCP_PORT=$(PC_DEVELOPMENT_TCP_PORT)
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
INCDIRS := -I.
|
||||
INCDIRS += -Ideps
|
||||
INCDIRS += -Ideps/stb
|
||||
INCDIRS += -Ideps/libz
|
||||
INCDIRS += -Ideps/7zip
|
||||
INCDIRS += -Ilibretro-common/include
|
||||
INCDIRS += -Iinput/include
|
||||
INCDIRS += -Iwiiu
|
||||
INCDIRS += -Iwiiu/include
|
||||
INCDIRS += -I$(DEVKITPRO)/portlibs/ppc/include
|
||||
LIBDIRS := -L. -L$(DEVKITPRO)/portlibs/ppc/lib
|
||||
|
||||
CFLAGS := -mwup -mcpu=750 -meabi -mhard-float
|
||||
LDFLAGS :=
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
LDFLAGS := $(CFLAGS)
|
||||
|
||||
ASFLAGS := $(CFLAGS) -mregnames
|
||||
|
||||
CFLAGS += -ffast-math -Werror=implicit-function-declaration
|
||||
#CFLAGS += -fomit-frame-pointer -mword-relocations
|
||||
#CFLAGS += -Wall
|
||||
|
||||
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
WHOLE_START := -Wl,--whole-archive
|
||||
WHOLE_END := -Wl,--no-whole-archive
|
||||
endif
|
||||
|
||||
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
LIBS := $(WHOLE_START) -lretro_wiiu $(WHOLE_END) -lm -lpng -lz
|
||||
|
||||
ifneq ($(WANT_LIBFAT), 1)
|
||||
LIBS += -lfat
|
||||
endif
|
||||
|
||||
ifneq ($(WANT_IOSUHAX), 1)
|
||||
LIBS += -liosuhax
|
||||
endif
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
rm -f $(OBJ) $(RPX_OBJ) $(HBL_ELF_OBJ) $(TARGET).elf $(TARGET).rpx.elf $(TARGET).rpx
|
||||
rm -f $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).rpx.elf $(BUILD_DIR)/$(TARGET).rpx
|
||||
rm -f .$(TARGET).elf.last .$(TARGET).rpx.elf.last .$(TARGET).rpx.last
|
||||
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)
|
||||
+6
-5
@@ -3,10 +3,11 @@ TARGET = retroarch.exe
|
||||
HAVE_DINPUT = 1
|
||||
HAVE_XAUDIO = 1
|
||||
HAVE_DSOUND = 1
|
||||
HAVE_WASAPI = 1
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_FBO = 1
|
||||
HAVE_DYLIB = 1
|
||||
HAVE_D3D9 = 1
|
||||
HAVE_NETPLAY = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_STDIN_CMD = 1
|
||||
HAVE_COMMAND = 1
|
||||
@@ -14,11 +15,11 @@ HAVE_THREADS = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_ZLIB_DEFLATE = 1
|
||||
HAVE_PYTHON = 0
|
||||
DYNAMIC = 1
|
||||
|
||||
HAVE_XINPUT = 1
|
||||
HAVE_WINMM = 1
|
||||
|
||||
HAVE_SDL := 0
|
||||
HAVE_SDL2 := 0
|
||||
@@ -33,7 +34,6 @@ HAVE_CG := 1
|
||||
HAVE_LIBXML2 := 0
|
||||
HAVE_ZLIB := 1
|
||||
WANT_ZLIB := 1
|
||||
HAVE_CC_RESAMPLER := 1
|
||||
|
||||
ifeq ($(HAVE_CG), 1)
|
||||
CG_LIBS := -lcg -lcgGL
|
||||
@@ -120,10 +120,11 @@ ifeq ($(DEBUG), 1)
|
||||
else
|
||||
CFLAGS += -O3 -ffast-math
|
||||
CXXFLAGS += -O3 -ffast-math
|
||||
LDCXXFLAGS += -s
|
||||
endif
|
||||
|
||||
CFLAGS += -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
|
||||
CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I.
|
||||
CXXFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=c++98 -D__STDC_CONSTANT_MACROS
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
CFLAGS += -std=c++98 -xc++ -D__STDC_CONSTANT_MACROS
|
||||
else
|
||||
|
||||
@@ -18,7 +18,7 @@ So we will use
|
||||
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:
|
||||
Now we edit drivers/video/sunxi/disp/dev_fb.c, and uncoment 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:
|
||||
|
||||
@@ -1,88 +1,61 @@
|
||||
[](https://travis-ci.org/libretro/RetroArch)
|
||||
[](https://scan.coverity.com/projects/retroarch)
|
||||
|
||||
# RetroArch
|
||||
|
||||
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
|
||||
Popular examples of implementations for this API includes videogame system emulators and game engines, but also
|
||||
more generalized 3D programs.
|
||||
These programs are instantiated as dynamic libraries. We refer to these as "libretro cores".
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## libretro
|
||||
|
||||
[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.
|
||||
A libretro core written in portable C or C++ can run seamlessly on many platforms with very little/no porting effort.
|
||||
|
||||
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.
|
||||
|
||||
[libretro API header](https://github.com/libretro/RetroArch/blob/master/libretro-common/include/libretro.h)
|
||||
[libretro API header](https://github.com/libretro/RetroArch/blob/master/libretro.h)
|
||||
|
||||
## Binaries
|
||||
|
||||
Latest binaries are currently hosted on the [buildbot](http://buildbot.libretro.com/).
|
||||
Latest Windows binaries are currently hosted on the buildbot -(http://buildbot.libretro.com/).
|
||||
|
||||
## Support
|
||||
|
||||
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.
|
||||
To reach developers, either make an issue here on Github, make a thread on the [forum](http://www.libretro.com/forums/),
|
||||
or visit our IRC channel: #retroarch @ irc.freenode.org.
|
||||
|
||||
## Documentation
|
||||
|
||||
See our [Documentation Center](https://docs.libretro.com/). On Unix, man-pages are provided.
|
||||
See our [wiki](https://github.com/libretro/RetroArch/wiki). On Unix, man-pages are provided.
|
||||
More developer-centric stuff is found [here](https://github.com/libretro/libretro.github.com/wiki/Documentation-devs).
|
||||
|
||||
## Related projects
|
||||
|
||||
- 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/)
|
||||
|
||||
## Philosophy
|
||||
|
||||
RetroArch attempts to be small and lean
|
||||
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 is designed to be very portable and features a gamepad-centric UI.
|
||||
It also has a full-featured command-line interface.
|
||||
|
||||
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.
|
||||
real-time rewind (Braid-style), video recording (using FFmpeg), etc.
|
||||
|
||||
RetroArch also emphasizes being easy to integrate into various launcher frontends.
|
||||
RetroArch also emphasizes on being easy to integrate into various launcher frontends.
|
||||
|
||||
## Platforms
|
||||
|
||||
RetroArch has been ported to the following platforms:
|
||||
RetroArch has been ported to the following platforms outside PC:
|
||||
|
||||
- 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
|
||||
- PlayStation3
|
||||
- Xbox 360 (Libxenon/XeXDK)
|
||||
- Xbox 1
|
||||
- Wii, Gamecube (Libogc)
|
||||
- Nintendo 3DS
|
||||
- Nintendo Switch
|
||||
- Nintendo NES/SNES Classic Edition
|
||||
- Raspberry Pi
|
||||
- Android
|
||||
- iOS
|
||||
@@ -122,7 +95,7 @@ RetroArch needs at least one of these audio driver libraries:
|
||||
- DirectSound (Win32, Xbox 1)
|
||||
- CoreAudio (OSX, iOS)
|
||||
|
||||
To run properly, RetroArch requires a libretro implementation present; however, as it's typically loaded
|
||||
To run properly, RetroArch requires a libretro implementation present, however, as it's typically loaded
|
||||
dynamically, it's not required at build time.
|
||||
|
||||
## Dependencies (Console ports, mobile)
|
||||
@@ -132,128 +105,102 @@ anything other than what the respective SDKs provide.
|
||||
|
||||
## Configuring
|
||||
|
||||
The default configuration is defined in `config.def.h`.
|
||||
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.
|
||||
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.
|
||||
RetroArch will on startup create a config file in $XDG\_CONFIG\_HOME/retroarch/retroarch.cfg if doesn't 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.
|
||||
To configure joypads, use the built-in menu or the <tt>retroarch-joyconfig</tt> command-line tool.
|
||||
|
||||
## Compiling and installing
|
||||
<b>Linux</b><br/>
|
||||
- Prerequisites:
|
||||
```bash
|
||||
sudo apt-get install -y make git-core curl g++ pkg-config libglu1-mesa-dev freeglut3-dev mesa-common-dev libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev
|
||||
```
|
||||
- Compiling:
|
||||
```bash
|
||||
./configure
|
||||
make
|
||||
```
|
||||
|
||||
Instructions for compiling and installing RetroArch can be found in the [Libretro/RetroArch Documentation Center](https://docs.libretro.com/).
|
||||
<b>Mac</b><br/>
|
||||
- Prerequisites: [XCode](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB4QFjAA&url=https%3A%2F%2Fitunes.apple.com%2Fus%2Fapp%2Fxcode%2Fid497799835%3Fmt%3D12&ei=ZmfeVNPtIILVoASBnoCYBw&usg=AFQjCNGrxKmVtXUdvUU3MhqZhP4MHT6Gtg&sig2=RIXKsWQ79YTQBt_lK5fdKA&bvm=bv.85970519,d.cGU), [Cg](https://developer.nvidia.com/cg-toolkit-download).
|
||||
- You can open the project (**pkg/apple/RetroArch.xcodeproj**) in the Xcode IDE and build (**⌘-B**) and run (**⌘-R**) it there. Or you can use the command line...
|
||||
- Debug:
|
||||
```bash
|
||||
# Build
|
||||
xcodebuild -target RetroArch -configuration Debug -project pkg/apple/RetroArch.xcodeproj
|
||||
# Run
|
||||
open ./pkg/apple/build/Debug/RetroArch.app/
|
||||
```
|
||||
- Release:
|
||||
```bash
|
||||
# Build
|
||||
xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
|
||||
# Run
|
||||
open ./pkg/apple/build/Release/RetroArch.app/
|
||||
```
|
||||
|
||||
## CRT 15Khz Resolution Switching
|
||||
<b>PC</b><br/>
|
||||
Instructions for compiling on PC can be found in the [wiki](https://github.com/Themaister/RetroArch/wiki).
|
||||
|
||||
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.
|
||||
<b>PlayStation3</b><br/>
|
||||
|
||||
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:
|
||||
RetroArch PS3 needs to be compiled in the following order:
|
||||
|
||||
- 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
|
||||
1) Compile RetroArch Salamander
|
||||
|
||||
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:
|
||||
<tt>make -f Makefile.ps3.salamander</tt>
|
||||
|
||||
- 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
|
||||
2) Finally, compile RetroArch packed together with the GUI:
|
||||
|
||||
Some games will require higher PAL resolutions which should also be installed:
|
||||
<tt>make -f Makefile.ps3</tt>
|
||||
|
||||
- 2560 x 512 @ 50.000000
|
||||
- 2560 x 576 @ 50.000000
|
||||
<b>PlayStation3 - Creating a PKG installable file</b><br />
|
||||
|
||||
Ideally install all these modelines and everything will work great.
|
||||
You can add `pkg` as a parameter in order to make a PKG file - for example:
|
||||
|
||||
## Super Resolutions
|
||||
<tt>make -f Makefile.ps3 pkg</tt>
|
||||
|
||||
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.
|
||||
This creates an NPDRM package. This can be installed on debug PS3s.
|
||||
|
||||
## Native Resolutions
|
||||
To make a non-NPDRM package that can be installed on a jailbroken/CFW PS3 (such as PSGroove or PS3 CFWs and other 3.55 CFW derivatives), do:
|
||||
|
||||
If native resolutions are activated you will need a whole new set of modelines:
|
||||
<tt>make -f Makefile.ps3 pkg-signed</tt>
|
||||
|
||||
- 512 x 240 @ 50.006977 SNESpal
|
||||
- 512 x 224 @ 50.006977 SNESpal
|
||||
- 512 x 448 @ 50.006977 SNESpal
|
||||
- 512 x 240 @ 60.098812 SNESntsc
|
||||
- 512 x 224 @ 60.098812 SNESntsc
|
||||
- 512 x 448 @ 60.098812 SNESntsc
|
||||
- 256 x 240 @ 50.006977 SNESpal
|
||||
- 256 x 448 @ 50.006977 SNESpal
|
||||
- 256 x 240 @ 60.098812 SNESntsc
|
||||
- 256 x 448 @ 60.098812 SNESntsc
|
||||
- 320 x 240 @ 59.922745 MDntsc
|
||||
- 320 x 448 @ 59.922745 MDntp
|
||||
- 320 x 480 @ 59.922745 MDntsc
|
||||
- 256 x 192 @ 59.922745 MDntsc
|
||||
- 320 x 224 @ 59.922745 MDntsc
|
||||
- 256 x 224 @ 59.922745 MDntsc
|
||||
- 320 x 288 @ 49.701458 MDpal
|
||||
- 320 x 576 @ 49.701458 MDpal
|
||||
- 256 x 192 @ 49.701458 MDpal
|
||||
- 320 x 224 @ 49.701458 MDpal
|
||||
- 320 x 240 @ 49.701458 MDpal
|
||||
- 320 x 448 @ 49.701458 MDpal
|
||||
- 320 x 480 @ 49.701458 MDpal
|
||||
- 256 x 224 @ 49.701458 MDpal
|
||||
- 256 x 288 @ 49.701458 MSYSpal
|
||||
- 256 x 240 @ 60.098812 NESntsc
|
||||
- 256 x 240 @ 50.006977 NESpal
|
||||
If you're using Kmeaw 3.55 firmware, the package needs to be signed:
|
||||
|
||||
- 640 x 480 @ 60.130001 N64ntsc
|
||||
- 640 x 237 @ 60.130001 N64ntsc
|
||||
- 640 x 240 @ 60.130001 N64ntsc
|
||||
- 640 x 480 @ 50.000000 N64pal
|
||||
- 640 x 576 @ 50.000000 n64pal
|
||||
- 640 x 288 @ 50.000000 n64pal
|
||||
<tt>make -f Makefile.ps3 pkg-signed-cfw</tt>
|
||||
|
||||
- 256 x 252 @ 49.759998 PSXpal
|
||||
- 384 x 252 @ 49.759998 PSXpal
|
||||
- 640 x 540 @ 49.759998 PSXpal
|
||||
- 320 x 252 @ 49.759998 PSXpal
|
||||
- 640 x 252 @ 49.759998 PSXpal
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch PS3. This file needs to be called <em><b>`libretro_ps3.a`</b></em>.
|
||||
|
||||
- 384 x 240 @ 59.941002 PSXntsc
|
||||
- 256 x 480 @ 59.941002 PSXntsc
|
||||
<b> Xbox 360 (XeXDK)</b><br />
|
||||
|
||||
- 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
|
||||
You will need Microsoft Visual Studio 2010 installed (or higher) in order to compile RetroArch 360.
|
||||
|
||||
- 240 x 160 @ 59.730000 GBA
|
||||
- 320 x 200 @ 60.000000 Doom
|
||||
The solution file can be found at the following location:
|
||||
|
||||
// Arcade
|
||||
<tt>pkg/msvc-360/RetroArch-360.sln</tt>
|
||||
|
||||
- 400 x 254 @ 54.706841 MK
|
||||
- 384 x 224 @ 59.637405 CPS1
|
||||
NOTE: A pre-existing libretro library needs to be present in the `pkg/msvc-360/RetroArch-360/Release` directory in order to link RetroArch 360. This file needs to be
|
||||
called <em><b>`libretro_xdk360.lib`</b></em>.
|
||||
|
||||
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.
|
||||
<b> Xbox 360 (Libxenon)</b><br />
|
||||
|
||||
## CRT resolution switching & MAME
|
||||
You will need to have the libxenon libraries and a working Devkit Xenon toolchain installed in order to compile RetroArch 360 Libxenon.
|
||||
|
||||
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.
|
||||
<tt>make -f Makefile.xenon</tt>
|
||||
|
||||
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.
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch 360 Libxenon. This file needs to be called <em><b>`libretro_xenon360.a`</b></em>.
|
||||
|
||||
<b> Wii</b><br >
|
||||
|
||||
You will need to have the libogc libraries and a working Devkit PPC toolchain installed in order to compile RetroArch Wii.
|
||||
|
||||
<tt>make -f Makefile.griffin platform=wii</tt>
|
||||
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch Wii. This file needs to be called <em><b>`libretro_wii.a`</b></em>.
|
||||
+475
-1164
File diff suppressed because it is too large.
Load diff
+50
-214
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -20,72 +20,54 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <audio/audio_mixer.h>
|
||||
#include <audio/audio_resampler.h>
|
||||
#include <retro_common_api.h>
|
||||
#include "audio_dsp_filter.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
enum audio_action
|
||||
enum rarch_audio_ctl_state
|
||||
{
|
||||
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
|
||||
RARCH_AUDIO_CTL_NONE = 0,
|
||||
RARCH_AUDIO_CTL_INIT,
|
||||
RARCH_AUDIO_CTL_DEINIT,
|
||||
RARCH_AUDIO_CTL_DESTROY,
|
||||
RARCH_AUDIO_CTL_DESTROY_DATA,
|
||||
RARCH_AUDIO_CTL_START,
|
||||
RARCH_AUDIO_CTL_STOP,
|
||||
RARCH_AUDIO_CTL_FIND_DRIVER,
|
||||
RARCH_AUDIO_CTL_SETUP_REWIND,
|
||||
/* Sets audio monitor refresh rate to new value. */
|
||||
RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE,
|
||||
RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES,
|
||||
RARCH_AUDIO_CTL_MUTE_TOGGLE,
|
||||
RARCH_AUDIO_CTL_SET_CALLBACK_ENABLE,
|
||||
RARCH_AUDIO_CTL_SET_CALLBACK_DISABLE,
|
||||
RARCH_AUDIO_CTL_SET_CALLBACK,
|
||||
RARCH_AUDIO_CTL_UNSET_CALLBACK,
|
||||
RARCH_AUDIO_CTL_CALLBACK,
|
||||
RARCH_AUDIO_CTL_HAS_CALLBACK,
|
||||
RARCH_AUDIO_CTL_ALIVE,
|
||||
RARCH_AUDIO_CTL_FRAME_IS_REVERSE,
|
||||
RARCH_AUDIO_CTL_SET_OWN_DRIVER,
|
||||
RARCH_AUDIO_CTL_UNSET_OWN_DRIVER,
|
||||
RARCH_AUDIO_CTL_OWNS_DRIVER,
|
||||
RARCH_AUDIO_CTL_SET_ACTIVE,
|
||||
RARCH_AUDIO_CTL_UNSET_ACTIVE,
|
||||
RARCH_AUDIO_CTL_IS_ACTIVE,
|
||||
RARCH_AUDIO_CTL_RESAMPLER_DEINIT,
|
||||
RARCH_AUDIO_CTL_RESAMPLER_INIT,
|
||||
RARCH_AUDIO_CTL_RESAMPLER_PROCESS
|
||||
};
|
||||
|
||||
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_mixer_stream
|
||||
{
|
||||
audio_mixer_sound_t *handle;
|
||||
audio_mixer_voice_t *voice;
|
||||
audio_mixer_stop_cb_t stop_cb;
|
||||
enum audio_mixer_state state;
|
||||
float volume;
|
||||
void *buf;
|
||||
char *name;
|
||||
size_t bufsize;
|
||||
} audio_mixer_stream_t;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct audio_driver
|
||||
{
|
||||
/* Creates and initializes handle to audio driver.
|
||||
*
|
||||
* Returns: audio driver handle on success, otherwise NULL.
|
||||
**/
|
||||
void *(*init)(const char *device, unsigned rate,
|
||||
unsigned latency, unsigned block_frames, unsigned *new_rate);
|
||||
void *(*init)(const char *device, unsigned rate, unsigned latency);
|
||||
|
||||
/*
|
||||
* @data : Pointer to audio data handle.
|
||||
@@ -93,111 +75,39 @@ typedef struct audio_driver
|
||||
* @size : Size of audio buffer.
|
||||
*
|
||||
* Write samples to audio driver.
|
||||
*
|
||||
* Write data in buffer to audio driver.
|
||||
* A frame here is defined as one combined sample of left and right
|
||||
* channels. (I.e. 44.1kHz, 16-bit stereo has 88.2k samples/s, and
|
||||
* 44.1k frames/s.)
|
||||
*
|
||||
* Samples are interleaved in format LRLRLRLRLR ...
|
||||
* If the driver returns true in use_float(), a floating point
|
||||
* format will be used, with range [-1.0, 1.0].
|
||||
* If not, signed 16-bit samples in native byte ordering will be used.
|
||||
*
|
||||
* This function returns the number of frames successfully written.
|
||||
* If an error occurs, -1 should be returned.
|
||||
* Note that non-blocking behavior that cannot write at this time
|
||||
* should return 0 as returning -1 will terminate the driver.
|
||||
*
|
||||
* Unless said otherwise with set_nonblock_state(), all writes
|
||||
* are blocking, and it should block till it has written all frames.
|
||||
*/
|
||||
**/
|
||||
ssize_t (*write)(void *data, const void *buf, size_t size);
|
||||
|
||||
/* Temporarily pauses the audio driver. */
|
||||
/* Stops driver. */
|
||||
bool (*stop)(void *data);
|
||||
|
||||
/* Resumes audio driver from the paused state. */
|
||||
bool (*start)(void *data, bool is_shutdown);
|
||||
/* Starts driver. */
|
||||
bool (*start)(void *data);
|
||||
|
||||
/* Is the audio driver currently running? */
|
||||
bool (*alive)(void *data);
|
||||
|
||||
/* Should we care about blocking in audio thread? Fast forwarding.
|
||||
*
|
||||
* If state is true, nonblocking operation is assumed.
|
||||
* This is typically used for fast-forwarding. If driver cannot
|
||||
* implement nonblocking writes, this can be disregarded, but should
|
||||
* log a message to stderr.
|
||||
* */
|
||||
/* Should we care about blocking in audio thread? Fast forwarding. */
|
||||
void (*set_nonblock_state)(void *data, bool toggle);
|
||||
|
||||
/* Stops and frees driver data. */
|
||||
/* Frees driver data. */
|
||||
void (*free)(void *data);
|
||||
|
||||
/* Defines if driver will take standard floating point samples,
|
||||
* or int16_t samples.
|
||||
*
|
||||
* If true is returned, the audio driver is capable of using
|
||||
* floating point data. This will likely increase performance as the
|
||||
* resampler unit uses floating point. The sample range is
|
||||
* [-1.0, 1.0].
|
||||
* */
|
||||
* or int16_t samples. */
|
||||
bool (*use_float)(void *data);
|
||||
|
||||
/* Human-readable identifier. */
|
||||
const char *ident;
|
||||
|
||||
/* Optional. Get audio device list (allocates, caller has to free this) */
|
||||
void *(*device_list_new)(void *data);
|
||||
|
||||
/* Optional. Frees audio device list */
|
||||
void (*device_list_free)(void *data, void *data2);
|
||||
|
||||
/* Optional. */
|
||||
size_t (*write_avail)(void *data);
|
||||
|
||||
size_t (*buffer_size)(void *data);
|
||||
} audio_driver_t;
|
||||
|
||||
typedef struct audio_mixer_stream_params
|
||||
{
|
||||
float volume;
|
||||
enum audio_mixer_type type;
|
||||
enum audio_mixer_state state;
|
||||
void *buf;
|
||||
char *basename;
|
||||
size_t bufsize;
|
||||
audio_mixer_stop_cb_t cb;
|
||||
} audio_mixer_stream_params_t;
|
||||
|
||||
void audio_driver_destroy_data(void);
|
||||
|
||||
void audio_driver_set_own_driver(void);
|
||||
|
||||
void audio_driver_unset_own_driver(void);
|
||||
|
||||
void audio_driver_suspend(void);
|
||||
|
||||
bool audio_driver_is_suspended(void);
|
||||
|
||||
void audio_driver_resume(void);
|
||||
|
||||
void audio_driver_set_active(void);
|
||||
|
||||
bool audio_driver_is_active(void);
|
||||
|
||||
void audio_driver_destroy(void);
|
||||
|
||||
void audio_driver_deinit_resampler(void);
|
||||
|
||||
bool audio_driver_free_devices_list(void);
|
||||
|
||||
bool audio_driver_new_devices_list(void);
|
||||
|
||||
bool audio_driver_enable_callback(void);
|
||||
|
||||
bool audio_driver_disable_callback(void);
|
||||
bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data);
|
||||
|
||||
/**
|
||||
* audio_driver_find_handle:
|
||||
@@ -236,7 +146,7 @@ void audio_driver_sample_rewind(int16_t left, int16_t right);
|
||||
|
||||
size_t audio_driver_sample_batch_rewind(const int16_t *data, size_t frames);
|
||||
|
||||
bool audio_driver_mixer_extension_supported(const char *ext);
|
||||
void audio_driver_set_volume_gain(float gain);
|
||||
|
||||
void audio_driver_dsp_filter_free(void);
|
||||
|
||||
@@ -244,82 +154,10 @@ void audio_driver_dsp_filter_init(const char *device);
|
||||
|
||||
void audio_driver_set_buffer_size(size_t bufsize);
|
||||
|
||||
bool audio_driver_get_devices_list(void **ptr);
|
||||
|
||||
void audio_driver_setup_rewind(void);
|
||||
|
||||
void audio_driver_monitor_adjust_system_rates(void);
|
||||
|
||||
bool audio_driver_set_callback(const void *data);
|
||||
|
||||
bool audio_driver_callback(void);
|
||||
|
||||
bool audio_driver_has_callback(void);
|
||||
|
||||
/* Sets audio monitor rate to new value. */
|
||||
void audio_driver_monitor_set_rate(void);
|
||||
|
||||
bool audio_driver_find_driver(void);
|
||||
|
||||
bool audio_driver_toggle_mute(void);
|
||||
|
||||
bool audio_driver_start(bool is_shutdown);
|
||||
|
||||
bool audio_driver_stop(void);
|
||||
|
||||
bool audio_driver_owns_driver(void);
|
||||
|
||||
void audio_driver_unset_callback(void);
|
||||
|
||||
void audio_driver_frame_is_reverse(void);
|
||||
|
||||
void audio_set_float(enum audio_action action, float val);
|
||||
|
||||
void audio_set_bool(enum audio_action action, bool val);
|
||||
|
||||
void audio_unset_bool(enum audio_action action, bool val);
|
||||
|
||||
float *audio_get_float_ptr(enum audio_action action);
|
||||
|
||||
bool *audio_get_bool_ptr(enum audio_action action);
|
||||
|
||||
bool audio_driver_deinit(void);
|
||||
|
||||
bool audio_driver_init(void);
|
||||
|
||||
void audio_driver_menu_sample(void);
|
||||
|
||||
audio_mixer_stream_t *audio_driver_mixer_get_stream(unsigned i);
|
||||
|
||||
bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params);
|
||||
|
||||
void audio_driver_mixer_play_stream(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_sequential(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_looped(unsigned i);
|
||||
|
||||
void audio_driver_mixer_stop_stream(unsigned i);
|
||||
|
||||
float audio_driver_mixer_get_stream_volume(unsigned i);
|
||||
|
||||
void audio_driver_mixer_set_stream_volume(unsigned i, float vol);
|
||||
|
||||
void audio_driver_mixer_remove_stream(unsigned i);
|
||||
|
||||
enum resampler_quality audio_driver_get_resampler_quality(void);
|
||||
|
||||
enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i);
|
||||
|
||||
const char *audio_driver_mixer_get_stream_name(unsigned i);
|
||||
|
||||
bool compute_audio_buffer_statistics(audio_statistics_t *stats);
|
||||
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_oss;
|
||||
extern audio_driver_t audio_alsa;
|
||||
extern audio_driver_t audio_alsathread;
|
||||
extern audio_driver_t audio_tinyalsa;
|
||||
extern audio_driver_t audio_roar;
|
||||
extern audio_driver_t audio_openal;
|
||||
extern audio_driver_t audio_opensl;
|
||||
@@ -328,20 +166,18 @@ extern audio_driver_t audio_sdl;
|
||||
extern audio_driver_t audio_xa;
|
||||
extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_wasapi;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
extern audio_driver_t audio_ax;
|
||||
extern audio_driver_t audio_psp;
|
||||
extern audio_driver_t audio_ctr_csnd;
|
||||
extern audio_driver_t audio_ctr_dsp;
|
||||
extern audio_driver_t audio_switch;
|
||||
extern audio_driver_t audio_switch_thread;
|
||||
extern audio_driver_t audio_rwebaudio;
|
||||
extern audio_driver_t audio_null;
|
||||
|
||||
RETRO_END_DECLS
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,323 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <compat/posix_string.h>
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
#include <file/file_path.h>
|
||||
#include <file/config_file_userdata.h>
|
||||
#include <file/dir_list.h>
|
||||
|
||||
#include "audio_dsp_filter.h"
|
||||
#include "audio_filters/dspfilter.h"
|
||||
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "../performance.h"
|
||||
#include "../dynamic.h"
|
||||
|
||||
struct rarch_dsp_plug
|
||||
{
|
||||
#ifdef HAVE_DYLIB
|
||||
dylib_t lib;
|
||||
#endif
|
||||
const struct dspfilter_implementation *impl;
|
||||
};
|
||||
|
||||
struct rarch_dsp_instance
|
||||
{
|
||||
const struct dspfilter_implementation *impl;
|
||||
void *impl_data;
|
||||
};
|
||||
|
||||
struct rarch_dsp_filter
|
||||
{
|
||||
config_file_t *conf;
|
||||
|
||||
struct rarch_dsp_plug *plugs;
|
||||
unsigned num_plugs;
|
||||
|
||||
struct rarch_dsp_instance *instances;
|
||||
unsigned num_instances;
|
||||
};
|
||||
|
||||
static const struct dspfilter_implementation *find_implementation(
|
||||
rarch_dsp_filter_t *dsp, const char *ident)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < dsp->num_plugs; i++)
|
||||
{
|
||||
if (!strcmp(dsp->plugs[i].impl->short_ident, ident))
|
||||
return dsp->plugs[i].impl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct dspfilter_config dspfilter_config = {
|
||||
config_userdata_get_float,
|
||||
config_userdata_get_int,
|
||||
config_userdata_get_float_array,
|
||||
config_userdata_get_int_array,
|
||||
config_userdata_get_string,
|
||||
config_userdata_free,
|
||||
};
|
||||
|
||||
static bool create_filter_graph(rarch_dsp_filter_t *dsp, float sample_rate)
|
||||
{
|
||||
unsigned i, filters = 0;
|
||||
|
||||
if (!config_get_uint(dsp->conf, "filters", &filters))
|
||||
return false;
|
||||
|
||||
dsp->instances = (struct rarch_dsp_instance*)
|
||||
calloc(filters, sizeof(*dsp->instances));
|
||||
if (!dsp->instances)
|
||||
return false;
|
||||
|
||||
dsp->num_instances = filters;
|
||||
|
||||
for (i = 0; i < filters; i++)
|
||||
{
|
||||
struct config_file_userdata userdata;
|
||||
struct dspfilter_info info;
|
||||
char key[64] = {0};
|
||||
char name[64] = {0};
|
||||
|
||||
info.input_rate = sample_rate;
|
||||
|
||||
snprintf(key, sizeof(key), "filter%u", i);
|
||||
|
||||
if (!config_get_array(dsp->conf, key, name, sizeof(name)))
|
||||
return false;
|
||||
|
||||
dsp->instances[i].impl = find_implementation(dsp, name);
|
||||
if (!dsp->instances[i].impl)
|
||||
return false;
|
||||
|
||||
userdata.conf = dsp->conf;
|
||||
/* Index-specific configs take priority over ident-specific. */
|
||||
userdata.prefix[0] = key;
|
||||
userdata.prefix[1] = dsp->instances[i].impl->short_ident;
|
||||
|
||||
dsp->instances[i].impl_data = dsp->instances[i].impl->init(&info, &dspfilter_config, &userdata);
|
||||
if (!dsp->instances[i].impl_data)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(HAVE_FILTERS_BUILTIN)
|
||||
extern const struct dspfilter_implementation *panning_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *iir_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *echo_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *phaser_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *wahwah_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *eq_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
extern const struct dspfilter_implementation *chorus_dspfilter_get_implementation(dspfilter_simd_mask_t mask);
|
||||
|
||||
static const dspfilter_get_implementation_t dsp_plugs_builtin[] = {
|
||||
panning_dspfilter_get_implementation,
|
||||
iir_dspfilter_get_implementation,
|
||||
echo_dspfilter_get_implementation,
|
||||
phaser_dspfilter_get_implementation,
|
||||
wahwah_dspfilter_get_implementation,
|
||||
eq_dspfilter_get_implementation,
|
||||
chorus_dspfilter_get_implementation,
|
||||
};
|
||||
|
||||
static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
|
||||
{
|
||||
unsigned i;
|
||||
dspfilter_simd_mask_t mask = retro_get_cpu_features();
|
||||
|
||||
(void)list;
|
||||
|
||||
dsp->plugs = (struct rarch_dsp_plug*)
|
||||
calloc(ARRAY_SIZE(dsp_plugs_builtin), sizeof(*dsp->plugs));
|
||||
if (!dsp->plugs)
|
||||
return false;
|
||||
|
||||
dsp->num_plugs = ARRAY_SIZE(dsp_plugs_builtin);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dsp_plugs_builtin); i++)
|
||||
{
|
||||
dsp->plugs[i].impl = dsp_plugs_builtin[i](mask);
|
||||
if (!dsp->plugs[i].impl)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#elif defined(HAVE_DYLIB)
|
||||
static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
|
||||
{
|
||||
unsigned i;
|
||||
dspfilter_simd_mask_t mask = retro_get_cpu_features();
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const struct dspfilter_implementation *impl = NULL;
|
||||
struct rarch_dsp_plug *new_plugs = NULL;
|
||||
dylib_t lib = dylib_load(list->elems[i].data);
|
||||
dspfilter_get_implementation_t cb;
|
||||
|
||||
if (!lib)
|
||||
continue;
|
||||
|
||||
cb = (dspfilter_get_implementation_t)dylib_proc(lib, "dspfilter_get_implementation");
|
||||
if (!cb)
|
||||
{
|
||||
dylib_close(lib);
|
||||
continue;
|
||||
}
|
||||
|
||||
impl = cb(mask);
|
||||
if (!impl)
|
||||
{
|
||||
dylib_close(lib);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (impl->api_version != DSPFILTER_API_VERSION)
|
||||
{
|
||||
dylib_close(lib);
|
||||
continue;
|
||||
}
|
||||
|
||||
new_plugs = (struct rarch_dsp_plug*)
|
||||
realloc(dsp->plugs, sizeof(*dsp->plugs) * (dsp->num_plugs + 1));
|
||||
if (!new_plugs)
|
||||
{
|
||||
dylib_close(lib);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Found plug. */
|
||||
|
||||
dsp->plugs = new_plugs;
|
||||
dsp->plugs[dsp->num_plugs].lib = lib;
|
||||
dsp->plugs[dsp->num_plugs].impl = impl;
|
||||
dsp->num_plugs++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
rarch_dsp_filter_t *rarch_dsp_filter_new(
|
||||
const char *filter_config, float sample_rate)
|
||||
{
|
||||
#if !defined(HAVE_FILTERS_BUILTIN) && defined(HAVE_DYLIB)
|
||||
char basedir[PATH_MAX_LENGTH];
|
||||
char ext_name[PATH_MAX_LENGTH];
|
||||
#endif
|
||||
struct string_list *plugs = NULL;
|
||||
rarch_dsp_filter_t *dsp = NULL;
|
||||
|
||||
dsp = (rarch_dsp_filter_t*)calloc(1, sizeof(*dsp));
|
||||
if (!dsp)
|
||||
return NULL;
|
||||
|
||||
dsp->conf = config_file_new(filter_config);
|
||||
if (!dsp->conf) /* Did not find config. */
|
||||
goto error;
|
||||
|
||||
#if !defined(HAVE_FILTERS_BUILTIN) && defined(HAVE_DYLIB)
|
||||
fill_pathname_basedir(basedir, filter_config, sizeof(basedir));
|
||||
|
||||
if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name)))
|
||||
goto error;
|
||||
|
||||
plugs = dir_list_new(basedir, ext_name, false, false);
|
||||
if (!plugs)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYLIB) || defined(HAVE_FILTERS_BUILTIN)
|
||||
if (!append_plugs(dsp, plugs))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
if (plugs)
|
||||
string_list_free(plugs);
|
||||
plugs = NULL;
|
||||
|
||||
if (!create_filter_graph(dsp, sample_rate))
|
||||
goto error;
|
||||
|
||||
return dsp;
|
||||
|
||||
error:
|
||||
if (plugs)
|
||||
string_list_free(plugs);
|
||||
rarch_dsp_filter_free(dsp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rarch_dsp_filter_free(rarch_dsp_filter_t *dsp)
|
||||
{
|
||||
unsigned i;
|
||||
if (!dsp)
|
||||
return;
|
||||
|
||||
for (i = 0; i < dsp->num_instances; i++)
|
||||
{
|
||||
if (dsp->instances[i].impl_data && dsp->instances[i].impl)
|
||||
dsp->instances[i].impl->free(dsp->instances[i].impl_data);
|
||||
}
|
||||
free(dsp->instances);
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
for (i = 0; i < dsp->num_plugs; i++)
|
||||
{
|
||||
if (dsp->plugs[i].lib)
|
||||
dylib_close(dsp->plugs[i].lib);
|
||||
}
|
||||
free(dsp->plugs);
|
||||
#endif
|
||||
|
||||
if (dsp->conf)
|
||||
config_file_free(dsp->conf);
|
||||
|
||||
free(dsp);
|
||||
}
|
||||
|
||||
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp,
|
||||
struct rarch_dsp_data *data)
|
||||
{
|
||||
unsigned i;
|
||||
struct dspfilter_output output = {0};
|
||||
struct dspfilter_input input = {0};
|
||||
|
||||
output.samples = data->input;
|
||||
output.frames = data->input_frames;
|
||||
|
||||
for (i = 0; i < dsp->num_instances; i++)
|
||||
{
|
||||
input.samples = output.samples;
|
||||
input.frames = output.frames;
|
||||
dsp->instances[i].impl->process(
|
||||
dsp->instances[i].impl_data, &output, &input);
|
||||
}
|
||||
|
||||
data->output = output.samples;
|
||||
data->output_frames = output.frames;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* 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 __AUDIO_DSP_FILTER_H__
|
||||
#define __AUDIO_DSP_FILTER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct rarch_dsp_filter rarch_dsp_filter_t;
|
||||
|
||||
rarch_dsp_filter_t *rarch_dsp_filter_new(const char *filter_config,
|
||||
float sample_rate);
|
||||
|
||||
void rarch_dsp_filter_free(rarch_dsp_filter_t *dsp);
|
||||
|
||||
struct rarch_dsp_data
|
||||
{
|
||||
float *input;
|
||||
unsigned input_frames;
|
||||
|
||||
/* Set by rarch_dsp_filter_process(). */
|
||||
float *output;
|
||||
unsigned output_frames;
|
||||
};
|
||||
|
||||
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp,
|
||||
struct rarch_dsp_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,91 @@
|
||||
compiler := gcc
|
||||
extra_flags :=
|
||||
use_neon := 0
|
||||
build = release
|
||||
DYLIB := so
|
||||
|
||||
ifeq ($(platform),)
|
||||
platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
platform = win
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
platform = osx
|
||||
arch = intel
|
||||
ifeq ($(shell uname -p),powerpc)
|
||||
arch = ppc
|
||||
endif
|
||||
else ifneq ($(findstring win,$(shell uname -a)),)
|
||||
platform = win
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(platform),gcc)
|
||||
extra_rules_gcc := $(shell $(compiler) -dumpmachine)
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring armv7,$(extra_rules_gcc)))
|
||||
extra_flags += -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon
|
||||
use_neon := 1
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring hardfloat,$(extra_rules_gcc)))
|
||||
extra_flags += -mfloat-abi=hard
|
||||
endif
|
||||
|
||||
ifeq (release,$(build))
|
||||
extra_flags += -O2
|
||||
endif
|
||||
|
||||
ifeq (debug,$(build))
|
||||
extra_flags += -O0 -g
|
||||
endif
|
||||
|
||||
ldflags := $(LDFLAGS) -shared -lm -Wl,--version-script=link.T
|
||||
|
||||
ifeq ($(platform), unix)
|
||||
DYLIB = so
|
||||
else ifeq ($(platform), osx)
|
||||
compiler := $(CC)
|
||||
DYLIB = dylib
|
||||
ldflags := -dynamiclib
|
||||
else
|
||||
extra_flags += -static-libgcc -static-libstdc++
|
||||
DYLIB = dll
|
||||
endif
|
||||
|
||||
CC := $(compiler) -Wall
|
||||
CXX := $(subst CC,++,$(compiler)) -std=gnu++0x -Wall
|
||||
flags := $(CFLAGS) -fPIC $(extra_flags) -I../../libretro-common/include
|
||||
asflags := $(ASFLAGS) -fPIC $(extra_flags)
|
||||
objects :=
|
||||
|
||||
ifeq (1,$(use_neon))
|
||||
ASMFLAGS := -INEON/asm
|
||||
asflags += -mfpu=neon
|
||||
endif
|
||||
|
||||
plugs := $(wildcard *.c)
|
||||
objects := $(plugs:.c=.o)
|
||||
targets := $(objects:.o=.$(DYLIB))
|
||||
|
||||
all: build;
|
||||
|
||||
%.o: %.S
|
||||
$(CC) -c -o $@ $(asflags) $(ASMFLAGS) $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $(flags) $<
|
||||
|
||||
%.$(DYLIB): %.o
|
||||
$(CC) -o $@ $(ldflags) $(flags) $^
|
||||
|
||||
build: $(targets)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.$(DYLIB)
|
||||
|
||||
strip:
|
||||
strip -s *.$(DYLIB)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,148 @@
|
||||
/* 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 "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#define CHORUS_MAX_DELAY 4096
|
||||
#define CHORUS_DELAY_MASK (CHORUS_MAX_DELAY - 1)
|
||||
|
||||
struct chorus_data
|
||||
{
|
||||
float old[2][CHORUS_MAX_DELAY];
|
||||
unsigned old_ptr;
|
||||
|
||||
float delay;
|
||||
float depth;
|
||||
float input_rate;
|
||||
float mix_dry;
|
||||
float mix_wet;
|
||||
unsigned lfo_ptr;
|
||||
unsigned lfo_period;
|
||||
};
|
||||
|
||||
static void chorus_free(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void chorus_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i;
|
||||
struct chorus_data *ch = (struct chorus_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
float *out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
unsigned delay_int;
|
||||
float delay_frac, l_a, l_b, r_a, r_b;
|
||||
float chorus_l, chorus_r;
|
||||
float in[2] = { out[0], out[1] };
|
||||
float delay = ch->delay + ch->depth * sin((2.0 * M_PI * ch->lfo_ptr++) / ch->lfo_period);
|
||||
|
||||
delay *= ch->input_rate;
|
||||
if (ch->lfo_ptr >= ch->lfo_period)
|
||||
ch->lfo_ptr = 0;
|
||||
|
||||
delay_int = (unsigned)delay;
|
||||
if (delay_int >= CHORUS_MAX_DELAY - 1)
|
||||
delay_int = CHORUS_MAX_DELAY - 2;
|
||||
delay_frac = delay - delay_int;
|
||||
|
||||
ch->old[0][ch->old_ptr] = in[0];
|
||||
ch->old[1][ch->old_ptr] = in[1];
|
||||
|
||||
l_a = ch->old[0][(ch->old_ptr - delay_int - 0) & CHORUS_DELAY_MASK];
|
||||
l_b = ch->old[0][(ch->old_ptr - delay_int - 1) & CHORUS_DELAY_MASK];
|
||||
r_a = ch->old[1][(ch->old_ptr - delay_int - 0) & CHORUS_DELAY_MASK];
|
||||
r_b = ch->old[1][(ch->old_ptr - delay_int - 1) & CHORUS_DELAY_MASK];
|
||||
|
||||
/* Lerp introduces aliasing of the chorus component, but doing full polyphase here is probably overkill. */
|
||||
chorus_l = l_a * (1.0f - delay_frac) + l_b * delay_frac;
|
||||
chorus_r = r_a * (1.0f - delay_frac) + r_b * delay_frac;
|
||||
|
||||
out[0] = ch->mix_dry * in[0] + ch->mix_wet * chorus_l;
|
||||
out[1] = ch->mix_dry * in[1] + ch->mix_wet * chorus_r;
|
||||
|
||||
ch->old_ptr = (ch->old_ptr + 1) & CHORUS_DELAY_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
static void *chorus_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
float delay, depth, lfo_freq, drywet;
|
||||
struct chorus_data *ch = (struct chorus_data*)calloc(1, sizeof(*ch));
|
||||
if (!ch)
|
||||
return NULL;
|
||||
|
||||
config->get_float(userdata, "delay_ms", &delay, 25.0f);
|
||||
config->get_float(userdata, "depth_ms", &depth, 1.0f);
|
||||
config->get_float(userdata, "lfo_freq", &lfo_freq, 0.5f);
|
||||
config->get_float(userdata, "drywet", &drywet, 0.8f);
|
||||
|
||||
delay /= 1000.0f;
|
||||
depth /= 1000.0f;
|
||||
|
||||
if (depth > delay)
|
||||
depth = delay;
|
||||
|
||||
if (drywet < 0.0f)
|
||||
drywet = 0.0f;
|
||||
else if (drywet > 1.0f)
|
||||
drywet = 1.0f;
|
||||
|
||||
ch->mix_dry = 1.0f - 0.5f * drywet;
|
||||
ch->mix_wet = 0.5f * drywet;
|
||||
|
||||
ch->delay = delay;
|
||||
ch->depth = depth;
|
||||
ch->lfo_period = (1.0f / lfo_freq) * info->input_rate;
|
||||
ch->input_rate = info->input_rate;
|
||||
if (!ch->lfo_period)
|
||||
ch->lfo_period = 1;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation chorus_plug = {
|
||||
chorus_init,
|
||||
chorus_process,
|
||||
chorus_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Chorus",
|
||||
"chorus",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation chorus_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &chorus_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2015 - 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 DSPFILTER_API_H__
|
||||
#define DSPFILTER_API_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DSPFILTER_SIMD_SSE (1 << 0)
|
||||
#define DSPFILTER_SIMD_SSE2 (1 << 1)
|
||||
#define DSPFILTER_SIMD_VMX (1 << 2)
|
||||
#define DSPFILTER_SIMD_VMX128 (1 << 3)
|
||||
#define DSPFILTER_SIMD_AVX (1 << 4)
|
||||
#define DSPFILTER_SIMD_NEON (1 << 5)
|
||||
#define DSPFILTER_SIMD_SSE3 (1 << 6)
|
||||
#define DSPFILTER_SIMD_SSSE3 (1 << 7)
|
||||
#define DSPFILTER_SIMD_MMX (1 << 8)
|
||||
#define DSPFILTER_SIMD_MMXEXT (1 << 9)
|
||||
#define DSPFILTER_SIMD_SSE4 (1 << 10)
|
||||
#define DSPFILTER_SIMD_SSE42 (1 << 11)
|
||||
#define DSPFILTER_SIMD_AVX2 (1 << 12)
|
||||
#define DSPFILTER_SIMD_VFPU (1 << 13)
|
||||
#define DSPFILTER_SIMD_PS (1 << 14)
|
||||
|
||||
/* A bit-mask of all supported SIMD instruction sets.
|
||||
* Allows an implementation to pick different
|
||||
* dspfilter_implementation structs.
|
||||
*/
|
||||
typedef unsigned dspfilter_simd_mask_t;
|
||||
|
||||
/* Dynamic library endpoint. */
|
||||
typedef const struct dspfilter_implementation *(
|
||||
*dspfilter_get_implementation_t)(dspfilter_simd_mask_t mask);
|
||||
|
||||
/* The same SIMD mask argument is forwarded to create() callback
|
||||
* as well to avoid having to keep lots of state around. */
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(
|
||||
dspfilter_simd_mask_t mask);
|
||||
|
||||
#define DSPFILTER_API_VERSION 1
|
||||
|
||||
struct dspfilter_info
|
||||
{
|
||||
/* Input sample rate that the DSP plugin receives. */
|
||||
float input_rate;
|
||||
};
|
||||
|
||||
struct dspfilter_output
|
||||
{
|
||||
/* The DSP plugin has to provide the buffering for the
|
||||
* output samples or reuse the input buffer directly.
|
||||
*
|
||||
* The samples are laid out in interleaving order: LRLRLRLR
|
||||
* The range of the samples are [-1.0, 1.0].
|
||||
*
|
||||
* It is not necessary to manually clip values. */
|
||||
float *samples;
|
||||
|
||||
/* Frames which the DSP plugin outputted for the current process.
|
||||
*
|
||||
* One frame is here defined as a combined sample of
|
||||
* left and right channels.
|
||||
*
|
||||
* (I.e. 44.1kHz, 16bit stereo will have
|
||||
* 88.2k samples/sec and 44.1k frames/sec.)
|
||||
*/
|
||||
unsigned frames;
|
||||
};
|
||||
|
||||
struct dspfilter_input
|
||||
{
|
||||
/* Input data for the DSP. The samples are interleaved in order: LRLRLRLR
|
||||
*
|
||||
* It is valid for a DSP plug to use this buffer for output as long as
|
||||
* the output size is less or equal to the input.
|
||||
*
|
||||
* This is useful for filters which can output one sample for each
|
||||
* input sample and do not need to maintain its own buffers.
|
||||
*
|
||||
* Block based filters must provide their own buffering scheme.
|
||||
*
|
||||
* The input size is not bound, but it can be safely assumed that it
|
||||
* will not exceed ~100ms worth of audio at a time. */
|
||||
float *samples;
|
||||
|
||||
/* Number of frames for input data.
|
||||
* One frame is here defined as a combined sample of
|
||||
* left and right channels.
|
||||
*
|
||||
* (I.e. 44.1kHz, 16bit stereo will have
|
||||
* 88.2k samples/sec and 44.1k frames/sec.)
|
||||
*/
|
||||
unsigned frames;
|
||||
};
|
||||
|
||||
/* Returns true if config key was found. Otherwise,
|
||||
* returns false, and sets value to default value.
|
||||
*/
|
||||
typedef int (*dspfilter_config_get_float_t)(void *userdata,
|
||||
const char *key, float *value, float default_value);
|
||||
|
||||
typedef int (*dspfilter_config_get_int_t)(void *userdata,
|
||||
const char *key, int *value, int default_value);
|
||||
|
||||
/* Allocates an array with values. free() with dspfilter_config_free_t. */
|
||||
typedef int (*dspfilter_config_get_float_array_t)(void *userdata,
|
||||
const char *key, float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*dspfilter_config_get_int_array_t)(void *userdata,
|
||||
const char *key, int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*dspfilter_config_get_string_t)(void *userdata,
|
||||
const char *key, char **output, const char *default_output);
|
||||
|
||||
/* Calls free() in host runtime. Sometimes needed on Windows.
|
||||
* free() on NULL is fine. */
|
||||
typedef void (*dspfilter_config_free_t)(void *ptr);
|
||||
|
||||
struct dspfilter_config
|
||||
{
|
||||
dspfilter_config_get_float_t get_float;
|
||||
dspfilter_config_get_int_t get_int;
|
||||
|
||||
dspfilter_config_get_float_array_t get_float_array;
|
||||
dspfilter_config_get_int_array_t get_int_array;
|
||||
|
||||
dspfilter_config_get_string_t get_string;
|
||||
/* Avoid problems where DSP plug and host are
|
||||
* linked against different C runtimes. */
|
||||
dspfilter_config_free_t free;
|
||||
};
|
||||
|
||||
/* Creates a handle of the plugin. Returns NULL if failed. */
|
||||
typedef void *(*dspfilter_init_t)(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata);
|
||||
|
||||
/* Frees the handle. */
|
||||
typedef void (*dspfilter_free_t)(void *data);
|
||||
|
||||
/* Processes input data.
|
||||
* The plugin is allowed to return variable sizes for output data. */
|
||||
typedef void (*dspfilter_process_t)(void *data,
|
||||
struct dspfilter_output *output, const struct dspfilter_input *input);
|
||||
|
||||
struct dspfilter_implementation
|
||||
{
|
||||
dspfilter_init_t init;
|
||||
dspfilter_process_t process;
|
||||
dspfilter_free_t free;
|
||||
|
||||
/* Must be DSPFILTER_API_VERSION */
|
||||
unsigned api_version;
|
||||
|
||||
/* Human readable identifier of implementation. */
|
||||
const char *ident;
|
||||
|
||||
/* Computer-friendly short version of ident.
|
||||
* Lower case, no spaces and special characters, etc. */
|
||||
const char *short_ident;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/* 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 <stdlib.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "dspfilter.h"
|
||||
|
||||
struct echo_channel
|
||||
{
|
||||
float *buffer;
|
||||
unsigned ptr;
|
||||
unsigned frames;
|
||||
float feedback;
|
||||
};
|
||||
|
||||
struct echo_data
|
||||
{
|
||||
struct echo_channel *channels;
|
||||
unsigned num_channels;
|
||||
float amp;
|
||||
};
|
||||
|
||||
static void echo_free(void *data)
|
||||
{
|
||||
unsigned i;
|
||||
struct echo_data *echo = (struct echo_data*)data;
|
||||
|
||||
for (i = 0; i < echo->num_channels; i++)
|
||||
free(echo->channels[i].buffer);
|
||||
free(echo->channels);
|
||||
free(echo);
|
||||
}
|
||||
|
||||
static void echo_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i, c;
|
||||
struct echo_data *echo = (struct echo_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
|
||||
float *out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
float left, right;
|
||||
float echo_left = 0.0f;
|
||||
float echo_right = 0.0f;
|
||||
|
||||
for (c = 0; c < echo->num_channels; c++)
|
||||
{
|
||||
echo_left += echo->channels[c].buffer[(echo->channels[c].ptr << 1) + 0];
|
||||
echo_right += echo->channels[c].buffer[(echo->channels[c].ptr << 1) + 1];
|
||||
}
|
||||
|
||||
echo_left *= echo->amp;
|
||||
echo_right *= echo->amp;
|
||||
|
||||
left = out[0] + echo_left;
|
||||
right = out[1] + echo_right;
|
||||
|
||||
for (c = 0; c < echo->num_channels; c++)
|
||||
{
|
||||
float feedback_left = out[0] + echo->channels[c].feedback * echo_left;
|
||||
float feedback_right = out[1] + echo->channels[c].feedback * echo_right;
|
||||
|
||||
echo->channels[c].buffer[(echo->channels[c].ptr << 1) + 0] = feedback_left;
|
||||
echo->channels[c].buffer[(echo->channels[c].ptr << 1) + 1] = feedback_right;
|
||||
|
||||
echo->channels[c].ptr = (echo->channels[c].ptr + 1) % echo->channels[c].frames;
|
||||
}
|
||||
|
||||
out[0] = left;
|
||||
out[1] = right;
|
||||
}
|
||||
}
|
||||
|
||||
static void *echo_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
unsigned i, channels;
|
||||
float *delay = NULL, *feedback = NULL;
|
||||
unsigned num_delay = 0, num_feedback = 0;
|
||||
|
||||
static const float default_delay[] = { 200.0f };
|
||||
static const float default_feedback[] = { 0.5f };
|
||||
struct echo_data *echo = (struct echo_data*)calloc(1, sizeof(*echo));
|
||||
if (!echo)
|
||||
return NULL;
|
||||
|
||||
config->get_float_array(userdata, "delay", &delay, &num_delay, default_delay, 1);
|
||||
config->get_float_array(userdata, "feedback", &feedback, &num_feedback, default_feedback, 1);
|
||||
config->get_float(userdata, "amp", &echo->amp, 0.2f);
|
||||
|
||||
channels = num_feedback = num_delay = MIN(num_delay, num_feedback);
|
||||
|
||||
echo->channels = (struct echo_channel*)calloc(channels, sizeof(*echo->channels));
|
||||
if (!echo->channels)
|
||||
goto error;
|
||||
|
||||
echo->num_channels = channels;
|
||||
|
||||
for (i = 0; i < channels; i++)
|
||||
{
|
||||
unsigned frames = (unsigned)(delay[i] * info->input_rate / 1000.0f + 0.5f);
|
||||
if (!frames)
|
||||
goto error;
|
||||
|
||||
echo->channels[i].buffer = (float*)calloc(frames, 2 * sizeof(float));
|
||||
if (!echo->channels[i].buffer)
|
||||
goto error;
|
||||
|
||||
echo->channels[i].frames = frames;
|
||||
echo->channels[i].feedback = feedback[i];
|
||||
}
|
||||
|
||||
config->free(delay);
|
||||
config->free(feedback);
|
||||
return echo;
|
||||
|
||||
error:
|
||||
config->free(delay);
|
||||
config->free(feedback);
|
||||
echo_free(echo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const struct dspfilter_implementation echo_plug = {
|
||||
echo_init,
|
||||
echo_process,
|
||||
echo_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Multi-Echo",
|
||||
"echo",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation echo_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &echo_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (eq.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
* 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.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -27,7 +19,8 @@
|
||||
#include <retro_inline.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <filters.h>
|
||||
#include <libretro_dspfilter.h>
|
||||
|
||||
#include "dspfilter.h"
|
||||
|
||||
#include "fft/fft.c"
|
||||
|
||||
@@ -149,8 +142,7 @@ static void generate_response(fft_complex_t *response,
|
||||
gains++;
|
||||
}
|
||||
|
||||
/* Create a response by linear interpolation between
|
||||
* known frequency sample points. */
|
||||
// Create a response by linear interpolation between known frequency sample points.
|
||||
for (i = 0; i <= samples; i++)
|
||||
{
|
||||
float gain;
|
||||
@@ -212,11 +204,9 @@ static void create_filter(struct eq_data *eq, unsigned size_log2,
|
||||
/* Get equivalent time-domain filter. */
|
||||
fft_process_inverse(fft, time_filter, eq->filter, 1);
|
||||
|
||||
/* ifftshift() to create the correct linear phase filter.
|
||||
* The filter response was designed with zero phase, which
|
||||
* won't work unless we compensate
|
||||
* for the repeating property of the FFT here
|
||||
* by flipping left and right blocks. */
|
||||
// ifftshift() to create the correct linear phase filter.
|
||||
// The filter response was designed with zero phase, which won't work unless we compensate
|
||||
// for the repeating property of the FFT here by flipping left and right blocks.
|
||||
for (i = 0; i < half_block_size; i++)
|
||||
{
|
||||
float tmp = time_filter[i + half_block_size];
|
||||
@@ -0,0 +1,194 @@
|
||||
/* 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 "fft.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
struct fft
|
||||
{
|
||||
fft_complex_t *interleave_buffer;
|
||||
fft_complex_t *phase_lut;
|
||||
unsigned *bitinverse_buffer;
|
||||
unsigned size;
|
||||
};
|
||||
|
||||
static unsigned bitswap(unsigned x, unsigned size_log2)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned ret = 0;
|
||||
for (i = 0; i < size_log2; i++)
|
||||
ret |= ((x >> i) & 1) << (size_log2 - i - 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void build_bitinverse(unsigned *bitinverse, unsigned size_log2)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned size = 1 << size_log2;
|
||||
for (i = 0; i < size; i++)
|
||||
bitinverse[i] = bitswap(i, size_log2);
|
||||
}
|
||||
|
||||
static fft_complex_t exp_imag(double phase)
|
||||
{
|
||||
fft_complex_t out = { cos(phase), sin(phase) };
|
||||
return out;
|
||||
}
|
||||
|
||||
static void build_phase_lut(fft_complex_t *out, int size)
|
||||
{
|
||||
int i;
|
||||
out += size;
|
||||
for (i = -size; i <= size; i++)
|
||||
out[i] = exp_imag((M_PI * i) / size);
|
||||
}
|
||||
|
||||
static void interleave_complex(const unsigned *bitinverse,
|
||||
fft_complex_t *out, const fft_complex_t *in,
|
||||
unsigned samples, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < samples; i++, in += step)
|
||||
out[bitinverse[i]] = *in;
|
||||
}
|
||||
|
||||
static void interleave_float(const unsigned *bitinverse,
|
||||
fft_complex_t *out, const float *in,
|
||||
unsigned samples, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < samples; i++, in += step)
|
||||
{
|
||||
unsigned inv_i = bitinverse[i];
|
||||
out[inv_i].real = *in;
|
||||
out[inv_i].imag = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void resolve_float(float *out, const fft_complex_t *in, unsigned samples,
|
||||
float gain, unsigned step)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < samples; i++, in++, out += step)
|
||||
*out = gain * in->real;
|
||||
}
|
||||
|
||||
fft_t *fft_new(unsigned block_size_log2)
|
||||
{
|
||||
fft_t *fft = (fft_t*)calloc(1, sizeof(*fft));
|
||||
if (!fft)
|
||||
return NULL;
|
||||
|
||||
unsigned size = 1 << block_size_log2;
|
||||
|
||||
fft->interleave_buffer = (fft_complex_t*)calloc(size, sizeof(*fft->interleave_buffer));
|
||||
fft->bitinverse_buffer = (unsigned*)calloc(size, sizeof(*fft->bitinverse_buffer));
|
||||
fft->phase_lut = (fft_complex_t*)calloc(2 * size + 1, sizeof(*fft->phase_lut));
|
||||
|
||||
if (!fft->interleave_buffer || !fft->bitinverse_buffer || !fft->phase_lut)
|
||||
goto error;
|
||||
|
||||
fft->size = size;
|
||||
|
||||
build_bitinverse(fft->bitinverse_buffer, block_size_log2);
|
||||
build_phase_lut(fft->phase_lut, size);
|
||||
return fft;
|
||||
|
||||
error:
|
||||
fft_free(fft);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fft_free(fft_t *fft)
|
||||
{
|
||||
if (!fft)
|
||||
return;
|
||||
|
||||
free(fft->interleave_buffer);
|
||||
free(fft->bitinverse_buffer);
|
||||
free(fft->phase_lut);
|
||||
free(fft);
|
||||
}
|
||||
|
||||
static void butterfly(fft_complex_t *a, fft_complex_t *b, fft_complex_t mod)
|
||||
{
|
||||
mod = fft_complex_mul(mod, *b);
|
||||
*b = fft_complex_sub(*a, mod);
|
||||
*a = fft_complex_add(*a, mod);
|
||||
}
|
||||
|
||||
static void butterflies(fft_complex_t *butterfly_buf,
|
||||
const fft_complex_t *phase_lut,
|
||||
int phase_dir, unsigned step_size, unsigned samples)
|
||||
{
|
||||
unsigned i, j;
|
||||
for (i = 0; i < samples; i += step_size << 1)
|
||||
{
|
||||
int phase_step = (int)samples * phase_dir / (int)step_size;
|
||||
for (j = i; j < i + step_size; j++)
|
||||
butterfly(&butterfly_buf[j], &butterfly_buf[j + step_size], phase_lut[phase_step * (int)(j - i)]);
|
||||
}
|
||||
}
|
||||
|
||||
void fft_process_forward_complex(fft_t *fft,
|
||||
fft_complex_t *out, const fft_complex_t *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
||||
interleave_complex(fft->bitinverse_buffer, out, in, samples, step);
|
||||
|
||||
for (step_size = 1; step_size < samples; step_size <<= 1)
|
||||
{
|
||||
butterflies(out,
|
||||
fft->phase_lut + samples,
|
||||
-1, step_size, samples);
|
||||
}
|
||||
}
|
||||
|
||||
void fft_process_forward(fft_t *fft,
|
||||
fft_complex_t *out, const float *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
||||
interleave_float(fft->bitinverse_buffer, out, in, samples, step);
|
||||
|
||||
for (step_size = 1; step_size < fft->size; step_size <<= 1)
|
||||
{
|
||||
butterflies(out,
|
||||
fft->phase_lut + samples,
|
||||
-1, step_size, samples);
|
||||
}
|
||||
}
|
||||
|
||||
void fft_process_inverse(fft_t *fft,
|
||||
float *out, const fft_complex_t *in, unsigned step)
|
||||
{
|
||||
unsigned step_size;
|
||||
unsigned samples = fft->size;
|
||||
interleave_complex(fft->bitinverse_buffer, fft->interleave_buffer, in, samples, 1);
|
||||
|
||||
for (step_size = 1; step_size < samples; step_size <<= 1)
|
||||
{
|
||||
butterflies(fft->interleave_buffer,
|
||||
fft->phase_lut + samples,
|
||||
1, step_size, samples);
|
||||
}
|
||||
|
||||
resolve_float(out, fft->interleave_buffer, samples, 1.0f / samples, step);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef RARCH_FFT_H__
|
||||
#define RARCH_FFT_H__
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
typedef struct fft fft_t;
|
||||
|
||||
// C99 <complex.h> would be nice.
|
||||
typedef struct
|
||||
{
|
||||
float real;
|
||||
float imag;
|
||||
} fft_complex_t;
|
||||
|
||||
static INLINE fft_complex_t fft_complex_mul(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
fft_complex_t out = {
|
||||
a.real * b.real - a.imag * b.imag,
|
||||
a.imag * b.real + a.real * b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static INLINE fft_complex_t fft_complex_add(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
fft_complex_t out = {
|
||||
a.real + b.real,
|
||||
a.imag + b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static INLINE fft_complex_t fft_complex_sub(fft_complex_t a,
|
||||
fft_complex_t b)
|
||||
{
|
||||
fft_complex_t out = {
|
||||
a.real - b.real,
|
||||
a.imag - b.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
static INLINE fft_complex_t fft_complex_conj(fft_complex_t a)
|
||||
{
|
||||
fft_complex_t out = {
|
||||
a.real, -a.imag,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
fft_t *fft_new(unsigned block_size_log2);
|
||||
|
||||
void fft_free(fft_t *fft);
|
||||
|
||||
void fft_process_forward_complex(fft_t *fft,
|
||||
fft_complex_t *out, const fft_complex_t *in, unsigned step);
|
||||
|
||||
void fft_process_forward(fft_t *fft,
|
||||
fft_complex_t *out, const float *in, unsigned step);
|
||||
|
||||
void fft_process_inverse(fft_t *fft,
|
||||
float *out, const fft_complex_t *in, unsigned step);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,25 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2014 - Brad Miller
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (iir.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
* 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.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <libretro_dspfilter.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#define sqr(a) ((a) * (a))
|
||||
|
||||
@@ -67,29 +60,34 @@ static void iir_free(void *data)
|
||||
static void iir_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
float b0, b1, b2, a0, a1, a2;
|
||||
float xn1_l, xn2_l, yn1_l, yn2_l;
|
||||
float xn1_r, xn2_r, yn1_r, yn2_r;
|
||||
unsigned i;
|
||||
float *out;
|
||||
struct iir_data *iir = (struct iir_data*)data;
|
||||
float *out = output->samples;
|
||||
|
||||
float b0 = iir->b0;
|
||||
float b1 = iir->b1;
|
||||
float b2 = iir->b2;
|
||||
float a0 = iir->a0;
|
||||
float a1 = iir->a1;
|
||||
float a2 = iir->a2;
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
|
||||
float xn1_l = iir->l.xn1;
|
||||
float xn2_l = iir->l.xn2;
|
||||
float yn1_l = iir->l.yn1;
|
||||
float yn2_l = iir->l.yn2;
|
||||
out = output->samples;
|
||||
|
||||
float xn1_r = iir->r.xn1;
|
||||
float xn2_r = iir->r.xn2;
|
||||
float yn1_r = iir->r.yn1;
|
||||
float yn2_r = iir->r.yn2;
|
||||
b0 = iir->b0;
|
||||
b1 = iir->b1;
|
||||
b2 = iir->b2;
|
||||
a0 = iir->a0;
|
||||
a1 = iir->a1;
|
||||
a2 = iir->a2;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
xn1_l = iir->l.xn1;
|
||||
xn2_l = iir->l.xn2;
|
||||
yn1_l = iir->l.yn1;
|
||||
yn2_l = iir->l.yn2;
|
||||
|
||||
xn1_r = iir->r.xn1;
|
||||
xn2_r = iir->r.xn2;
|
||||
yn1_r = iir->r.yn1;
|
||||
yn2_r = iir->r.yn2;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
@@ -99,18 +97,18 @@ static void iir_process(void *data, struct dspfilter_output *output,
|
||||
float l = (b0 * in_l + b1 * xn1_l + b2 * xn2_l - a1 * yn1_l - a2 * yn2_l) / a0;
|
||||
float r = (b0 * in_r + b1 * xn1_r + b2 * xn2_r - a1 * yn1_r - a2 * yn2_r) / a0;
|
||||
|
||||
xn2_l = xn1_l;
|
||||
xn1_l = in_l;
|
||||
yn2_l = yn1_l;
|
||||
yn1_l = l;
|
||||
xn2_l = xn1_l;
|
||||
xn1_l = in_l;
|
||||
yn2_l = yn1_l;
|
||||
yn1_l = l;
|
||||
|
||||
xn2_r = xn1_r;
|
||||
xn1_r = in_r;
|
||||
yn2_r = yn1_r;
|
||||
yn1_r = r;
|
||||
xn2_r = xn1_r;
|
||||
xn1_r = in_r;
|
||||
yn2_r = yn1_r;
|
||||
yn1_r = r;
|
||||
|
||||
out[0] = l;
|
||||
out[1] = r;
|
||||
out[0] = l;
|
||||
out[1] = r;
|
||||
}
|
||||
|
||||
iir->l.xn1 = xn1_l;
|
||||
@@ -124,7 +122,7 @@ static void iir_process(void *data, struct dspfilter_output *output,
|
||||
iir->r.yn2 = yn2_r;
|
||||
}
|
||||
|
||||
#define CHECK(x) if (string_is_equal(str, #x)) return x
|
||||
#define CHECK(x) if (!strcmp(str, #x)) return x
|
||||
static enum IIRFilter str_to_type(const char *str)
|
||||
{
|
||||
CHECK(LPF);
|
||||
@@ -139,8 +137,7 @@ static enum IIRFilter str_to_type(const char *str)
|
||||
CHECK(LSH);
|
||||
CHECK(HSH);
|
||||
CHECK(RIAA_CD);
|
||||
|
||||
return LPF; /* Fallback. */
|
||||
return LPF; // Fallback.
|
||||
}
|
||||
|
||||
static void make_poly_from_roots(
|
||||
@@ -212,7 +209,7 @@ static void iir_filter_init(struct iir_data *iir,
|
||||
a1 = -2.0 * cs;
|
||||
a2 = 1.0 - a1pha;
|
||||
break;
|
||||
case NOTCH:
|
||||
case NOTCH:
|
||||
b0 = 1.0;
|
||||
b1 = -2.0 * cs;
|
||||
b2 = 1.0;
|
||||
@@ -253,7 +250,7 @@ static void iir_filter_init(struct iir_data *iir,
|
||||
make_poly_from_roots(zeros, 2, b);
|
||||
make_poly_from_roots(poles, 2, a);
|
||||
}
|
||||
|
||||
|
||||
b0 = b[0];
|
||||
b1 = b[1];
|
||||
b2 = b[2];
|
||||
@@ -272,15 +269,15 @@ static void iir_filter_init(struct iir_data *iir,
|
||||
b0 *= g; b1 *= g; b2 *= g;
|
||||
break;
|
||||
}
|
||||
case PEQ:
|
||||
case PEQ:
|
||||
b0 = 1.0 + a1pha * A;
|
||||
b1 = -2.0 * cs;
|
||||
b2 = 1.0 - a1pha * A;
|
||||
a0 = 1.0 + a1pha / A;
|
||||
a1 = -2.0 * cs;
|
||||
a2 = 1.0 - a1pha / A;
|
||||
break;
|
||||
case BBOOST:
|
||||
break;
|
||||
case BBOOST:
|
||||
beta = sqrt((A * A + 1) / 1.0 - (pow((A - 1), 2)));
|
||||
b0 = A * ((A + 1) - (A - 1) * cs + beta * sn);
|
||||
b1 = 2 * A * ((A - 1) - (A + 1) * cs);
|
||||
@@ -329,9 +326,9 @@ static void *iir_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
float freq, qual, gain;
|
||||
enum IIRFilter filter = LPF;
|
||||
char *type = NULL;
|
||||
struct iir_data *iir = (struct iir_data*)calloc(1, sizeof(*iir));
|
||||
enum IIRFilter filter;
|
||||
char *type = NULL;
|
||||
struct iir_data *iir = (struct iir_data*)calloc(1, sizeof(*iir));
|
||||
if (!iir)
|
||||
return NULL;
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,96 @@
|
||||
/* 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 "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct panning_data
|
||||
{
|
||||
float left[2];
|
||||
float right[2];
|
||||
};
|
||||
|
||||
static void panning_free(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void panning_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i;
|
||||
float *out;
|
||||
struct panning_data *pan = (struct panning_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
float left = out[0];
|
||||
float right = out[1];
|
||||
out[0] = left * pan->left[0] + right * pan->left[1];
|
||||
out[1] = left * pan->right[0] + right * pan->right[1];
|
||||
}
|
||||
}
|
||||
|
||||
static void *panning_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
static const float default_left[] = { 1.0f, 0.0f };
|
||||
static const float default_right[] = { 0.0f, 1.0f };
|
||||
float *left = NULL, *right = NULL;
|
||||
unsigned num_left = 0, num_right = 0;
|
||||
struct panning_data *pan = (struct panning_data*)calloc(1, sizeof(*pan));
|
||||
if (!pan)
|
||||
return NULL;
|
||||
|
||||
config->get_float_array(userdata, "left_mix", &left, &num_left, default_left, 2);
|
||||
config->get_float_array(userdata, "right_mix", &right, &num_right, default_right, 2);
|
||||
|
||||
memcpy(pan->left, (num_left == 2) ? left : default_left, sizeof(pan->left));
|
||||
memcpy(pan->right, (num_right == 2) ? right : default_right, sizeof(pan->right));
|
||||
|
||||
config->free(left);
|
||||
config->free(right);
|
||||
|
||||
return pan;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation panning = {
|
||||
panning_init,
|
||||
panning_process,
|
||||
panning_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Panning",
|
||||
"panning",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation panning_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &panning;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2014 - Brad Miller
|
||||
*
|
||||
* 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 "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#define phaserlfoshape 4.0
|
||||
#define phaserlfoskipsamples 20
|
||||
|
||||
struct phaser_data
|
||||
{
|
||||
float freq;
|
||||
float startphase;
|
||||
float fb;
|
||||
float depth;
|
||||
float drywet;
|
||||
float old[2][24];
|
||||
float gain;
|
||||
float fbout[2];
|
||||
float lfoskip;
|
||||
float phase;
|
||||
|
||||
int stages;
|
||||
unsigned long skipcount;
|
||||
};
|
||||
|
||||
static void phaser_free(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void phaser_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i, c;
|
||||
int s;
|
||||
float m[2], tmp[2], *out;
|
||||
struct phaser_data *ph = (struct phaser_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
float in[2] = { out[0], out[1] };
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
m[c] = in[c] + ph->fbout[c] * ph->fb * 0.01f;
|
||||
|
||||
if ((ph->skipcount++ % phaserlfoskipsamples) == 0)
|
||||
{
|
||||
ph->gain = 0.5 * (1.0 + cos(ph->skipcount * ph->lfoskip + ph->phase));
|
||||
ph->gain = (exp(ph->gain * phaserlfoshape) - 1.0) / (exp(phaserlfoshape) - 1);
|
||||
ph->gain = 1.0 - ph->gain * ph->depth;
|
||||
}
|
||||
|
||||
for (s = 0; s < ph->stages; s++)
|
||||
{
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
tmp[c] = ph->old[c][s];
|
||||
ph->old[c][s] = ph->gain * tmp[c] + m[c];
|
||||
m[c] = tmp[c] - ph->gain * ph->old[c][s];
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
ph->fbout[c] = m[c];
|
||||
out[c] = m[c] * ph->drywet + in[c] * (1.0f - ph->drywet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *phaser_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
float lfo_freq, lfo_start_phase;
|
||||
struct phaser_data *ph = (struct phaser_data*)calloc(1, sizeof(*ph));
|
||||
if (!ph)
|
||||
return NULL;
|
||||
|
||||
config->get_float(userdata, "lfo_freq", &lfo_freq, 0.4f);
|
||||
config->get_float(userdata, "lfo_start_phase", &lfo_start_phase, 0.0f);
|
||||
config->get_float(userdata, "feedback", &ph->fb, 0.0f);
|
||||
config->get_float(userdata, "depth", &ph->depth, 0.4f);
|
||||
config->get_float(userdata, "dry_wet", &ph->drywet, 0.5f);
|
||||
config->get_int(userdata, "stages", &ph->stages, 2);
|
||||
|
||||
if (ph->stages < 1)
|
||||
ph->stages = 1;
|
||||
else if (ph->stages > 24)
|
||||
ph->stages = 24;
|
||||
|
||||
ph->lfoskip = lfo_freq * 2.0 * M_PI / info->input_rate;
|
||||
ph->phase = lfo_start_phase * M_PI / 180.0;
|
||||
|
||||
return ph;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation phaser_plug = {
|
||||
phaser_init,
|
||||
phaser_process,
|
||||
phaser_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Phaser",
|
||||
"phaser",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation phaser_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &phaser_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2014 - Brad Miller
|
||||
*
|
||||
* 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 "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
struct comb
|
||||
{
|
||||
float *buffer;
|
||||
unsigned bufsize;
|
||||
unsigned bufidx;
|
||||
|
||||
float feedback;
|
||||
float filterstore;
|
||||
float damp1, damp2;
|
||||
};
|
||||
|
||||
struct allpass
|
||||
{
|
||||
float *buffer;
|
||||
float feedback;
|
||||
unsigned bufsize;
|
||||
unsigned bufidx;
|
||||
};
|
||||
|
||||
static INLINE float comb_process(struct comb *c, float input)
|
||||
{
|
||||
float output = c->buffer[c->bufidx];
|
||||
c->filterstore = (output * c->damp2) + (c->filterstore * c->damp1);
|
||||
|
||||
c->buffer[c->bufidx] = input + (c->filterstore * c->feedback);
|
||||
|
||||
c->bufidx++;
|
||||
if (c->bufidx >= c->bufsize)
|
||||
c->bufidx = 0;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
static INLINE float allpass_process(struct allpass *a, float input)
|
||||
{
|
||||
float bufout = a->buffer[a->bufidx];
|
||||
float output = -input + bufout;
|
||||
a->buffer[a->bufidx] = input + bufout * a->feedback;
|
||||
|
||||
a->bufidx++;
|
||||
if (a->bufidx >= a->bufsize)
|
||||
a->bufidx = 0;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#define numcombs 8
|
||||
#define numallpasses 4
|
||||
static const float muted = 0;
|
||||
static const float fixedgain = 0.015f;
|
||||
static const float scalewet = 3;
|
||||
static const float scaledry = 2;
|
||||
static const float scaledamp = 0.4f;
|
||||
static const float scaleroom = 0.28f;
|
||||
static const float offsetroom = 0.7f;
|
||||
static const float initialroom = 0.5f;
|
||||
static const float initialdamp = 0.5f;
|
||||
static const float initialwet = 1.0f / 3.0f;
|
||||
static const float initialdry = 0;
|
||||
static const float initialwidth = 1;
|
||||
static const float initialmode = 0;
|
||||
static const float freezemode = 0.5f;
|
||||
|
||||
#define combtuningL1 1116
|
||||
#define combtuningL2 1188
|
||||
#define combtuningL3 1277
|
||||
#define combtuningL4 1356
|
||||
#define combtuningL5 1422
|
||||
#define combtuningL6 1491
|
||||
#define combtuningL7 1557
|
||||
#define combtuningL8 1617
|
||||
#define allpasstuningL1 556
|
||||
#define allpasstuningL2 441
|
||||
#define allpasstuningL3 341
|
||||
#define allpasstuningL4 225
|
||||
|
||||
struct revmodel
|
||||
{
|
||||
struct comb combL[numcombs];
|
||||
struct allpass allpassL[numallpasses];
|
||||
|
||||
float bufcombL1[combtuningL1];
|
||||
float bufcombL2[combtuningL2];
|
||||
float bufcombL3[combtuningL3];
|
||||
float bufcombL4[combtuningL4];
|
||||
float bufcombL5[combtuningL5];
|
||||
float bufcombL6[combtuningL6];
|
||||
float bufcombL7[combtuningL7];
|
||||
float bufcombL8[combtuningL8];
|
||||
|
||||
float bufallpassL1[allpasstuningL1];
|
||||
float bufallpassL2[allpasstuningL2];
|
||||
float bufallpassL3[allpasstuningL3];
|
||||
float bufallpassL4[allpasstuningL4];
|
||||
|
||||
float gain;
|
||||
float roomsize, roomsize1;
|
||||
float damp, damp1;
|
||||
float wet, wet1, wet2;
|
||||
float dry;
|
||||
float width;
|
||||
float mode;
|
||||
};
|
||||
|
||||
static float revmodel_process(struct revmodel *rev, float in)
|
||||
{
|
||||
int i;
|
||||
float mono_out = 0.0f;
|
||||
float mono_in = in;
|
||||
float input = mono_in * rev->gain;
|
||||
for (i = 0; i < numcombs; i++)
|
||||
mono_out += comb_process(&rev->combL[i], input);
|
||||
|
||||
for (i = 0; i < numallpasses; i++)
|
||||
mono_out = allpass_process(&rev->allpassL[i], mono_out);
|
||||
|
||||
return mono_in * rev->dry + mono_out * rev->wet1;
|
||||
}
|
||||
|
||||
static void revmodel_update(struct revmodel *rev)
|
||||
{
|
||||
int i;
|
||||
rev->wet1 = rev->wet * (rev->width / 2.0f + 0.5f);
|
||||
|
||||
if (rev->mode >= freezemode)
|
||||
{
|
||||
rev->roomsize1 = 1.0f;
|
||||
rev->damp1 = 0.0f;
|
||||
rev->gain = muted;
|
||||
}
|
||||
else
|
||||
{
|
||||
rev->roomsize1 = rev->roomsize;
|
||||
rev->damp1 = rev->damp;
|
||||
rev->gain = fixedgain;
|
||||
}
|
||||
|
||||
for (i = 0; i < numcombs; i++)
|
||||
{
|
||||
rev->combL[i].feedback = rev->roomsize1;
|
||||
rev->combL[i].damp1 = rev->damp1;
|
||||
rev->combL[i].damp2 = 1.0f - rev->damp1;
|
||||
}
|
||||
}
|
||||
|
||||
static void revmodel_setroomsize(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->roomsize = value * scaleroom + offsetroom;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_setdamp(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->damp = value * scaledamp;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_setwet(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->wet = value * scalewet;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_setdry(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->dry = value * scaledry;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_setwidth(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->width = value;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_setmode(struct revmodel *rev, float value)
|
||||
{
|
||||
rev->mode = value;
|
||||
revmodel_update(rev);
|
||||
}
|
||||
|
||||
static void revmodel_init(struct revmodel *rev)
|
||||
{
|
||||
rev->combL[0].buffer = rev->bufcombL1; rev->combL[0].bufsize = combtuningL1;
|
||||
rev->combL[1].buffer = rev->bufcombL2; rev->combL[1].bufsize = combtuningL2;
|
||||
rev->combL[2].buffer = rev->bufcombL3; rev->combL[2].bufsize = combtuningL3;
|
||||
rev->combL[3].buffer = rev->bufcombL4; rev->combL[3].bufsize = combtuningL4;
|
||||
rev->combL[4].buffer = rev->bufcombL5; rev->combL[4].bufsize = combtuningL5;
|
||||
rev->combL[5].buffer = rev->bufcombL6; rev->combL[5].bufsize = combtuningL6;
|
||||
rev->combL[6].buffer = rev->bufcombL7; rev->combL[6].bufsize = combtuningL7;
|
||||
rev->combL[7].buffer = rev->bufcombL8; rev->combL[7].bufsize = combtuningL8;
|
||||
|
||||
rev->allpassL[0].buffer = rev->bufallpassL1; rev->allpassL[0].bufsize = allpasstuningL1;
|
||||
rev->allpassL[1].buffer = rev->bufallpassL2; rev->allpassL[1].bufsize = allpasstuningL2;
|
||||
rev->allpassL[2].buffer = rev->bufallpassL3; rev->allpassL[2].bufsize = allpasstuningL3;
|
||||
rev->allpassL[3].buffer = rev->bufallpassL4; rev->allpassL[3].bufsize = allpasstuningL4;
|
||||
|
||||
rev->allpassL[0].feedback = 0.5f;
|
||||
rev->allpassL[1].feedback = 0.5f;
|
||||
rev->allpassL[2].feedback = 0.5f;
|
||||
rev->allpassL[3].feedback = 0.5f;
|
||||
|
||||
revmodel_setwet(rev, initialwet);
|
||||
revmodel_setroomsize(rev, initialroom);
|
||||
revmodel_setdry(rev, initialdry);
|
||||
revmodel_setdamp(rev, initialdamp);
|
||||
revmodel_setwidth(rev, initialwidth);
|
||||
revmodel_setmode(rev, initialmode);
|
||||
}
|
||||
|
||||
struct reverb_data
|
||||
{
|
||||
struct revmodel left, right;
|
||||
};
|
||||
|
||||
static void reverb_free(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void reverb_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i;
|
||||
float *out;
|
||||
struct reverb_data *rev = (struct reverb_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
float in[2] = { out[0], out[1] };
|
||||
|
||||
out[0] = revmodel_process(&rev->left, in[0]);
|
||||
out[1] = revmodel_process(&rev->right, in[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void *reverb_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
float drytime, wettime, damping, roomwidth, roomsize;
|
||||
struct reverb_data *rev = (struct reverb_data*)
|
||||
calloc(1, sizeof(*rev));
|
||||
if (!rev)
|
||||
return NULL;
|
||||
|
||||
config->get_float(userdata, "drytime", &drytime, 0.43f);
|
||||
config->get_float(userdata, "wettime", &wettime, 0.4f);
|
||||
config->get_float(userdata, "damping", &damping, 0.8f);
|
||||
config->get_float(userdata, "roomwidth", &roomwidth, 0.56f);
|
||||
config->get_float(userdata, "roomsize", &roomsize, 0.56f);
|
||||
|
||||
revmodel_init(&rev->left);
|
||||
revmodel_init(&rev->right);
|
||||
|
||||
revmodel_setdamp(&rev->left, damping);
|
||||
revmodel_setdry(&rev->left, drytime);
|
||||
revmodel_setwet(&rev->left, wettime);
|
||||
revmodel_setwidth(&rev->left, roomwidth);
|
||||
revmodel_setroomsize(&rev->left, roomsize);
|
||||
|
||||
revmodel_setdamp(&rev->right, damping);
|
||||
revmodel_setdry(&rev->right, drytime);
|
||||
revmodel_setwet(&rev->right, wettime);
|
||||
revmodel_setwidth(&rev->right, roomwidth);
|
||||
revmodel_setroomsize(&rev->right, roomsize);
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation reverb_plug = {
|
||||
reverb_init,
|
||||
reverb_process,
|
||||
reverb_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Reverb",
|
||||
"reverb",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation reverb_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &reverb_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2014 - Brad Miller
|
||||
*
|
||||
* 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 "dspfilter.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#define WAHWAH_LFO_SKIP_SAMPLES 30
|
||||
|
||||
struct wahwah_data
|
||||
{
|
||||
float phase;
|
||||
float lfoskip;
|
||||
float b0, b1, b2, a0, a1, a2;
|
||||
float freq, startphase;
|
||||
float depth, freqofs, res;
|
||||
unsigned long skipcount;
|
||||
|
||||
struct
|
||||
{
|
||||
float xn1, xn2, yn1, yn2;
|
||||
} l, r;
|
||||
};
|
||||
|
||||
static void wahwah_free(void *data)
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void wahwah_process(void *data, struct dspfilter_output *output,
|
||||
const struct dspfilter_input *input)
|
||||
{
|
||||
unsigned i;
|
||||
float *out;
|
||||
struct wahwah_data *wah = (struct wahwah_data*)data;
|
||||
|
||||
output->samples = input->samples;
|
||||
output->frames = input->frames;
|
||||
out = output->samples;
|
||||
|
||||
for (i = 0; i < input->frames; i++, out += 2)
|
||||
{
|
||||
float out_l, out_r;
|
||||
float in[2] = { out[0], out[1] };
|
||||
|
||||
if ((wah->skipcount++ % WAHWAH_LFO_SKIP_SAMPLES) == 0)
|
||||
{
|
||||
float omega, sn, cs, alpha;
|
||||
float frequency = (1.0 + cos(wah->skipcount * wah->lfoskip + wah->phase)) / 2.0;
|
||||
|
||||
frequency = frequency * wah->depth * (1.0 - wah->freqofs) + wah->freqofs;
|
||||
frequency = exp((frequency - 1.0) * 6.0);
|
||||
|
||||
omega = M_PI * frequency;
|
||||
sn = sin(omega);
|
||||
cs = cos(omega);
|
||||
alpha = sn / (2.0 * wah->res);
|
||||
|
||||
wah->b0 = (1.0 - cs) / 2.0;
|
||||
wah->b1 = 1.0 - cs;
|
||||
wah->b2 = (1.0 - cs) / 2.0;
|
||||
wah->a0 = 1.0 + alpha;
|
||||
wah->a1 = -2.0 * cs;
|
||||
wah->a2 = 1.0 - alpha;
|
||||
}
|
||||
|
||||
out_l = (wah->b0 * in[0] + wah->b1 * wah->l.xn1 + wah->b2 * wah->l.xn2 - wah->a1 * wah->l.yn1 - wah->a2 * wah->l.yn2) / wah->a0;
|
||||
out_r = (wah->b0 * in[1] + wah->b1 * wah->r.xn1 + wah->b2 * wah->r.xn2 - wah->a1 * wah->r.yn1 - wah->a2 * wah->r.yn2) / wah->a0;
|
||||
|
||||
wah->l.xn2 = wah->l.xn1;
|
||||
wah->l.xn1 = in[0];
|
||||
wah->l.yn2 = wah->l.yn1;
|
||||
wah->l.yn1 = out_l;
|
||||
|
||||
wah->r.xn2 = wah->r.xn1;
|
||||
wah->r.xn1 = in[1];
|
||||
wah->r.yn2 = wah->r.yn1;
|
||||
wah->r.yn1 = out_r;
|
||||
|
||||
out[0] = out_l;
|
||||
out[1] = out_r;
|
||||
}
|
||||
}
|
||||
|
||||
static void *wahwah_init(const struct dspfilter_info *info,
|
||||
const struct dspfilter_config *config, void *userdata)
|
||||
{
|
||||
struct wahwah_data *wah = (struct wahwah_data*)calloc(1, sizeof(*wah));
|
||||
if (!wah)
|
||||
return NULL;
|
||||
|
||||
config->get_float(userdata, "lfo_freq", &wah->freq, 1.5f);
|
||||
config->get_float(userdata, "lfo_start_phase", &wah->startphase, 0.0f);
|
||||
config->get_float(userdata, "freq_offset", &wah->freqofs, 0.3f);
|
||||
config->get_float(userdata, "depth", &wah->depth, 0.7f);
|
||||
config->get_float(userdata, "resonance", &wah->res, 2.5f);
|
||||
|
||||
wah->lfoskip = wah->freq * 2.0 * M_PI / info->input_rate;
|
||||
wah->phase = wah->startphase * M_PI / 180.0;
|
||||
|
||||
return wah;
|
||||
}
|
||||
|
||||
static const struct dspfilter_implementation wahwah_plug = {
|
||||
wahwah_init,
|
||||
wahwah_process,
|
||||
wahwah_free,
|
||||
|
||||
DSPFILTER_API_VERSION,
|
||||
"Wah-Wah",
|
||||
"wahwah",
|
||||
};
|
||||
|
||||
#ifdef HAVE_FILTERS_BUILTIN
|
||||
#define dspfilter_get_implementation wahwah_dspfilter_get_implementation
|
||||
#endif
|
||||
|
||||
const struct dspfilter_implementation *dspfilter_get_implementation(dspfilter_simd_mask_t mask)
|
||||
{
|
||||
(void)mask;
|
||||
return &wahwah_plug;
|
||||
}
|
||||
|
||||
#undef dspfilter_get_implementation
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <file/config_file_userdata.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "audio_resampler_driver.h"
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "../performance.h"
|
||||
#endif
|
||||
#ifndef DONT_HAVE_STRING_LIST
|
||||
#include "../string_list_special.h"
|
||||
#endif
|
||||
|
||||
static const rarch_resampler_t *resampler_drivers[] = {
|
||||
&sinc_resampler,
|
||||
&CC_resampler,
|
||||
&nearest_resampler,
|
||||
&null_resampler,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct resampler_config resampler_config = {
|
||||
config_userdata_get_float,
|
||||
config_userdata_get_int,
|
||||
config_userdata_get_float_array,
|
||||
config_userdata_get_int_array,
|
||||
config_userdata_get_string,
|
||||
config_userdata_free,
|
||||
};
|
||||
|
||||
/**
|
||||
* find_resampler_driver_index:
|
||||
* @ident : Identifier of resampler driver to find.
|
||||
*
|
||||
* Finds resampler driver index by @ident name.
|
||||
*
|
||||
* Returns: resampler driver index if resampler driver was found, otherwise
|
||||
* -1.
|
||||
**/
|
||||
static int find_resampler_driver_index(const char *ident)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; resampler_drivers[i]; i++)
|
||||
if (string_is_equal_noncase(ident, resampler_drivers[i]->ident))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_handle:
|
||||
* @idx : index of driver to get handle to.
|
||||
*
|
||||
* Returns: handle to audio resampler driver at index. Can be NULL
|
||||
* if nothing found.
|
||||
**/
|
||||
const void *audio_resampler_driver_find_handle(int idx)
|
||||
{
|
||||
const void *drv = resampler_drivers[idx];
|
||||
if (!drv)
|
||||
return NULL;
|
||||
return drv;
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_ident:
|
||||
* @idx : index of driver to get handle to.
|
||||
*
|
||||
* Returns: Human-readable identifier of audio resampler driver at index.
|
||||
* Can be NULL if nothing found.
|
||||
**/
|
||||
const char *audio_resampler_driver_find_ident(int idx)
|
||||
{
|
||||
const rarch_resampler_t *drv = resampler_drivers[idx];
|
||||
if (!drv)
|
||||
return NULL;
|
||||
return drv->ident;
|
||||
}
|
||||
|
||||
#ifndef DONT_HAVE_STRING_LIST
|
||||
/**
|
||||
* config_get_audio_resampler_driver_options:
|
||||
*
|
||||
* Get an enumerated list of all resampler driver names, separated by '|'.
|
||||
*
|
||||
* Returns: string listing of all resampler driver names, separated by '|'.
|
||||
**/
|
||||
const char* config_get_audio_resampler_driver_options(void)
|
||||
{
|
||||
return char_list_new_special(STRING_LIST_AUDIO_RESAMPLER_DRIVERS, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* find_resampler_driver:
|
||||
* @ident : Identifier of resampler driver to find.
|
||||
*
|
||||
* Finds resampler by @ident name.
|
||||
*
|
||||
* Returns: resampler driver if resampler driver was found, otherwise
|
||||
* NULL.
|
||||
**/
|
||||
static const rarch_resampler_t *find_resampler_driver(const char *ident)
|
||||
{
|
||||
int i = find_resampler_driver_index(ident);
|
||||
|
||||
if (i >= 0)
|
||||
return resampler_drivers[i];
|
||||
|
||||
return resampler_drivers[0];
|
||||
}
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static resampler_simd_mask_t resampler_get_cpu_features(void)
|
||||
{
|
||||
#ifdef RARCH_INTERNAL
|
||||
return retro_get_cpu_features();
|
||||
#else
|
||||
return perf_get_cpu_features_cb();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* resampler_append_plugs:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Initializes resampler driver based on queried CPU features.
|
||||
*
|
||||
* Returns: true (1) if successfully initialized, otherwise false (0).
|
||||
**/
|
||||
static bool resampler_append_plugs(void **re,
|
||||
const rarch_resampler_t **backend,
|
||||
double bw_ratio)
|
||||
{
|
||||
resampler_simd_mask_t mask = resampler_get_cpu_features();
|
||||
|
||||
*re = (*backend)->init(&resampler_config, bw_ratio, mask);
|
||||
|
||||
if (!*re)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rarch_resampler_realloc:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @ident : Identifier name for resampler we want.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Reallocates resampler. Will free previous handle before
|
||||
* allocating a new one. If ident is NULL, first resampler will be used.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
|
||||
const char *ident, double bw_ratio)
|
||||
{
|
||||
if (*re && *backend)
|
||||
(*backend)->free(*re);
|
||||
|
||||
*re = NULL;
|
||||
*backend = find_resampler_driver(ident);
|
||||
|
||||
if (!resampler_append_plugs(re, backend, bw_ratio))
|
||||
goto error;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (!*re)
|
||||
*backend = NULL;
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/* 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 __AUDIO_RESAMPLER_DRIVER_H
|
||||
#define __AUDIO_RESAMPLER_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#define RESAMPLER_SIMD_SSE (1 << 0)
|
||||
#define RESAMPLER_SIMD_SSE2 (1 << 1)
|
||||
#define RESAMPLER_SIMD_VMX (1 << 2)
|
||||
#define RESAMPLER_SIMD_VMX128 (1 << 3)
|
||||
#define RESAMPLER_SIMD_AVX (1 << 4)
|
||||
#define RESAMPLER_SIMD_NEON (1 << 5)
|
||||
#define RESAMPLER_SIMD_SSE3 (1 << 6)
|
||||
#define RESAMPLER_SIMD_SSSE3 (1 << 7)
|
||||
#define RESAMPLER_SIMD_MMX (1 << 8)
|
||||
#define RESAMPLER_SIMD_MMXEXT (1 << 9)
|
||||
#define RESAMPLER_SIMD_SSE4 (1 << 10)
|
||||
#define RESAMPLER_SIMD_SSE42 (1 << 11)
|
||||
#define RESAMPLER_SIMD_AVX2 (1 << 12)
|
||||
#define RESAMPLER_SIMD_VFPU (1 << 13)
|
||||
#define RESAMPLER_SIMD_PS (1 << 14)
|
||||
|
||||
/* A bit-mask of all supported SIMD instruction sets.
|
||||
* Allows an implementation to pick different
|
||||
* resampler_implementation structs.
|
||||
*/
|
||||
typedef unsigned resampler_simd_mask_t;
|
||||
|
||||
#define RESAMPLER_API_VERSION 1
|
||||
|
||||
struct resampler_data
|
||||
{
|
||||
const float *data_in;
|
||||
float *data_out;
|
||||
|
||||
size_t input_frames;
|
||||
size_t output_frames;
|
||||
|
||||
double ratio;
|
||||
};
|
||||
|
||||
/* Returns true if config key was found. Otherwise,
|
||||
* returns false, and sets value to default value.
|
||||
*/
|
||||
typedef int (*resampler_config_get_float_t)(void *userdata,
|
||||
const char *key, float *value, float default_value);
|
||||
|
||||
typedef int (*resampler_config_get_int_t)(void *userdata,
|
||||
const char *key, int *value, int default_value);
|
||||
|
||||
/* Allocates an array with values. free() with resampler_config_free_t. */
|
||||
typedef int (*resampler_config_get_float_array_t)(void *userdata,
|
||||
const char *key, float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*resampler_config_get_int_array_t)(void *userdata,
|
||||
const char *key, int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values);
|
||||
|
||||
typedef int (*resampler_config_get_string_t)(void *userdata,
|
||||
const char *key, char **output, const char *default_output);
|
||||
|
||||
/* Calls free() in host runtime. Sometimes needed on Windows.
|
||||
* free() on NULL is fine. */
|
||||
typedef void (*resampler_config_free_t)(void *ptr);
|
||||
|
||||
struct resampler_config
|
||||
{
|
||||
resampler_config_get_float_t get_float;
|
||||
resampler_config_get_int_t get_int;
|
||||
|
||||
resampler_config_get_float_array_t get_float_array;
|
||||
resampler_config_get_int_array_t get_int_array;
|
||||
|
||||
resampler_config_get_string_t get_string;
|
||||
/* Avoid problems where resampler plug and host are
|
||||
* linked against different C runtimes. */
|
||||
resampler_config_free_t free;
|
||||
};
|
||||
|
||||
/* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling.
|
||||
* Corresponds to expected resampling ratio. */
|
||||
typedef void *(*resampler_init_t)(const struct resampler_config *config,
|
||||
double bandwidth_mod, resampler_simd_mask_t mask);
|
||||
|
||||
/* Frees the handle. */
|
||||
typedef void (*resampler_free_t)(void *data);
|
||||
|
||||
/* Processes input data. */
|
||||
typedef void (*resampler_process_t)(void *_data, struct resampler_data *data);
|
||||
|
||||
typedef struct rarch_resampler
|
||||
{
|
||||
resampler_init_t init;
|
||||
resampler_process_t process;
|
||||
resampler_free_t free;
|
||||
|
||||
/* Must be RESAMPLER_API_VERSION */
|
||||
unsigned api_version;
|
||||
|
||||
/* Human readable identifier of implementation. */
|
||||
const char *ident;
|
||||
|
||||
/* Computer-friendly short version of ident.
|
||||
* Lower case, no spaces and special characters, etc. */
|
||||
const char *short_ident;
|
||||
} rarch_resampler_t;
|
||||
|
||||
typedef struct audio_frame_float
|
||||
{
|
||||
float l;
|
||||
float r;
|
||||
} audio_frame_float_t;
|
||||
|
||||
extern rarch_resampler_t sinc_resampler;
|
||||
extern rarch_resampler_t CC_resampler;
|
||||
extern rarch_resampler_t nearest_resampler;
|
||||
extern rarch_resampler_t null_resampler;
|
||||
|
||||
#ifndef DONT_HAVE_STRING_LIST
|
||||
/**
|
||||
* config_get_audio_resampler_driver_options:
|
||||
*
|
||||
* Get an enumerated list of all resampler driver names, separated by '|'.
|
||||
*
|
||||
* Returns: string listing of all resampler driver names, separated by '|'.
|
||||
**/
|
||||
const char* config_get_audio_resampler_driver_options(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_handle:
|
||||
* @index : index of driver to get handle to.
|
||||
*
|
||||
* Returns: handle to audio resampler driver at index. Can be NULL
|
||||
* if nothing found.
|
||||
**/
|
||||
const void *audio_resampler_driver_find_handle(int index);
|
||||
|
||||
/**
|
||||
* audio_resampler_driver_find_ident:
|
||||
* @index : index of driver to get handle to.
|
||||
*
|
||||
* Returns: Human-readable identifier of audio resampler driver at index.
|
||||
* Can be NULL if nothing found.
|
||||
**/
|
||||
const char *audio_resampler_driver_find_ident(int index);
|
||||
|
||||
/**
|
||||
* rarch_resampler_realloc:
|
||||
* @re : Resampler handle
|
||||
* @backend : Resampler backend that is about to be set.
|
||||
* @ident : Identifier name for resampler we want.
|
||||
* @bw_ratio : Bandwidth ratio.
|
||||
*
|
||||
* Reallocates resampler. Will free previous handle before
|
||||
* allocating a new one. If ident is NULL, first resampler will be used.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
|
||||
const char *ident, double bw_ratio);
|
||||
|
||||
/* Convenience macros.
|
||||
* freep makes sure to set handles to NULL to avoid double-free
|
||||
* in rarch_resampler_realloc. */
|
||||
#define rarch_resampler_freep(backend, handle) do { \
|
||||
if (*(backend) && *(handle)) \
|
||||
(*backend)->free(*handle); \
|
||||
*backend = NULL; \
|
||||
*handle = NULL; \
|
||||
} while(0)
|
||||
|
||||
#define rarch_resampler_process(backend, handle, data) do { \
|
||||
(backend)->process(handle, data); \
|
||||
} while(0)
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
#include "libretro.h"
|
||||
extern retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -17,10 +17,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <queues/fifo_buffer.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
|
||||
#include "audio_thread_wrapper.h"
|
||||
#include "../performance.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
typedef struct audio_thread
|
||||
@@ -35,17 +36,14 @@ typedef struct audio_thread
|
||||
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)
|
||||
@@ -56,8 +54,7 @@ static void audio_thread_loop(void *data)
|
||||
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);
|
||||
thr->driver_data = thr->driver->init(thr->device, thr->out_rate, thr->latency);
|
||||
slock_lock(thr->lock);
|
||||
thr->inited = thr->driver_data ? 1 : -1;
|
||||
if (thr->inited > 0 && thr->driver->use_float)
|
||||
@@ -68,7 +65,7 @@ static void audio_thread_loop(void *data)
|
||||
if (thr->inited < 0)
|
||||
return;
|
||||
|
||||
/* Wait until we start to avoid calling
|
||||
/* Wait until we start to avoid calling
|
||||
* stop immediately after initialization. */
|
||||
slock_lock(thr->lock);
|
||||
while (thr->stopped)
|
||||
@@ -84,8 +81,8 @@ static void audio_thread_loop(void *data)
|
||||
if (!thr->alive)
|
||||
{
|
||||
scond_signal(thr->cond);
|
||||
thr->stopped_ack = true;
|
||||
slock_unlock(thr->lock);
|
||||
thr->stopped_ack = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -101,11 +98,11 @@ static void audio_thread_loop(void *data)
|
||||
|
||||
scond_wait(thr->cond, thr->lock);
|
||||
}
|
||||
thr->driver->start(thr->driver_data, thr->is_shutdown);
|
||||
thr->driver->start(thr->driver_data);
|
||||
}
|
||||
|
||||
slock_unlock(thr->lock);
|
||||
audio_driver_callback();
|
||||
audio_driver_ctl(RARCH_AUDIO_CTL_CALLBACK, NULL);
|
||||
}
|
||||
|
||||
RARCH_LOG("[Audio Thread]: Tearing down driver.\n");
|
||||
@@ -188,27 +185,26 @@ static bool audio_thread_stop(void *data)
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
audio_thread_block(thr);
|
||||
thr->is_paused = true;
|
||||
|
||||
audio_driver_disable_callback();
|
||||
audio_driver_ctl(RARCH_AUDIO_CTL_SET_CALLBACK_DISABLE, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool audio_thread_start(void *data, bool is_shutdown)
|
||||
static bool audio_thread_start(void *data)
|
||||
{
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return false;
|
||||
|
||||
audio_driver_enable_callback();
|
||||
audio_driver_ctl(RARCH_AUDIO_CTL_SET_CALLBACK_ENABLE, NULL);
|
||||
|
||||
thr->is_paused = false;
|
||||
thr->is_shutdown = is_shutdown;
|
||||
thr->is_paused = false;
|
||||
audio_thread_unblock(thr);
|
||||
|
||||
return true;
|
||||
@@ -264,7 +260,7 @@ static const audio_driver_t audio_thread = {
|
||||
};
|
||||
|
||||
/**
|
||||
* audio_init_thread:
|
||||
* rarch_threaded_audio_init:
|
||||
* @out_driver : output driver
|
||||
* @out_data : output audio data
|
||||
* @device : audio device (optional)
|
||||
@@ -274,15 +270,14 @@ static const audio_driver_t audio_thread = {
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
bool rarch_threaded_audio_init(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)
|
||||
unsigned latency, const audio_driver_t *drv)
|
||||
{
|
||||
audio_thread_t *thr = (audio_thread_t*)calloc(1, sizeof(*thr));
|
||||
if (!thr)
|
||||
@@ -291,9 +286,7 @@ bool audio_init_thread(const audio_driver_t **out_driver,
|
||||
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;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -22,12 +22,11 @@
|
||||
#include "audio_driver.h"
|
||||
|
||||
/**
|
||||
* audio_init_thread:
|
||||
* rarch_threaded_audio_init:
|
||||
* @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
|
||||
*
|
||||
@@ -37,9 +36,8 @@
|
||||
*
|
||||
* 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,
|
||||
bool rarch_threaded_audio_init(const audio_driver_t **out_driver, void **out_data,
|
||||
const char *device, unsigned out_rate, unsigned latency,
|
||||
const audio_driver_t *driver);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2014-2016 - Ali Bouhlel ( [email protected] )
|
||||
*
|
||||
* 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 <boolean.h>
|
||||
#include "audio_utils.h"
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#elif defined(__ALTIVEC__)
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "../performance.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_C:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* C implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_C(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
size_t i;
|
||||
gain = gain / 0x8000;
|
||||
for (i = 0; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_C:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* C implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_C(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
int32_t val = (int32_t)(in[i] * 0x8000);
|
||||
out[i] = (val > 0x7FFF) ? 0x7FFF :
|
||||
(val < -0x8000 ? -0x8000 : (int16_t)val);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__SSE2__)
|
||||
/**
|
||||
* audio_convert_s16_to_float_SSE2:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* SSE2 implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_SSE2(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
size_t i;
|
||||
float fgain = gain / UINT32_C(0x80000000);
|
||||
__m128 factor = _mm_set1_ps(fgain);
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128i input = _mm_loadu_si128((const __m128i *)in);
|
||||
__m128i regs_l = _mm_unpacklo_epi16(_mm_setzero_si128(), input);
|
||||
__m128i regs_r = _mm_unpackhi_epi16(_mm_setzero_si128(), input);
|
||||
__m128 output_l = _mm_mul_ps(_mm_cvtepi32_ps(regs_l), factor);
|
||||
__m128 output_r = _mm_mul_ps(_mm_cvtepi32_ps(regs_r), factor);
|
||||
|
||||
_mm_storeu_ps(out + 0, output_l);
|
||||
_mm_storeu_ps(out + 4, output_r);
|
||||
}
|
||||
|
||||
audio_convert_s16_to_float_C(out, in, samples - i, gain);
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_SSE2:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* SSE2 implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_SSE2(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
size_t i;
|
||||
__m128 factor = _mm_set1_ps((float)0x8000);
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128 input_l = _mm_loadu_ps(in + 0);
|
||||
__m128 input_r = _mm_loadu_ps(in + 4);
|
||||
__m128 res_l = _mm_mul_ps(input_l, factor);
|
||||
__m128 res_r = _mm_mul_ps(input_r, factor);
|
||||
__m128i ints_l = _mm_cvtps_epi32(res_l);
|
||||
__m128i ints_r = _mm_cvtps_epi32(res_r);
|
||||
__m128i packed = _mm_packs_epi32(ints_l, ints_r);
|
||||
|
||||
_mm_storeu_si128((__m128i *)out, packed);
|
||||
}
|
||||
|
||||
audio_convert_float_to_s16_C(out, in, samples - i);
|
||||
}
|
||||
#elif defined(__ALTIVEC__)
|
||||
/**
|
||||
* audio_convert_s16_to_float_altivec:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* AltiVec implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_altivec(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
size_t samples_in = samples;
|
||||
|
||||
/* Unaligned loads/store is a bit expensive, so we
|
||||
* optimize for the good path (very likely). */
|
||||
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
|
||||
{
|
||||
size_t i;
|
||||
const vector float gain_vec = { gain, gain , gain, gain };
|
||||
const vector float zero_vec = { 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
vector signed short input = vec_ld(0, in);
|
||||
vector signed int hi = vec_unpackh(input);
|
||||
vector signed int lo = vec_unpackl(input);
|
||||
vector float out_hi = vec_madd(vec_ctf(hi, 15), gain_vec, zero_vec);
|
||||
vector float out_lo = vec_madd(vec_ctf(lo, 15), gain_vec, zero_vec);
|
||||
|
||||
vec_st(out_hi, 0, out);
|
||||
vec_st(out_lo, 16, out);
|
||||
}
|
||||
|
||||
samples_in -= i;
|
||||
}
|
||||
audio_convert_s16_to_float_C(out, in, samples_in, gain);
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_altivec:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* AltiVec implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_altivec(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
int samples_in = samples;
|
||||
|
||||
/* Unaligned loads/store is a bit expensive,
|
||||
* so we optimize for the good path (very likely). */
|
||||
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
vector float input0 = vec_ld( 0, in);
|
||||
vector float input1 = vec_ld(16, in);
|
||||
vector signed int result0 = vec_cts(input0, 15);
|
||||
vector signed int result1 = vec_cts(input1, 15);
|
||||
vec_st(vec_packs(result0, result1), 0, out);
|
||||
}
|
||||
|
||||
samples_in -= i;
|
||||
}
|
||||
audio_convert_float_to_s16_C(out, in, samples_in);
|
||||
}
|
||||
#elif defined(__ARM_NEON__) && !defined(VITA)
|
||||
/* Avoid potential hard-float/soft-float ABI issues. */
|
||||
void audio_convert_s16_float_asm(float *out, const int16_t *in,
|
||||
size_t samples, const float *gain);
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_neon:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* ARM NEON implementation callback function.
|
||||
**/
|
||||
static void audio_convert_s16_to_float_neon(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
size_t aligned_samples = samples & ~7;
|
||||
if (aligned_samples)
|
||||
audio_convert_s16_float_asm(out, in, aligned_samples, &gain);
|
||||
|
||||
/* Could do all conversion in ASM, but keep it simple for now. */
|
||||
audio_convert_s16_to_float_C(out + aligned_samples, in + aligned_samples,
|
||||
samples - aligned_samples, gain);
|
||||
}
|
||||
|
||||
void audio_convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_neon:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* ARM NEON implementation callback function.
|
||||
**/
|
||||
static void audio_convert_float_to_s16_neon(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
size_t aligned_samples = samples & ~7;
|
||||
if (aligned_samples)
|
||||
audio_convert_float_s16_asm(out, in, aligned_samples);
|
||||
|
||||
audio_convert_float_to_s16_C(out + aligned_samples, in + aligned_samples,
|
||||
samples - aligned_samples);
|
||||
}
|
||||
#elif defined(_MIPS_ARCH_ALLEGREX)
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_ALLEGREX:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* MIPS ALLEGREX implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_ALLEGREX(float *out,
|
||||
const int16_t *in, size_t samples, float gain)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/* Make sure the buffer is 16 byte aligned, this should be the
|
||||
* default behaviour of malloc in the PSPSDK.
|
||||
* Only the output buffer can be assumed to be 16-byte aligned. */
|
||||
retro_assert(((uintptr_t)out & 0xf) == 0);
|
||||
#endif
|
||||
|
||||
size_t i;
|
||||
gain = gain / 0x8000;
|
||||
__asm__ (
|
||||
".set push \n"
|
||||
".set noreorder \n"
|
||||
"mtv %0, s200 \n"
|
||||
".set pop \n"
|
||||
::"r"(gain));
|
||||
|
||||
for (i = 0; i + 16 <= samples; i += 16)
|
||||
{
|
||||
__asm__ (
|
||||
".set push \n"
|
||||
".set noreorder \n"
|
||||
|
||||
"lv.s s100, 0(%0) \n"
|
||||
"lv.s s101, 4(%0) \n"
|
||||
"lv.s s110, 8(%0) \n"
|
||||
"lv.s s111, 12(%0) \n"
|
||||
"lv.s s120, 16(%0) \n"
|
||||
"lv.s s121, 20(%0) \n"
|
||||
"lv.s s130, 24(%0) \n"
|
||||
"lv.s s131, 28(%0) \n"
|
||||
|
||||
"vs2i.p c100, c100 \n"
|
||||
"vs2i.p c110, c110 \n"
|
||||
"vs2i.p c120, c120 \n"
|
||||
"vs2i.p c130, c130 \n"
|
||||
|
||||
"vi2f.q c100, c100, 16 \n"
|
||||
"vi2f.q c110, c110, 16 \n"
|
||||
"vi2f.q c120, c120, 16 \n"
|
||||
"vi2f.q c130, c130, 16 \n"
|
||||
|
||||
"vmscl.q e100, e100, s200 \n"
|
||||
|
||||
"sv.q c100, 0(%1) \n"
|
||||
"sv.q c110, 16(%1) \n"
|
||||
"sv.q c120, 32(%1) \n"
|
||||
"sv.q c130, 48(%1) \n"
|
||||
|
||||
".set pop \n"
|
||||
:: "r"(in + i), "r"(out + i));
|
||||
}
|
||||
|
||||
for (; i < samples; i++)
|
||||
out[i] = (float)in[i] * gain;
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_ALLEGREX:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* MIPS ALLEGREX implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_ALLEGREX(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Make sure the buffers are 16 byte aligned, this should be
|
||||
* the default behaviour of malloc in the PSPSDK.
|
||||
* Both buffers are allocated by RetroArch, so can assume alignment. */
|
||||
retro_assert(((uintptr_t)in & 0xf) == 0);
|
||||
retro_assert(((uintptr_t)out & 0xf) == 0);
|
||||
#endif
|
||||
|
||||
for (i = 0; i + 8 <= samples; i += 8)
|
||||
{
|
||||
__asm__ (
|
||||
".set push \n"
|
||||
".set noreorder \n"
|
||||
|
||||
"lv.q c100, 0(%0) \n"
|
||||
"lv.q c110, 16(%0) \n"
|
||||
|
||||
"vf2in.q c100, c100, 31 \n"
|
||||
"vf2in.q c110, c110, 31 \n"
|
||||
"vi2s.q c100, c100 \n"
|
||||
"vi2s.q c102, c110 \n"
|
||||
|
||||
"sv.q c100, 0(%1) \n"
|
||||
|
||||
".set pop \n"
|
||||
:: "r"(in + i), "r"(out + i));
|
||||
}
|
||||
|
||||
for (; i < samples; i++)
|
||||
{
|
||||
int32_t val = (int32_t)(in[i] * 0x8000);
|
||||
out[i] = (val > 0x7FFF) ? 0x7FFF :
|
||||
(val < -0x8000 ? -0x8000 : (int16_t)val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned audio_convert_get_cpu_features(void)
|
||||
{
|
||||
#ifdef RARCH_INTERNAL
|
||||
return retro_get_cpu_features();
|
||||
#else
|
||||
return perf_get_cpu_features_cb();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_convert_init_simd:
|
||||
*
|
||||
* Sets up function pointers for audio conversion
|
||||
* functions based on CPU features.
|
||||
**/
|
||||
void audio_convert_init_simd(void)
|
||||
{
|
||||
unsigned cpu = audio_convert_get_cpu_features();
|
||||
|
||||
(void)cpu;
|
||||
#if defined(__ARM_NEON__) && !defined(VITA)
|
||||
audio_convert_s16_to_float_arm = (cpu & RETRO_SIMD_NEON) ?
|
||||
audio_convert_s16_to_float_neon : audio_convert_s16_to_float_C;
|
||||
audio_convert_float_to_s16_arm = (cpu & RETRO_SIMD_NEON) ?
|
||||
audio_convert_float_to_s16_neon : audio_convert_float_to_s16_C;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_UTILS_H
|
||||
#define AUDIO_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_SSE2
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_SSE2
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_SSE2:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* SSE2 implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_SSE2(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_SSE2:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* SSE2 implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_SSE2(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#elif defined(__ALTIVEC__)
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_altivec
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_altivec
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_altivec:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* AltiVec implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_altivec(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_altivec:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* AltiVec implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_altivec(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#elif defined(__ARM_NEON__) && !defined(VITA)
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_arm
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_arm
|
||||
|
||||
void (*audio_convert_s16_to_float_arm)(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
void (*audio_convert_float_to_s16_arm)(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#elif defined(_MIPS_ARCH_ALLEGREX)
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_ALLEGREX
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_ALLEGREX
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_ALLEGREX:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* MIPS ALLEGREX implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_ALLEGREX(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_ALLEGREX:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* MIPS ALLEGREX implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_ALLEGREX(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
#else
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_C
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* audio_convert_s16_to_float_C:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
* @gain : gain applied to the audio volume
|
||||
*
|
||||
* Converts audio samples from signed integer 16-bit
|
||||
* to floating point.
|
||||
*
|
||||
* C implementation callback function.
|
||||
**/
|
||||
void audio_convert_s16_to_float_C(float *out,
|
||||
const int16_t *in, size_t samples, float gain);
|
||||
|
||||
/**
|
||||
* audio_convert_float_to_s16_C:
|
||||
* @out : output buffer
|
||||
* @in : input buffer
|
||||
* @samples : size of samples to be converted
|
||||
*
|
||||
* Converts audio samples from floating point
|
||||
* to signed integer 16-bit.
|
||||
*
|
||||
* C implementation callback function.
|
||||
**/
|
||||
void audio_convert_float_to_s16_C(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
/**
|
||||
* audio_convert_init_simd:
|
||||
*
|
||||
* Sets up function pointers for audio conversion
|
||||
* functions based on CPU features.
|
||||
**/
|
||||
void audio_convert_init_simd(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
#if defined(__ARM_NEON__)
|
||||
|
||||
#ifndef __MACH__
|
||||
.arm
|
||||
#endif
|
||||
|
||||
.align 4
|
||||
.globl audio_convert_s16_float_asm
|
||||
.globl _audio_convert_s16_float_asm
|
||||
# audio_convert_s16_float_asm(float *out, const int16_t *in, size_t samples, const float *gain)
|
||||
audio_convert_s16_float_asm:
|
||||
_audio_convert_s16_float_asm:
|
||||
# Hacky way to get a constant of 2^-15.
|
||||
# Might be faster to just load a constant from memory.
|
||||
# It's just done once however ...
|
||||
vmov.f32 q8, #0.25
|
||||
vmul.f32 q8, q8, q8
|
||||
vmul.f32 q8, q8, q8
|
||||
vmul.f32 q8, q8, q8
|
||||
vadd.f32 q8, q8, q8
|
||||
|
||||
# Apply gain
|
||||
vld1.f32 {d6[0]}, [r3]
|
||||
vmul.f32 q8, q8, d6[0]
|
||||
|
||||
1:
|
||||
# Preload here?
|
||||
vld1.s16 {q0}, [r1]!
|
||||
|
||||
# Widen to 32-bit
|
||||
vmovl.s16 q1, d0
|
||||
vmovl.s16 q2, d1
|
||||
|
||||
# Convert to float
|
||||
vcvt.f32.s32 q1, q1
|
||||
vcvt.f32.s32 q2, q2
|
||||
|
||||
vmul.f32 q1, q1, q8
|
||||
vmul.f32 q2, q2, q8
|
||||
|
||||
vst1.f32 {q1-q2}, [r0]!
|
||||
|
||||
# Guaranteed to get samples in multiples of 8.
|
||||
subs r2, r2, #8
|
||||
bne 1b
|
||||
|
||||
bx lr
|
||||
|
||||
.align 4
|
||||
.globl audio_convert_float_s16_asm
|
||||
.globl _audio_convert_float_s16_asm
|
||||
# audio_convert_float_s16_asm(int16_t *out, const float *in, size_t samples)
|
||||
audio_convert_float_s16_asm:
|
||||
_audio_convert_float_s16_asm:
|
||||
# Hacky way to get a constant of 2^15.
|
||||
# ((2^4)^2)^2 * 0.5 = 2^15
|
||||
vmov.f32 q8, #16.0
|
||||
vmov.f32 q9, #0.5
|
||||
vmul.f32 q8, q8, q8
|
||||
vmul.f32 q8, q8, q8
|
||||
vmul.f32 q8, q8, q9
|
||||
|
||||
1:
|
||||
# Preload here?
|
||||
vld1.f32 {q0-q1}, [r1]!
|
||||
|
||||
vmul.f32 q0, q0, q8
|
||||
vmul.f32 q1, q1, q8
|
||||
|
||||
vcvt.s32.f32 q0, q0
|
||||
vcvt.s32.f32 q1, q1
|
||||
|
||||
vqmovn.s32 d4, q0
|
||||
vqmovn.s32 d5, q1
|
||||
|
||||
vst1.f32 {d4-d5}, [r0]!
|
||||
|
||||
# Guaranteed to get samples in multiples of 8.
|
||||
subs r2, r2, #8
|
||||
bne 1b
|
||||
|
||||
bx lr
|
||||
|
||||
#endif
|
||||
+78
-159
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -16,12 +15,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <lists/string_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct alsa
|
||||
@@ -29,7 +26,6 @@ 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;
|
||||
@@ -47,28 +43,27 @@ static bool find_float_format(snd_pcm_t *pcm, void *data)
|
||||
|
||||
if (snd_pcm_hw_params_test_format(pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
{
|
||||
RARCH_LOG("[ALSA]: Using floating point format.\n");
|
||||
RARCH_LOG("ALSA: Using floating point format.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
RARCH_LOG("[ALSA]: Using signed 16-bit format.\n");
|
||||
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)
|
||||
static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
snd_pcm_format_t format;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
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));
|
||||
|
||||
unsigned latency_usec = latency * 1000;
|
||||
unsigned channels = 2;
|
||||
unsigned periods = 4;
|
||||
|
||||
const char *alsa_dev = "default";
|
||||
alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
|
||||
if (!alsa)
|
||||
return NULL;
|
||||
@@ -93,23 +88,15 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency,
|
||||
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)
|
||||
if (snd_pcm_hw_params_set_rate(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;
|
||||
@@ -121,22 +108,22 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency,
|
||||
if (snd_pcm_hw_params(alsa->pcm, params) < 0)
|
||||
goto error;
|
||||
|
||||
/* Shouldn't have to bother with this,
|
||||
/* 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);
|
||||
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);
|
||||
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");
|
||||
RARCH_LOG("ALSA: Can pause: %s.\n", alsa->can_pause ? "yes" : "no");
|
||||
|
||||
if (snd_pcm_sw_params_malloc(&sw_params) < 0)
|
||||
goto error;
|
||||
@@ -157,7 +144,7 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency,
|
||||
return alsa;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[ALSA]: Failed to initialize...\n");
|
||||
RARCH_ERR("ALSA: Failed to initialize...\n");
|
||||
if (params)
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
||||
@@ -167,92 +154,80 @@ error:
|
||||
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 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_;
|
||||
bool eagain_retry = true;
|
||||
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);
|
||||
snd_pcm_sframes_t size = snd_pcm_bytes_to_frames(alsa->pcm, size_);
|
||||
|
||||
if (alsa->nonblock)
|
||||
while (size)
|
||||
{
|
||||
while (size)
|
||||
snd_pcm_sframes_t frames;
|
||||
|
||||
if (!alsa->nonblock)
|
||||
{
|
||||
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)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: (#1) Failed to recover from error (%s)\n",
|
||||
snd_strerror(rc));
|
||||
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;
|
||||
}
|
||||
|
||||
frames = snd_pcm_writei(alsa->pcm, buf, size);
|
||||
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (frames == -EAGAIN && !alsa->nonblock)
|
||||
{
|
||||
/* Definitely not supposed to happen. */
|
||||
RARCH_WARN("[ALSA]: poll() was signaled, but EAGAIN returned from write.\n"
|
||||
"Your ALSA driver might be subtly broken.\n");
|
||||
|
||||
if (eagain_retry)
|
||||
{
|
||||
eagain_retry = false;
|
||||
continue;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
else if (frames == -EAGAIN) /* Expected if we're running nonblock. */
|
||||
return written;
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n",
|
||||
snd_strerror(frames));
|
||||
return -1;
|
||||
}
|
||||
|
||||
written += frames;
|
||||
buf += (frames << 1) *
|
||||
(alsa->has_float ? sizeof(float) : sizeof(int16_t));
|
||||
size -= frames;
|
||||
}
|
||||
|
||||
return written;
|
||||
@@ -290,7 +265,7 @@ static void alsa_set_nonblock_state(void *data, bool state)
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool alsa_start(void *data, bool is_shutdown)
|
||||
static bool alsa_start(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
@@ -321,22 +296,26 @@ static void alsa_free(void *data)
|
||||
{
|
||||
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;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
snd_pcm_sframes_t avail = snd_pcm_avail(alsa->pcm);
|
||||
|
||||
if (avail < 0)
|
||||
{
|
||||
#if 0
|
||||
RARCH_WARN("[ALSA]: snd_pcm_avail() failed: %s\n",
|
||||
snd_strerror(avail));
|
||||
#endif
|
||||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
return FRAMES_TO_BYTES(avail, alsa->frame_bits);
|
||||
return snd_pcm_frames_to_bytes(alsa->pcm, avail);
|
||||
}
|
||||
|
||||
static size_t alsa_buffer_size(void *data)
|
||||
@@ -345,64 +324,6 @@ static size_t alsa_buffer_size(void *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,
|
||||
@@ -413,8 +334,6 @@ audio_driver_t audio_alsa = {
|
||||
alsa_free,
|
||||
alsa_use_float,
|
||||
"alsa",
|
||||
alsa_device_list_new,
|
||||
alsa_device_list_free,
|
||||
alsa_write_avail,
|
||||
alsa_buffer_size,
|
||||
};
|
||||
+17
-19
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -17,9 +17,9 @@
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
#define ALSA_PCM_NEW_SW_PARAMS_API
|
||||
#include <sys/asoundlib.h>
|
||||
#include <retro_math.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
#define MAX_FRAG_SIZE 3072
|
||||
#define DEFAULT_RATE 48000
|
||||
@@ -46,14 +46,14 @@ typedef struct alsa
|
||||
typedef long snd_pcm_sframes_t;
|
||||
|
||||
static void *alsa_qsa_init(const char *device,
|
||||
unsigned rate, unsigned latency, unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
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_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
snd_pcm_channel_info_t pi;
|
||||
snd_pcm_channel_setup_t setup = {0};
|
||||
settings_t *settings = config_get_ptr();
|
||||
alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
if (!alsa)
|
||||
return NULL;
|
||||
|
||||
@@ -122,8 +122,8 @@ static void *alsa_qsa_init(const char *device,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (block_frames)
|
||||
alsa->buf_size = block_frames * 4;
|
||||
if (settings->audio.block_frames)
|
||||
alsa->buf_size = settings->audio.block_frames * 4;
|
||||
else
|
||||
alsa->buf_size = next_pow2(32 * latency);
|
||||
|
||||
@@ -164,9 +164,9 @@ error:
|
||||
|
||||
static int check_pcm_status(void *data, int channel_type)
|
||||
{
|
||||
snd_pcm_channel_status_t status;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
int ret = EOK;
|
||||
snd_pcm_channel_status_t status;
|
||||
int ret = EOK;
|
||||
|
||||
memset(&status, 0, sizeof (status));
|
||||
status.channel = channel_type;
|
||||
@@ -231,7 +231,7 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size)
|
||||
|
||||
if (avail_write)
|
||||
{
|
||||
memcpy(alsa->buffer[alsa->buffer_index] +
|
||||
memcpy(alsa->buffer[alsa->buffer_index] +
|
||||
alsa->buffer_ptr, buf, avail_write);
|
||||
|
||||
alsa->buffer_ptr += avail_write;
|
||||
@@ -291,7 +291,7 @@ static bool alsa_qsa_alive(void *data)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_start(void *data, bool is_shutdown)
|
||||
static bool alsa_qsa_start(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
@@ -355,8 +355,8 @@ static void alsa_qsa_free(void *data)
|
||||
static size_t alsa_qsa_write_avail(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
size_t avail = (alsa->buf_count -
|
||||
(int)alsa->buffered_blocks - 1) * alsa->buf_size +
|
||||
size_t avail = (alsa->buf_count -
|
||||
(int)alsa->buffered_blocks - 1) * alsa->buf_size +
|
||||
(alsa->buf_size - (int)alsa->buffer_ptr);
|
||||
return avail;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ static size_t alsa_qsa_write_avail(void *data)
|
||||
static size_t alsa_qsa_buffer_size(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->buf_size * alsa->buf_count;
|
||||
return alsa->buf_size * alsa->buf_count;
|
||||
}
|
||||
|
||||
audio_driver_t audio_alsa = {
|
||||
@@ -377,8 +377,6 @@ audio_driver_t audio_alsa = {
|
||||
alsa_qsa_free,
|
||||
alsa_qsa_use_float,
|
||||
"alsa",
|
||||
NULL,
|
||||
NULL,
|
||||
alsa_qsa_write_avail,
|
||||
alsa_qsa_buffer_size,
|
||||
};
|
||||
+24
-87
@@ -1,7 +1,7 @@
|
||||
/* 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.
|
||||
@@ -16,19 +16,18 @@
|
||||
|
||||
#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 <queues/fifo_buffer.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define TRY_ALSA(x) if (x < 0) \
|
||||
goto error;
|
||||
#define TRY_ALSA(x) if (x < 0) { \
|
||||
goto error; \
|
||||
}
|
||||
|
||||
typedef struct alsa_thread
|
||||
{
|
||||
@@ -52,8 +51,8 @@ typedef struct alsa_thread
|
||||
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);
|
||||
|
||||
uint8_t *buf = (uint8_t *)calloc(1, alsa->period_size);
|
||||
if (!buf)
|
||||
{
|
||||
RARCH_ERR("failed to allocate audio buffer");
|
||||
@@ -77,7 +76,7 @@ static void alsa_worker_thread(void *data)
|
||||
|
||||
frames = snd_pcm_writei(alsa->pcm, buf, alsa->period_frames);
|
||||
|
||||
if (frames == -EPIPE || frames == -EINTR ||
|
||||
if (frames == -EPIPE || frames == -EINTR ||
|
||||
frames == -ESTRPIPE)
|
||||
{
|
||||
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
|
||||
@@ -91,7 +90,7 @@ static void alsa_worker_thread(void *data)
|
||||
}
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Unknown error occurred (%s).\n",
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n",
|
||||
snd_strerror(frames));
|
||||
break;
|
||||
}
|
||||
@@ -131,9 +130,7 @@ static void alsa_thread_free(void *data)
|
||||
{
|
||||
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)
|
||||
@@ -154,20 +151,21 @@ static void alsa_thread_free(void *data)
|
||||
}
|
||||
|
||||
static void *alsa_thread_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)calloc(1, sizeof(alsa_thread_t));
|
||||
|
||||
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;
|
||||
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;
|
||||
@@ -192,7 +190,7 @@ static void *alsa_thread_init(const char *device,
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
/* Shouldn't have to bother with this,
|
||||
/* 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(
|
||||
@@ -284,8 +282,7 @@ static ssize_t alsa_thread_write(void *data, const void *buf, size_t size)
|
||||
else
|
||||
{
|
||||
size_t write_amt = MIN(size - written, avail);
|
||||
fifo_write(alsa->buffer,
|
||||
(const char*)buf + written, write_amt);
|
||||
fifo_write(alsa->buffer, (const char*)buf + written, write_amt);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
written += write_amt;
|
||||
}
|
||||
@@ -317,7 +314,7 @@ static void alsa_thread_set_nonblock_state(void *data, bool state)
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool alsa_thread_start(void *data, bool is_shutdown)
|
||||
static bool alsa_thread_start(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
|
||||
@@ -345,64 +342,6 @@ static size_t alsa_thread_buffer_size(void *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_alsathread = {
|
||||
alsa_thread_init,
|
||||
alsa_thread_write,
|
||||
@@ -413,8 +352,6 @@ audio_driver_t audio_alsathread = {
|
||||
alsa_thread_free,
|
||||
alsa_thread_use_float,
|
||||
"alsathread",
|
||||
alsa_device_list_new,
|
||||
alsa_device_list_free,
|
||||
alsa_thread_write_avail,
|
||||
alsa_thread_buffer_size,
|
||||
};
|
||||
+58
-66
@@ -1,7 +1,7 @@
|
||||
/* 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.
|
||||
@@ -27,20 +27,29 @@
|
||||
#include <AudioUnit/AUComponent.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <queues/fifo_buffer.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <retro_endianness.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__)
|
||||
|
||||
#ifndef OSX_PPC
|
||||
#define OSX_PPC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct coreaudio
|
||||
{
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#ifdef OSX_PPC
|
||||
ComponentInstance dev;
|
||||
#else
|
||||
AudioComponentInstance dev;
|
||||
@@ -65,7 +74,7 @@ static void coreaudio_free(void *data)
|
||||
if (dev->dev_alive)
|
||||
{
|
||||
AudioOutputUnitStop(dev->dev);
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#ifdef OSX_PPC
|
||||
CloseComponent(dev->dev);
|
||||
#else
|
||||
AudioComponentInstanceDispose(dev->dev);
|
||||
@@ -86,19 +95,21 @@ static OSStatus audio_write_cb(void *userdata,
|
||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||
UInt32 number_frames, AudioBufferList *io_data)
|
||||
{
|
||||
void *outbuf;
|
||||
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)
|
||||
if (!io_data)
|
||||
return noErr;
|
||||
if (io_data->mNumberBuffers != 1)
|
||||
return noErr;
|
||||
|
||||
write_avail = io_data->mBuffers[0].mDataByteSize;
|
||||
outbuf = io_data->mBuffers[0].mData;
|
||||
outbuf = io_data->mBuffers[0].mData;
|
||||
|
||||
slock_lock(dev->lock);
|
||||
|
||||
@@ -112,7 +123,7 @@ static OSStatus audio_write_cb(void *userdata,
|
||||
slock_unlock(dev->lock);
|
||||
|
||||
/* Technically possible to deadlock without. */
|
||||
scond_signal(dev->cond);
|
||||
scond_signal(dev->cond);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -132,47 +143,41 @@ static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
|
||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||
{
|
||||
unsigned i;
|
||||
UInt32 deviceCount;
|
||||
AudioObjectPropertyAddress propaddr;
|
||||
AudioDeviceID *devices = NULL;
|
||||
UInt32 size = 0;
|
||||
AudioDeviceID *devices;
|
||||
AudioObjectPropertyAddress propaddr =
|
||||
{
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
propaddr.mSelector = kAudioHardwarePropertyDevices;
|
||||
#if MAC_OS_X_VERSION_10_12
|
||||
propaddr.mScope = kAudioObjectPropertyScopeOutput;
|
||||
#else
|
||||
propaddr.mScope = kAudioObjectPropertyScopeGlobal;
|
||||
#endif
|
||||
propaddr.mElement = kAudioObjectPropertyElementMaster;
|
||||
UInt32 size = 0, deviceCount;
|
||||
|
||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||
&propaddr, 0, 0, &size) != noErr)
|
||||
return;
|
||||
|
||||
deviceCount = size / sizeof(AudioDeviceID);
|
||||
devices = (AudioDeviceID*)malloc(size);
|
||||
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.mScope = kAudioDevicePropertyScopeOutput;
|
||||
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
||||
size = 1024;
|
||||
|
||||
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
|
||||
&propaddr, 0, 0, &size, device_name) == noErr
|
||||
&& string_is_equal(device_name, device))
|
||||
{
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||
goto done;
|
||||
}
|
||||
@@ -184,14 +189,12 @@ done:
|
||||
#endif
|
||||
|
||||
static void *coreaudio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
size_t fifo_size;
|
||||
UInt32 i_size;
|
||||
AudioStreamBasicDescription real_desc;
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#ifdef OSX_PPC
|
||||
Component comp;
|
||||
#else
|
||||
AudioComponent comp;
|
||||
@@ -203,19 +206,21 @@ static void *coreaudio_init(const char *device,
|
||||
AudioStreamBasicDescription stream_desc = {0};
|
||||
bool component_unavailable = false;
|
||||
static bool session_initialized = false;
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
coreaudio_t *dev = NULL;
|
||||
#ifdef OSX_PPC
|
||||
ComponentDescription desc = {0};
|
||||
#else
|
||||
AudioComponentDescription desc = {0};
|
||||
#endif
|
||||
coreaudio_t *dev = (coreaudio_t*)
|
||||
calloc(1, sizeof(*dev));
|
||||
if (!dev)
|
||||
return NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
(void)session_initialized;
|
||||
(void)device;
|
||||
|
||||
dev = (coreaudio_t*)calloc(1, sizeof(*dev));
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->lock = slock_new();
|
||||
dev->cond = scond_new();
|
||||
|
||||
@@ -237,15 +242,15 @@ static void *coreaudio_init(const char *device,
|
||||
#endif
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#ifdef OSX_PPC
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
#else
|
||||
comp = AudioComponentFindNext(NULL, &desc);
|
||||
#endif
|
||||
if (comp == NULL)
|
||||
goto error;
|
||||
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
|
||||
#ifdef OSX_PPC
|
||||
component_unavailable = (OpenAComponent(comp, &dev->dev) != noErr);
|
||||
#else
|
||||
component_unavailable = (AudioComponentInstanceNew(comp, &dev->dev) != noErr);
|
||||
@@ -259,7 +264,7 @@ static void *coreaudio_init(const char *device,
|
||||
choose_output_device(dev, device);
|
||||
#endif
|
||||
|
||||
dev->dev_alive = true;
|
||||
dev->dev_alive = true;
|
||||
|
||||
/* Set audio format */
|
||||
stream_desc.mSampleRate = rate;
|
||||
@@ -269,17 +274,17 @@ static void *coreaudio_init(const char *device,
|
||||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||
stream_desc.mFramesPerPacket = 1;
|
||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat |
|
||||
kAudioFormatFlagIsPacked | (is_little_endian() ?
|
||||
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,
|
||||
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
|
||||
goto error;
|
||||
|
||||
@@ -294,7 +299,7 @@ static void *coreaudio_init(const char *device,
|
||||
|
||||
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n",
|
||||
(float)real_desc.mSampleRate);
|
||||
*new_rate = real_desc.mSampleRate;
|
||||
settings->audio.out_rate = real_desc.mSampleRate;
|
||||
|
||||
/* Set channel layout (fails on iOS). */
|
||||
#ifndef TARGET_OS_IPHONE
|
||||
@@ -315,11 +320,11 @@ static void *coreaudio_init(const char *device,
|
||||
if (AudioUnitInitialize(dev->dev) != noErr)
|
||||
goto error;
|
||||
|
||||
fifo_size = (latency * (*new_rate)) / 1000;
|
||||
fifo_size *= 2 * sizeof(float);
|
||||
dev->buffer_size = fifo_size;
|
||||
fifo_size = (latency * settings->audio.out_rate) / 1000;
|
||||
fifo_size *= 2 * sizeof(float);
|
||||
dev->buffer_size = fifo_size;
|
||||
|
||||
dev->buffer = fifo_new(fifo_size);
|
||||
dev->buffer = fifo_new(fifo_size);
|
||||
if (!dev->buffer)
|
||||
goto error;
|
||||
|
||||
@@ -339,9 +344,9 @@ error:
|
||||
|
||||
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
size_t written = 0;
|
||||
|
||||
while (!g_interrupted && size > 0)
|
||||
{
|
||||
@@ -402,7 +407,7 @@ static bool coreaudio_stop(void *data)
|
||||
return dev->is_paused ? true : false;
|
||||
}
|
||||
|
||||
static bool coreaudio_start(void *data, bool is_shutdown)
|
||||
static bool coreaudio_start(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (!dev)
|
||||
@@ -435,17 +440,6 @@ static size_t coreaudio_buffer_size(void *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,
|
||||
@@ -456,8 +450,6 @@ audio_driver_t audio_coreaudio = {
|
||||
coreaudio_free,
|
||||
coreaudio_use_float,
|
||||
"coreaudio",
|
||||
coreaudio_device_list_new,
|
||||
coreaudio_device_list_free,
|
||||
coreaudio_write_avail,
|
||||
coreaudio_buffer_size,
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2017 - Ali Bouhlel
|
||||
* Copyright (C) 2014-2016 - 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-
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../performance.h"
|
||||
#include "../../runloop.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -48,40 +48,37 @@ typedef struct
|
||||
|
||||
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;
|
||||
uint32_t samples_played;
|
||||
uint64_t current_tick;
|
||||
|
||||
current_tick = svcGetSystemTick();
|
||||
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)
|
||||
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;
|
||||
u32 paddr0 = 0, paddr1 = 0;
|
||||
|
||||
int encoding = (flags >> 12) & 3;
|
||||
int loopMode = (flags >> 10) & 3;
|
||||
|
||||
if (!loopMode) flags |= SOUND_ONE_SHOT;
|
||||
|
||||
if (encoding != CSND_ENCODING_PSG)
|
||||
{
|
||||
if (data0)
|
||||
paddr0 = osConvertVirtToPhys(data0);
|
||||
if (data1)
|
||||
paddr1 = osConvertVirtToPhys(data1);
|
||||
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];
|
||||
int adpcmIndex = ((u8*)data0)[-2];
|
||||
CSND_SetAdpcmState(chn, 0, adpcmSample, adpcmIndex);
|
||||
}
|
||||
}
|
||||
@@ -94,8 +91,7 @@ Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan,
|
||||
|
||||
if (loopMode == CSND_LOOPMODE_NORMAL && paddr1 > paddr0)
|
||||
{
|
||||
/* Now that the first block is playing,
|
||||
* configure the size of the subsequent blocks */
|
||||
// Now that the first block is playing, configure the size of the subsequent blocks
|
||||
size -= paddr1 - paddr0;
|
||||
CSND_SetBlock(chn, 1, paddr1, size);
|
||||
}
|
||||
@@ -103,11 +99,10 @@ Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *ctr_csnd_audio_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *ctr_csnd_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
ctr_csnd_audio_t *ctr = (ctr_csnd_audio_t*)calloc(1, sizeof(ctr_csnd_audio_t));
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!ctr)
|
||||
return NULL;
|
||||
@@ -116,7 +111,7 @@ static void *ctr_csnd_audio_init(const char *device, unsigned rate, unsigned lat
|
||||
(void)rate;
|
||||
(void)latency;
|
||||
|
||||
*new_rate = CTR_CSND_AUDIO_RATE;
|
||||
settings->audio.out_rate = CTR_CSND_AUDIO_RATE;
|
||||
|
||||
ctr->l = linearAlloc(CTR_CSND_AUDIO_SIZE);
|
||||
ctr->r = linearAlloc(CTR_CSND_AUDIO_SIZE);
|
||||
@@ -149,9 +144,7 @@ static void ctr_csnd_audio_free(void *data)
|
||||
{
|
||||
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
|
||||
|
||||
#if 0
|
||||
csndExit();
|
||||
#endif
|
||||
// csndExit();
|
||||
CSND_SetPlayState(0x8, 0);
|
||||
CSND_SetPlayState(0x9, 0);
|
||||
csndExecCmds(false);
|
||||
@@ -165,16 +158,20 @@ static void ctr_csnd_audio_free(void *data)
|
||||
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;
|
||||
uint32_t samples_played = 0;
|
||||
uint64_t current_tick = 0;
|
||||
static struct retro_perf_counter ctraudio_f = {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;
|
||||
|
||||
rarch_perf_init(&ctraudio_f, "ctraudio_f");
|
||||
retro_perf_start(&ctraudio_f);
|
||||
|
||||
ctr_csnd_audio_update_playpos(ctr);
|
||||
|
||||
if((((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 2)) ||
|
||||
@@ -205,11 +202,13 @@ static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size)
|
||||
GSPGPU_FlushDataCache(ctr->l, CTR_CSND_AUDIO_SIZE);
|
||||
GSPGPU_FlushDataCache(ctr->r, CTR_CSND_AUDIO_SIZE);
|
||||
|
||||
retro_perf_stop(&ctraudio_f);
|
||||
|
||||
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
|
||||
@@ -238,13 +237,14 @@ static bool ctr_csnd_audio_alive(void *data)
|
||||
return ctr->playing;
|
||||
}
|
||||
|
||||
static bool ctr_csnd_audio_start(void *data, bool is_shutdown)
|
||||
static bool ctr_csnd_audio_start(void *data)
|
||||
{
|
||||
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
|
||||
|
||||
/* Prevents restarting audio when the menu
|
||||
* is toggled off on shutdown */
|
||||
if (is_shutdown)
|
||||
|
||||
if (runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL))
|
||||
return true;
|
||||
|
||||
#if 0
|
||||
@@ -300,8 +300,6 @@ audio_driver_t audio_ctr_csnd = {
|
||||
ctr_csnd_audio_free,
|
||||
ctr_csnd_audio_use_float,
|
||||
"csnd",
|
||||
NULL,
|
||||
NULL,
|
||||
ctr_csnd_audio_write_avail,
|
||||
ctr_csnd_audio_buffer_size
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2017 - Ali Bouhlel
|
||||
* Copyright (C) 2014-2016 - 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-
|
||||
@@ -15,9 +15,11 @@
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../performance.h"
|
||||
#include "../../runloop.h"
|
||||
#include "../../ctr/ctr_debug.h"
|
||||
|
||||
typedef struct
|
||||
@@ -35,11 +37,10 @@ typedef struct
|
||||
#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)
|
||||
static void *ctr_dsp_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
ctr_dsp_audio_t *ctr = NULL;
|
||||
ctr_dsp_audio_t *ctr;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
(void)device;
|
||||
(void)rate;
|
||||
@@ -53,12 +54,12 @@ static void *ctr_dsp_audio_init(const char *device, unsigned rate, unsigned late
|
||||
if (!ctr)
|
||||
return NULL;
|
||||
|
||||
*new_rate = 32730;
|
||||
settings->audio.out_rate = 32730;
|
||||
|
||||
ctr->channel = 0;
|
||||
|
||||
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
|
||||
ndspSetClippingMode(NDSP_CLIP_SOFT); /* ?? */
|
||||
ndspSetClippingMode(NDSP_CLIP_SOFT); //??
|
||||
ndspSetOutputCount(1);
|
||||
ndspChnReset(ctr->channel);
|
||||
ndspChnSetFormat(ctr->channel, NDSP_FORMAT_STEREO_PCM16);
|
||||
@@ -94,9 +95,10 @@ static void ctr_dsp_audio_free(void *data)
|
||||
|
||||
static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
static struct retro_perf_counter ctraudio_dsp_f = {0};
|
||||
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
|
||||
u32 pos;
|
||||
ctr_dsp_audio_t * ctr = (ctr_dsp_audio_t*)data;
|
||||
uint32_t sample_pos = ndspChnGetSamplePos(ctr->channel);
|
||||
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)) ||
|
||||
@@ -114,6 +116,9 @@ static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
rarch_perf_init(&ctraudio_dsp_f, "ctraudio_dsp_f");
|
||||
retro_perf_start(&ctraudio_dsp_f);
|
||||
|
||||
pos = ctr->pos << 2;
|
||||
|
||||
if((pos + size) > CTR_DSP_AUDIO_SIZE)
|
||||
@@ -135,6 +140,8 @@ static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
|
||||
ctr->pos += size >> 2;
|
||||
ctr->pos &= CTR_DSP_AUDIO_COUNT_MASK;
|
||||
|
||||
retro_perf_stop(&ctraudio_dsp_f);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -154,13 +161,14 @@ static bool ctr_dsp_audio_alive(void *data)
|
||||
return ctr->playing;
|
||||
}
|
||||
|
||||
static bool ctr_dsp_audio_start(void *data, bool is_shutdown)
|
||||
static bool ctr_dsp_audio_start(void *data)
|
||||
{
|
||||
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
|
||||
|
||||
/* Prevents restarting audio when the menu
|
||||
* is toggled off on shutdown */
|
||||
if (is_shutdown)
|
||||
|
||||
if (runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL))
|
||||
return true;
|
||||
|
||||
ndspSetMasterVol(1.0);
|
||||
@@ -206,8 +214,6 @@ audio_driver_t audio_ctr_dsp = {
|
||||
ctr_dsp_audio_free,
|
||||
ctr_dsp_audio_use_float,
|
||||
"dsp",
|
||||
NULL,
|
||||
NULL,
|
||||
ctr_dsp_audio_write_avail,
|
||||
ctr_dsp_audio_buffer_size
|
||||
};
|
||||
|
||||
+22
-59
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
#ifndef _XBOX
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <mmreg.h>
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
#include <dsound.h>
|
||||
@@ -31,13 +31,11 @@
|
||||
|
||||
#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 <queues/fifo_buffer.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
@@ -61,11 +59,7 @@ typedef struct dsound
|
||||
CRITICAL_SECTION crit;
|
||||
|
||||
HANDLE event;
|
||||
#ifdef HAVE_THREADS
|
||||
sthread_t *thread;
|
||||
#else
|
||||
HANDLE thread;
|
||||
#endif
|
||||
|
||||
unsigned buffer_size;
|
||||
|
||||
@@ -74,8 +68,7 @@ typedef struct dsound
|
||||
volatile bool thread_alive;
|
||||
} dsound_t;
|
||||
|
||||
static INLINE unsigned write_avail(unsigned read_ptr,
|
||||
unsigned write_ptr, unsigned buffer_size)
|
||||
static INLINE unsigned write_avail(unsigned read_ptr, unsigned write_ptr, unsigned buffer_size)
|
||||
{
|
||||
return (read_ptr + buffer_size - write_ptr) % buffer_size;
|
||||
}
|
||||
@@ -98,8 +91,8 @@ struct audio_lock
|
||||
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,
|
||||
const char *err;
|
||||
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
||||
®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||
|
||||
if (res == DSERR_BUFFERLOST)
|
||||
@@ -139,15 +132,10 @@ static INLINE bool grab_region(dsound_t *ds, uint32_t write_ptr,
|
||||
|
||||
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);
|
||||
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;
|
||||
@@ -162,7 +150,7 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
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);
|
||||
@@ -171,12 +159,12 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
|
||||
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,
|
||||
/* 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
|
||||
* but it is not guaranteed to work, so use high
|
||||
* priority sleeping patterns.
|
||||
*/
|
||||
retro_sleep(1);
|
||||
@@ -192,7 +180,7 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
|
||||
if (fifo_avail < CHUNK_SIZE)
|
||||
{
|
||||
/* Got space to write, but nothing in FIFO (underrun),
|
||||
/* Got space to write, but nothing in FIFO (underrun),
|
||||
* fill block with silence. */
|
||||
|
||||
memset(region.chunk1, 0, region.size1);
|
||||
@@ -201,7 +189,7 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
release_region(ds, ®ion);
|
||||
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* All is good. Pull from it and notify FIFO. */
|
||||
|
||||
@@ -229,13 +217,7 @@ static void dsound_stop_thread(dsound_t *ds)
|
||||
|
||||
ds->thread_alive = false;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
sthread_join(ds->thread);
|
||||
#else
|
||||
WaitForSingleObject(ds->thread, INFINITE);
|
||||
CloseHandle(ds->thread);
|
||||
#endif
|
||||
|
||||
ds->thread = NULL;
|
||||
}
|
||||
|
||||
@@ -244,12 +226,7 @@ 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
|
||||
ds->thread = sthread_create(dsound_thread, ds);
|
||||
if (!ds->thread)
|
||||
return false;
|
||||
}
|
||||
@@ -259,9 +236,8 @@ static bool dsound_start_thread(dsound_t *ds)
|
||||
|
||||
static void dsound_clear_buffer(dsound_t *ds)
|
||||
{
|
||||
void *ptr;
|
||||
DWORD size;
|
||||
void *ptr = NULL;
|
||||
|
||||
IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
|
||||
|
||||
if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size,
|
||||
@@ -282,12 +258,7 @@ static void dsound_free(void *data)
|
||||
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);
|
||||
@@ -329,9 +300,7 @@ static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOI
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void *dsound_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *dsound_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
WAVEFORMATEX wfx = {0};
|
||||
DSBUFFERDESC bufdesc = {0};
|
||||
@@ -348,11 +317,7 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency,
|
||||
|
||||
RARCH_LOG("DirectSound devices:\n");
|
||||
#ifndef _XBOX
|
||||
#ifdef UNICODE
|
||||
DirectSoundEnumerate((LPDSENUMCALLBACKW)enumerate_cb, &dev);
|
||||
#else
|
||||
DirectSoundEnumerate((LPDSENUMCALLBACKA)enumerate_cb, &dev);
|
||||
#endif
|
||||
DirectSoundEnumerate(enumerate_cb, &dev);
|
||||
#endif
|
||||
|
||||
if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
|
||||
@@ -412,7 +377,7 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency,
|
||||
return ds;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[DirectSound] Error occurred in init.\n");
|
||||
RARCH_ERR("[DirectSound] Error occured in init.\n");
|
||||
dsound_free(ds);
|
||||
return NULL;
|
||||
}
|
||||
@@ -427,7 +392,7 @@ static bool dsound_stop(void *data)
|
||||
return (ds->is_paused) ? true : false;
|
||||
}
|
||||
|
||||
static bool dsound_start(void *data, bool is_shutdown)
|
||||
static bool dsound_start(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
|
||||
@@ -459,8 +424,8 @@ static void dsound_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static ssize_t dsound_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
size_t written = 0;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
size_t written = 0;
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
if (!ds->thread_alive)
|
||||
@@ -524,8 +489,6 @@ audio_driver_t audio_dsound = {
|
||||
dsound_free,
|
||||
dsound_use_float,
|
||||
"dsound",
|
||||
NULL,
|
||||
NULL,
|
||||
dsound_write_avail,
|
||||
dsound_buffer_size,
|
||||
};
|
||||
+16
-19
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <retro_inline.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../defines/gx_defines.h"
|
||||
|
||||
typedef struct
|
||||
@@ -44,8 +45,8 @@ typedef struct
|
||||
bool is_paused;
|
||||
} gx_audio_t;
|
||||
|
||||
static volatile gx_audio_t *gx_audio_data = NULL;
|
||||
static volatile bool stop_audio = false;
|
||||
static volatile gx_audio_t *gx_audio_data;
|
||||
static volatile bool stop_audio;
|
||||
|
||||
static void dma_callback(void)
|
||||
{
|
||||
@@ -68,10 +69,9 @@ static void dma_callback(void)
|
||||
}
|
||||
|
||||
static void *gx_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
gx_audio_t *wa = (gx_audio_t*)memalign(32, sizeof(*wa));
|
||||
if (!wa)
|
||||
return NULL;
|
||||
@@ -83,16 +83,15 @@ static void *gx_audio_init(const char *device,
|
||||
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))
|
||||
if (rate < 33000)
|
||||
{
|
||||
AISetDSPSampleRate(AI_SAMPLERATE_32KHZ);
|
||||
*new_rate = 32000;
|
||||
settings->audio.out_rate = 32000;
|
||||
}
|
||||
else //ranges 32001-39999 (in settings going up from 32000) and 48000-max (default high) -> set to 48000 hz
|
||||
else
|
||||
{
|
||||
AISetDSPSampleRate(AI_SAMPLERATE_48KHZ);
|
||||
*new_rate = 48000;
|
||||
settings->audio.out_rate = 48000;
|
||||
}
|
||||
|
||||
OSInitThreadQueue(&wa->cond);
|
||||
@@ -119,9 +118,9 @@ static INLINE void copy_swapped(uint32_t * restrict dst,
|
||||
|
||||
static ssize_t gx_audio_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
size_t frames = size >> 2;
|
||||
size_t frames = size >> 2;
|
||||
const uint32_t *buf = buf_;
|
||||
gx_audio_t *wa = data;
|
||||
gx_audio_t *wa = data;
|
||||
|
||||
while (frames)
|
||||
{
|
||||
@@ -130,9 +129,9 @@ static ssize_t gx_audio_write(void *data, const void *buf_, size_t size)
|
||||
if (frames < to_write)
|
||||
to_write = frames;
|
||||
|
||||
/* FIXME: Nonblocking audio should break out of loop
|
||||
/* FIXME: Nonblocking audio should break out of loop
|
||||
* when it has nothing to write. */
|
||||
while ((wa->dma_write == wa->dma_next ||
|
||||
while ((wa->dma_write == wa->dma_next ||
|
||||
wa->dma_write == wa->dma_busy) && !wa->nonblock)
|
||||
OSSleepThread(wa->cond);
|
||||
|
||||
@@ -174,7 +173,7 @@ static void gx_audio_set_nonblock_state(void *data, bool state)
|
||||
wa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool gx_audio_start(void *data, bool is_shutdown)
|
||||
static bool gx_audio_start(void *data)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)data;
|
||||
|
||||
@@ -242,8 +241,6 @@ audio_driver_t audio_gx = {
|
||||
gx_audio_free,
|
||||
gx_audio_use_float,
|
||||
"gx",
|
||||
NULL,
|
||||
NULL,
|
||||
gx_audio_write_avail,
|
||||
gx_audio_buffer_size,
|
||||
};
|
||||
+38
-59
@@ -1,6 +1,6 @@
|
||||
/* 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.
|
||||
@@ -13,11 +13,12 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <jack/jack.h>
|
||||
#include <jack/types.h>
|
||||
#include <jack/ringbuffer.h>
|
||||
@@ -40,29 +41,25 @@ typedef struct jack
|
||||
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_nframes_t f, 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]);
|
||||
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)
|
||||
@@ -70,17 +67,14 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
||||
|
||||
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);
|
||||
|
||||
assert(out);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -92,19 +86,16 @@ static void shutdown_cb(void *data)
|
||||
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);
|
||||
char *save = NULL;
|
||||
int parsed = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *con = strtok_r(settings->audio.device, ",", &save);
|
||||
|
||||
if (con)
|
||||
dest_ports[parsed++] = strdup(con);
|
||||
@@ -115,16 +106,15 @@ static int parse_ports(char **dest_ports, const char **jports)
|
||||
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)
|
||||
static size_t find_buffersize(jack_t *jd, int latency)
|
||||
{
|
||||
jack_latency_range_t range;
|
||||
int i, buffer_frames, min_buffer_frames;
|
||||
int jack_latency = 0;
|
||||
int frames = latency * out_rate / 1000;
|
||||
int i, buffer_frames, min_buffer_frames, jack_latency = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
int frames = latency * settings->audio.out_rate / 1000;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -133,12 +123,12 @@ static size_t find_buffersize(jack_t *jd, int latency, unsigned out_rate)
|
||||
jack_latency = range.max;
|
||||
}
|
||||
|
||||
RARCH_LOG("[JACK]: Jack latency is %d frames.\n", jack_latency);
|
||||
RARCH_LOG("JACK: Jack latency is %d frames.\n", jack_latency);
|
||||
|
||||
buffer_frames = frames - 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);
|
||||
RARCH_LOG("JACK: Minimum buffer size is %d frames.\n", min_buffer_frames);
|
||||
|
||||
if (buffer_frames < min_buffer_frames)
|
||||
buffer_frames = min_buffer_frames;
|
||||
@@ -146,30 +136,27 @@ static size_t find_buffersize(jack_t *jd, int latency, unsigned out_rate)
|
||||
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)
|
||||
static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
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));
|
||||
char *dest_ports[2];
|
||||
size_t bufsize = 0;
|
||||
int parsed = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
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);
|
||||
settings->audio.out_rate = jack_get_sample_rate(jd->client);
|
||||
|
||||
jack_set_process_callback(jd->client, process_cb, jd);
|
||||
jack_on_shutdown(jd->client, shutdown_cb, jd);
|
||||
@@ -178,27 +165,27 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
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");
|
||||
RARCH_ERR("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");
|
||||
RARCH_ERR("Failed to get ports.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
bufsize = find_buffersize(jd, latency, *new_rate);
|
||||
bufsize = find_buffersize(jd, latency);
|
||||
jd->buffer_size = bufsize;
|
||||
|
||||
RARCH_LOG("[JACK]: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
|
||||
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");
|
||||
RARCH_ERR("Failed to create buffers.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +194,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
|
||||
if (jack_activate(jd->client) < 0)
|
||||
{
|
||||
RARCH_ERR("[JACK]: Failed to activate Jack...\n");
|
||||
RARCH_ERR("Failed to activate Jack...\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -215,32 +202,30 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
{
|
||||
if (jack_connect(jd->client, jack_port_name(jd->ports[i]), dest_ports[i]))
|
||||
{
|
||||
RARCH_ERR("[JACK]: Failed to connect to Jack port.\n");
|
||||
RARCH_ERR("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;
|
||||
size_t j, frames, written = 0;
|
||||
jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO];
|
||||
size_t frames = FRAMES(size);
|
||||
|
||||
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)
|
||||
@@ -273,14 +258,12 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
}
|
||||
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;
|
||||
@@ -319,7 +302,7 @@ static void ja_set_nonblock_state(void *data, bool state)
|
||||
jd->nonblock = state;
|
||||
}
|
||||
|
||||
static bool ja_start(void *data, bool is_shutdown)
|
||||
static bool ja_start(void *data)
|
||||
{
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (jd)
|
||||
@@ -344,12 +327,10 @@ static void ja_free(void *data)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -381,8 +362,6 @@ audio_driver_t audio_jack = {
|
||||
ja_free,
|
||||
ja_use_float,
|
||||
"jack",
|
||||
NULL,
|
||||
NULL,
|
||||
ja_write_avail,
|
||||
ja_buffer_size,
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -17,16 +16,13 @@
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
static void *null_audio_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *null_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
RARCH_ERR("Using the null audio driver. RetroArch will be silent.");
|
||||
|
||||
(void)device;
|
||||
(void)rate;
|
||||
(void)latency;
|
||||
(void)new_rate;
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
@@ -55,7 +51,7 @@ static bool null_audio_alive(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_audio_start(void *data, bool is_shutdown)
|
||||
static bool null_audio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
@@ -89,8 +85,6 @@ audio_driver_t audio_null = {
|
||||
null_audio_free,
|
||||
null_audio_use_float,
|
||||
"null",
|
||||
NULL,
|
||||
NULL,
|
||||
null_audio_write_avail,
|
||||
NULL
|
||||
};
|
||||
+6
-14
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -14,7 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -30,10 +28,8 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define BUFSIZE 1024
|
||||
@@ -82,9 +78,7 @@ static void al_free(void *data)
|
||||
free(al);
|
||||
}
|
||||
|
||||
static void *al_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *al_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
al_t *al;
|
||||
|
||||
@@ -176,9 +170,9 @@ static size_t al_fill_internal_buf(al_t *al, const void *buf, size_t size)
|
||||
|
||||
static ssize_t al_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
al_t *al = (al_t*)data;
|
||||
al_t *al = (al_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
size_t written = 0;
|
||||
|
||||
while (size)
|
||||
{
|
||||
@@ -236,7 +230,7 @@ static void al_set_nonblock_state(void *data, bool state)
|
||||
al->nonblock = state;
|
||||
}
|
||||
|
||||
static bool al_start(void *data, bool is_shutdown)
|
||||
static bool al_start(void *data)
|
||||
{
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
@@ -273,8 +267,6 @@ audio_driver_t audio_openal = {
|
||||
al_free,
|
||||
al_use_float,
|
||||
"openal",
|
||||
NULL,
|
||||
NULL,
|
||||
al_write_avail,
|
||||
al_buffer_size,
|
||||
};
|
||||
+52
-55
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <rthreads/rthreads.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
/* Helper macros, COM-style. */
|
||||
#define SLObjectItf_Realize(a, ...) ((*(a))->Realize(a, __VA_ARGS__))
|
||||
@@ -97,26 +98,31 @@ static void sl_free(void *data)
|
||||
free(sl);
|
||||
}
|
||||
|
||||
static void *sl_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *sl_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
unsigned i;
|
||||
SLDataFormat_PCM fmt_pcm = {0};
|
||||
SLDataSource audio_src = {0};
|
||||
SLDataSink audio_sink = {0};
|
||||
SLInterfaceID id;
|
||||
SLboolean req;
|
||||
SLresult res;
|
||||
sl_t *sl;
|
||||
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));
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
(void)device;
|
||||
|
||||
id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
req = SL_BOOLEAN_TRUE;
|
||||
|
||||
res = 0;
|
||||
sl = (sl_t*)calloc(1, sizeof(sl_t));
|
||||
if (!sl)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[OpenSL]: Requested audio latency: %u ms.", latency);
|
||||
RARCH_LOG("[SLES]: 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));
|
||||
@@ -125,18 +131,15 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency,
|
||||
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;
|
||||
if (settings->audio.block_frames)
|
||||
sl->buf_size = settings->audio.block_frames * 4;
|
||||
else
|
||||
sl->buf_size = next_pow2(32 * latency);
|
||||
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;
|
||||
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);
|
||||
sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count);
|
||||
if (!sl->buffer)
|
||||
goto error;
|
||||
|
||||
@@ -147,27 +150,27 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency,
|
||||
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",
|
||||
RARCH_LOG("[SLES]: 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. */
|
||||
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;
|
||||
audio_src.pLocator = &loc_bufq;
|
||||
audio_src.pFormat = &fmt_pcm;
|
||||
|
||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bufq.numBuffers = sl->buf_count;
|
||||
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;
|
||||
audio_sink.pLocator = &loc_outmix;
|
||||
|
||||
GOTO_IF_FAIL(SLEngineItf_CreateAudioPlayer(sl->engine, &sl->buffer_queue_object,
|
||||
&audio_src, &audio_sink,
|
||||
@@ -177,15 +180,14 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency,
|
||||
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
|
||||
&sl->buffer_queue));
|
||||
|
||||
sl->cond = scond_new();
|
||||
sl->lock = slock_new();
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
@@ -195,17 +197,15 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency,
|
||||
return sl;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[OpenSL]: Couldn't initialize OpenSL ES driver, error code: [%d].\n", (int)res);
|
||||
RARCH_ERR("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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -224,19 +224,18 @@ static void sl_set_nonblock_state(void *data, bool state)
|
||||
sl->nonblock = state;
|
||||
}
|
||||
|
||||
static bool sl_start(void *data, bool is_shutdown)
|
||||
static bool sl_start(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING)
|
||||
== SL_RESULT_SUCCESS) ? false : true;
|
||||
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;
|
||||
sl_t *sl = (sl_t*)data;
|
||||
size_t written = 0;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
while (size)
|
||||
@@ -269,10 +268,10 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
|
||||
|
||||
if (sl->buffer_ptr >= sl->buf_size)
|
||||
{
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], 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;
|
||||
sl->buffer_ptr = 0;
|
||||
|
||||
if (res != SL_RESULT_SUCCESS)
|
||||
{
|
||||
@@ -314,8 +313,6 @@ audio_driver_t audio_opensl = {
|
||||
sl_free,
|
||||
sl_use_float,
|
||||
"opensl",
|
||||
NULL,
|
||||
NULL,
|
||||
sl_write_avail,
|
||||
sl_buffer_size,
|
||||
};
|
||||
+35
-33
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -13,7 +12,6 @@
|
||||
* 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>
|
||||
@@ -34,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifdef HAVE_OSS_BSD
|
||||
@@ -42,17 +41,17 @@
|
||||
#define DEFAULT_OSS_DEV "/dev/dsp"
|
||||
#endif
|
||||
|
||||
static bool oss_is_paused = false;
|
||||
static bool oss_is_paused;
|
||||
|
||||
static void *oss_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_out_rate)
|
||||
static void *oss_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int frags, frag, channels, format, new_rate;
|
||||
int *fd = (int*)calloc(1, sizeof(int));
|
||||
const char *oss_device = device ? device : DEFAULT_OSS_DEV;
|
||||
int *fd = (int*)calloc(1, sizeof(int));
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!fd)
|
||||
const char *oss_device = device ? device : DEFAULT_OSS_DEV;
|
||||
|
||||
if (fd == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((*fd = open(oss_device, O_WRONLY)) < 0)
|
||||
@@ -63,38 +62,47 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency,
|
||||
}
|
||||
|
||||
frags = (latency * rate * 4) / (1000 * (1 << 10));
|
||||
frag = (frags << 16) | 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;
|
||||
format = is_little_endian() ? AFMT_S16_LE : AFMT_S16_BE;
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0)
|
||||
goto error;
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_SETFMT, &format) < 0)
|
||||
goto error;
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_rate = rate;
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_SPEED, &new_rate) < 0)
|
||||
goto error;
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
settings->audio.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)
|
||||
@@ -120,14 +128,12 @@ static bool oss_stop(void *data)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_RESET, 0) < 0)
|
||||
return false;
|
||||
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
oss_is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool oss_start(void *data, bool is_shutdown)
|
||||
static bool oss_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
oss_is_paused = false;
|
||||
@@ -157,9 +163,7 @@ static void oss_free(void *data)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_RESET, 0) < 0)
|
||||
return;
|
||||
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
close(*fd);
|
||||
free(fd);
|
||||
}
|
||||
@@ -171,7 +175,7 @@ static size_t oss_write_avail(void *data)
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("[OSS]: SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -185,7 +189,7 @@ static size_t oss_buffer_size(void *data)
|
||||
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("[OSS]: SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
return 1; /* Return something non-zero to avoid SIGFPE. */
|
||||
}
|
||||
|
||||
@@ -208,8 +212,6 @@ audio_driver_t audio_oss = {
|
||||
oss_free,
|
||||
oss_use_float,
|
||||
"oss",
|
||||
NULL,
|
||||
NULL,
|
||||
oss_write_avail,
|
||||
oss_buffer_size,
|
||||
};
|
||||
+16
-17
@@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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.
|
||||
@@ -17,9 +17,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <queues/fifo_buffer.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
#include "../../defines/ps3_defines.h"
|
||||
|
||||
@@ -51,7 +52,7 @@ static void event_loop(uint64_t data)
|
||||
sys_event_queue_t id;
|
||||
sys_ipc_key_t key;
|
||||
sys_event_t event;
|
||||
ps3_audio_t *aud = (ps3_audio_t*)(uintptr_t)data;
|
||||
ps3_audio_t *aud = data;
|
||||
|
||||
cellAudioCreateNotifyEventQueue(&id, &key);
|
||||
cellAudioSetNotifyEventQueue(key);
|
||||
@@ -77,23 +78,23 @@ static void event_loop(uint64_t data)
|
||||
}
|
||||
|
||||
static void *ps3_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
CellAudioPortParam params;
|
||||
ps3_audio_t *data = calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
return NULL;
|
||||
ps3_audio_t *data = NULL;
|
||||
|
||||
(void)latency;
|
||||
(void)device;
|
||||
(void)rate;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
cellAudioInit();
|
||||
|
||||
params.numChannels = AUDIO_CHANNELS;
|
||||
params.numBlocks = AUDIO_BLOCKS;
|
||||
params.numBlocks = AUDIO_BLOCKS;
|
||||
#if 0
|
||||
#ifdef HAVE_HEADSET
|
||||
if(global->console.sound.mode == SOUND_MODE_HEADSET)
|
||||
@@ -110,11 +111,11 @@ static void *ps3_audio_init(const char *device,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES *
|
||||
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_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"};
|
||||
@@ -177,7 +178,7 @@ static bool ps3_audio_stop(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ps3_audio_start(void *data, bool is_shutdown)
|
||||
static bool ps3_audio_start(void *data)
|
||||
{
|
||||
ps3_audio_t *aud = data;
|
||||
if (!aud->started)
|
||||
@@ -209,7 +210,7 @@ static void ps3_audio_free(void *data)
|
||||
ps3_audio_t *aud = data;
|
||||
|
||||
aud->quit_thread = true;
|
||||
ps3_audio_start(aud, false);
|
||||
ps3_audio_start(aud);
|
||||
sys_ppu_thread_join(aud->thread, &val);
|
||||
|
||||
ps3_audio_stop(aud);
|
||||
@@ -246,8 +247,6 @@ audio_driver_t audio_ps3 = {
|
||||
ps3_audio_free,
|
||||
ps3_audio_use_float,
|
||||
"ps3",
|
||||
NULL,
|
||||
NULL,
|
||||
ps3_audio_write_avail,
|
||||
NULL
|
||||
};
|
||||
+103
-128
@@ -1,7 +1,7 @@
|
||||
/* 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
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
* Copyright (C) 2014-2016 - 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-
|
||||
@@ -17,11 +17,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
|
||||
#ifdef VITA
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
@@ -34,75 +29,64 @@
|
||||
#endif
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.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;
|
||||
|
||||
volatile uint16_t readPos;
|
||||
volatile uint16_t writePos;
|
||||
} 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)
|
||||
#ifdef VITA
|
||||
#define PSP_THREAD_STOPPED PSP2_THREAD_STOPPED
|
||||
#else
|
||||
#define SceKernelThreadInfo SceKernelThreadRunStatus
|
||||
#define sceKernelGetThreadInfo sceKernelReferThreadRunStatus
|
||||
#endif
|
||||
|
||||
static int audioMainLoop(SceSize args, void* argp)
|
||||
{
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
psp_audio_t* psp = *((psp_audio_t**)argp);
|
||||
|
||||
#ifdef VITA
|
||||
int port = sceAudioOutOpenPort(
|
||||
SCE_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT,
|
||||
psp->rate, SCE_AUDIO_OUT_MODE_STEREO);
|
||||
int port = sceAudioOutOpenPort(PSP2_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT,
|
||||
psp->rate, PSP2_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)
|
||||
/* Get a non-volatile copy. */
|
||||
uint16_t readPos = psp->readPos;
|
||||
bool cond = ((uint16_t)(psp->writePos - readPos) & 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);
|
||||
|
||||
#ifdef VITA
|
||||
sceAudioOutOutput(port,
|
||||
cond ? (psp->zeroBuffer)
|
||||
: (psp->buffer + read_pos_2));
|
||||
cond ? psp->zeroBuffer : (psp->buffer + readPos));
|
||||
#else
|
||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer)
|
||||
: (psp->buffer + read_pos));
|
||||
: (psp->buffer + readPos));
|
||||
#endif
|
||||
|
||||
if (!cond)
|
||||
{
|
||||
readPos += AUDIO_OUT_COUNT;
|
||||
readPos &= AUDIO_BUFFER_SIZE_MASK;
|
||||
psp->readPos = readPos;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VITA
|
||||
@@ -110,14 +94,12 @@ static void audioMainLoop(void *data)
|
||||
#else
|
||||
sceAudioSRCChRelease();
|
||||
#endif
|
||||
|
||||
return;
|
||||
sceKernelExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *psp_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
psp_audio_t *psp = (psp_audio_t*)calloc(1, sizeof(psp_audio_t));
|
||||
|
||||
@@ -131,93 +113,80 @@ static void *psp_audio_init(const char *device,
|
||||
psp->buffer = (uint32_t*)
|
||||
memalign(64, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
|
||||
memset(psp->buffer, 0, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
|
||||
|
||||
psp->zeroBuffer = (uint32_t*)
|
||||
memalign(64, AUDIO_OUT_COUNT * sizeof(uint32_t));
|
||||
memset(psp->zeroBuffer, 0, AUDIO_OUT_COUNT * sizeof(uint32_t));
|
||||
|
||||
psp->read_pos = 0;
|
||||
psp->write_pos = 0;
|
||||
psp->readPos = 0;
|
||||
psp->writePos = 0;
|
||||
psp->rate = rate;
|
||||
|
||||
psp->fifo_lock = slock_new();
|
||||
psp->cond_lock = slock_new();
|
||||
psp->cond = scond_new();
|
||||
|
||||
#if defined(VITA)
|
||||
psp->thread = sceKernelCreateThread
|
||||
("audioMainLoop", audioMainLoop, 0x10000100, 0x10000, 0, 0, NULL);
|
||||
#else
|
||||
psp->thread = sceKernelCreateThread
|
||||
("audioMainLoop", audioMainLoop, 0x08, 0x10000, 0, NULL);
|
||||
#endif
|
||||
psp->nonblocking = false;
|
||||
|
||||
psp->running = true;
|
||||
psp->worker_thread = sthread_create(audioMainLoop, psp);
|
||||
sceKernelStartThread(psp->thread, sizeof(psp_audio_t*), &psp);
|
||||
|
||||
return psp;
|
||||
}
|
||||
|
||||
static void psp_audio_free(void *data)
|
||||
{
|
||||
SceUInt timeout = 100000;
|
||||
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);
|
||||
}
|
||||
psp->running = false;
|
||||
#if defined(VITA)
|
||||
sceKernelWaitThreadEnd(psp->thread, NULL, &timeout);
|
||||
#else
|
||||
sceKernelWaitThreadEnd(psp->thread, &timeout);
|
||||
#endif
|
||||
sceKernelDeleteThread(psp->thread);
|
||||
|
||||
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)
|
||||
{
|
||||
uint16_t sampleCount;
|
||||
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;
|
||||
uint16_t writePos = psp->writePos;
|
||||
|
||||
sampleCount= size / sizeof(uint32_t);
|
||||
|
||||
#if 0
|
||||
if (psp->nonblocking)
|
||||
{
|
||||
if (AUDIO_BUFFER_SIZE - ((uint16_t)
|
||||
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
|
||||
return 0;
|
||||
/* TODO */
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
if((writePos + sampleCount) > AUDIO_BUFFER_SIZE)
|
||||
{
|
||||
memcpy(psp->buffer + write_pos, buf,
|
||||
(AUDIO_BUFFER_SIZE - write_pos) * sizeof(uint32_t));
|
||||
memcpy(psp->buffer + writePos, buf,
|
||||
(AUDIO_BUFFER_SIZE - writePos) * sizeof(uint32_t));
|
||||
memcpy(psp->buffer, (uint32_t*) buf +
|
||||
(AUDIO_BUFFER_SIZE - write_pos),
|
||||
(write_pos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t));
|
||||
(AUDIO_BUFFER_SIZE - writePos),
|
||||
(writePos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t));
|
||||
}
|
||||
else
|
||||
memcpy(psp->buffer + write_pos, buf, size);
|
||||
memcpy(psp->buffer + writePos, buf, size);
|
||||
|
||||
write_pos += sampleCount;
|
||||
write_pos &= AUDIO_BUFFER_SIZE_MASK;
|
||||
psp->write_pos = write_pos;
|
||||
writePos += sampleCount;
|
||||
writePos &= AUDIO_BUFFER_SIZE_MASK;
|
||||
psp->writePos = writePos;
|
||||
|
||||
slock_unlock(psp->fifo_lock);
|
||||
return size;
|
||||
|
||||
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
static bool psp_audio_alive(void *data)
|
||||
@@ -231,32 +200,46 @@ static bool psp_audio_alive(void *data)
|
||||
|
||||
static bool psp_audio_stop(void *data)
|
||||
{
|
||||
SceKernelThreadInfo info;
|
||||
SceUInt timeout = 100000;
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
|
||||
if (psp){
|
||||
psp->running = false;
|
||||
info.size = sizeof(SceKernelThreadInfo);
|
||||
|
||||
if (!psp->worker_thread)
|
||||
return true;
|
||||
if (sceKernelGetThreadInfo(
|
||||
psp->thread, &info) < 0) /* Error */
|
||||
return false;
|
||||
|
||||
if (info.status == PSP_THREAD_STOPPED)
|
||||
return false;
|
||||
|
||||
psp->running = false;
|
||||
#if defined(VITA)
|
||||
sceKernelWaitThreadEnd(psp->thread, NULL, &timeout);
|
||||
#else
|
||||
sceKernelWaitThreadEnd(psp->thread, &timeout);
|
||||
#endif
|
||||
|
||||
sthread_join(psp->worker_thread);
|
||||
psp->worker_thread = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool psp_audio_start(void *data, bool is_shutdown)
|
||||
static bool psp_audio_start(void *data)
|
||||
{
|
||||
SceKernelThreadInfo info;
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
|
||||
if(psp && psp->running)
|
||||
return true;
|
||||
info.size = sizeof(SceKernelThreadInfo);
|
||||
|
||||
if (!psp->worker_thread)
|
||||
{
|
||||
psp->running = true;
|
||||
psp->worker_thread = sthread_create(audioMainLoop, psp);
|
||||
}
|
||||
if (sceKernelGetThreadInfo(
|
||||
psp->thread, &info) < 0) /* Error */
|
||||
return false;
|
||||
|
||||
if (info.status != PSP_THREAD_STOPPED)
|
||||
return false;
|
||||
|
||||
psp->running = true;
|
||||
|
||||
sceKernelStartThread(psp->thread, sizeof(psp_audio_t*), &psp);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -276,22 +259,16 @@ static bool psp_audio_use_float(void *data)
|
||||
|
||||
static size_t psp_write_avail(void *data)
|
||||
{
|
||||
size_t val;
|
||||
/* TODO */
|
||||
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;
|
||||
return AUDIO_BUFFER_SIZE - ((uint16_t)
|
||||
(psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK);
|
||||
}
|
||||
|
||||
static size_t psp_buffer_size(void *data)
|
||||
{
|
||||
/* TODO */
|
||||
return AUDIO_BUFFER_SIZE /** sizeof(uint32_t)*/;
|
||||
return AUDIO_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
@@ -309,8 +286,6 @@ audio_driver_t audio_psp = {
|
||||
#else
|
||||
"psp",
|
||||
#endif
|
||||
NULL,
|
||||
NULL,
|
||||
psp_write_avail,
|
||||
psp_buffer_size
|
||||
psp_buffer_size,
|
||||
};
|
||||
+23
-33
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -20,10 +19,10 @@
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_endianness.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
@@ -89,7 +88,7 @@ static void context_state_cb(pa_context *c, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void stream_state_cb(pa_stream *s, void *data)
|
||||
static void stream_state_cb(pa_stream *s, void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
@@ -105,7 +104,7 @@ static void stream_state_cb(pa_stream *s, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void stream_request_cb(pa_stream *s, size_t length, void *data)
|
||||
static void stream_request_cb(pa_stream *s, size_t length, void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
@@ -115,7 +114,7 @@ static void stream_request_cb(pa_stream *s, size_t length, void *data)
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
}
|
||||
|
||||
static void stream_latency_update_cb(pa_stream *s, void *data)
|
||||
static void stream_latency_update_cb(pa_stream *s, void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
@@ -126,7 +125,6 @@ static void stream_latency_update_cb(pa_stream *s, void *data)
|
||||
|
||||
static void underrun_update_cb(pa_stream *s, void *data)
|
||||
{
|
||||
#if 0
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
(void)s;
|
||||
@@ -134,7 +132,6 @@ static void underrun_update_cb(pa_stream *s, void *data)
|
||||
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)
|
||||
@@ -144,23 +141,19 @@ static void buffer_attr_cb(pa_stream *s, void *data)
|
||||
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)
|
||||
static void *pulse_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
pa_sample_spec spec;
|
||||
pa_buffer_attr buffer_attr = {0};
|
||||
pa_sample_spec spec;
|
||||
pa_t *pa;
|
||||
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));
|
||||
|
||||
|
||||
pa = (pa_t*)calloc(1, sizeof(*pa));
|
||||
if (!pa)
|
||||
goto error;
|
||||
|
||||
@@ -186,11 +179,11 @@ static void *pulse_init(const char *device, unsigned rate,
|
||||
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.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE;
|
||||
spec.channels = 2;
|
||||
spec.rate = rate;
|
||||
spec.rate = rate;
|
||||
|
||||
pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
|
||||
pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
|
||||
if (!pa->stream)
|
||||
goto unlock_error;
|
||||
|
||||
@@ -201,13 +194,12 @@ static void *pulse_init(const char *device, unsigned rate,
|
||||
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;
|
||||
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)
|
||||
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);
|
||||
@@ -233,15 +225,15 @@ static void *pulse_init(const char *device, unsigned rate,
|
||||
unlock_error:
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
error:
|
||||
pulse_free(pa);
|
||||
pulse_free(pa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t pulse_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
size_t written = 0;
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
while (size)
|
||||
@@ -292,7 +284,7 @@ static bool pulse_alive(void *data)
|
||||
return !pa->is_paused;
|
||||
}
|
||||
|
||||
static bool pulse_start(void *data, bool is_shutdown)
|
||||
static bool pulse_start(void *data)
|
||||
{
|
||||
bool ret;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
@@ -351,8 +343,6 @@ audio_driver_t audio_pulse = {
|
||||
pulse_free,
|
||||
pulse_use_float,
|
||||
"pulse",
|
||||
NULL,
|
||||
NULL,
|
||||
pulse_write_avail,
|
||||
pulse_buffer_size,
|
||||
};
|
||||
+8
-14
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -24,21 +23,19 @@
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../../configuration.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)
|
||||
static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int err;
|
||||
roar_vs_t *vss = NULL;
|
||||
roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t));
|
||||
roar_vs_t *vss;
|
||||
roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t));
|
||||
|
||||
if (!roar)
|
||||
return NULL;
|
||||
@@ -62,7 +59,7 @@ 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;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
@@ -72,8 +69,7 @@ static ssize_t ra_write(void *data, const void *buf, size_t 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 ((rc = roar_vs_write(roar->vss, (const char*)buf + written, write_amt, &err)) < (ssize_t)write_amt)
|
||||
{
|
||||
if (roar->nonblocking)
|
||||
return rc;
|
||||
@@ -110,7 +106,7 @@ static void ra_set_nonblock_state(void *data, bool state)
|
||||
roar->nonblocking = state;
|
||||
}
|
||||
|
||||
static bool ra_start(void *data, bool is_shutdown)
|
||||
static bool ra_start(void *data)
|
||||
{
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar)
|
||||
@@ -146,8 +142,6 @@ audio_driver_t audio_roar = {
|
||||
ra_free,
|
||||
ra_use_float,
|
||||
"roar",
|
||||
NULL,
|
||||
NULL,
|
||||
ra_write_avail,
|
||||
NULL
|
||||
};
|
||||
+18
-23
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -18,7 +17,7 @@
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <queues/fifo_buffer.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
@@ -56,26 +55,28 @@ static void err_cb(void *userdata)
|
||||
scond_signal(rsd->cond);
|
||||
}
|
||||
|
||||
static void *rs_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *rs_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int channels, format;
|
||||
rsound_t *rd = NULL;
|
||||
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
|
||||
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
|
||||
if (!rsd)
|
||||
return NULL;
|
||||
|
||||
rsound_t *rd;
|
||||
|
||||
if (rsd_init(&rd) < 0)
|
||||
goto error;
|
||||
{
|
||||
free(rsd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rsd->cond_lock = slock_new();
|
||||
rsd->cond = scond_new();
|
||||
rsd->cond = scond_new();
|
||||
|
||||
rsd->buffer = fifo_new(1024 * 4);
|
||||
rsd->buffer = fifo_new(1024 * 4);
|
||||
|
||||
channels = 2;
|
||||
format = RSD_S16_NE;
|
||||
channels = 2;
|
||||
format = RSD_S16_NE;
|
||||
|
||||
rsd_set_param(rd, RSD_CHANNELS, &channels);
|
||||
rsd_set_param(rd, RSD_SAMPLERATE, &rate);
|
||||
@@ -91,15 +92,12 @@ static void *rs_init(const char *device, unsigned rate, unsigned latency,
|
||||
if (rsd_start(rd) < 0)
|
||||
{
|
||||
free(rsd);
|
||||
goto error;
|
||||
rsd_free(rd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rsd->rd = rd;
|
||||
return rsd;
|
||||
|
||||
error:
|
||||
rsd_free(rd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t rs_write(void *data, const void *buf, size_t size)
|
||||
@@ -177,7 +175,7 @@ static bool rs_alive(void *data)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rs_start(void *data, bool is_shutdown)
|
||||
static bool rs_start(void *data)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
if (rsd_start(rsd->rd) < 0)
|
||||
@@ -203,13 +201,12 @@ static void rs_free(void *data)
|
||||
|
||||
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);
|
||||
size_t val = fifo_write_avail(rsd->buffer);
|
||||
rsd_callback_unlock(rsd->rd);
|
||||
return val;
|
||||
}
|
||||
@@ -236,8 +233,6 @@ audio_driver_t audio_rsound = {
|
||||
rs_free,
|
||||
rs_use_float,
|
||||
"rsound",
|
||||
NULL,
|
||||
NULL,
|
||||
rs_write_avail,
|
||||
rs_buffer_size,
|
||||
};
|
||||
+48
-41
@@ -1,6 +1,6 @@
|
||||
/* 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.
|
||||
@@ -16,6 +16,14 @@
|
||||
#ifndef __RSOUND_H
|
||||
#define __RSOUND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define STANDALONE
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
@@ -24,10 +32,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
#include <queues/fifo_buffer.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define RSD_DEFAULT_HOST "127.0.0.1" /* Stupid Windows. */
|
||||
@@ -43,7 +48,7 @@ RETRO_BEGIN_DECLS
|
||||
#endif
|
||||
|
||||
/* Feature tests */
|
||||
#define RSD_SAMPLERATE RSD_SAMPLERATE
|
||||
#define RSD_SAMPLERATE RSD_SAMPLERATE
|
||||
#define RSD_CHANNELS RSD_CHANNELS
|
||||
#define RSD_HOST RSD_HOST
|
||||
#define RSD_PORT RSD_PORT
|
||||
@@ -125,7 +130,7 @@ enum rsd_settings
|
||||
/* 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,
|
||||
/* 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);
|
||||
|
||||
@@ -144,7 +149,7 @@ typedef struct rsound
|
||||
int conn_type;
|
||||
|
||||
volatile int buffer_pointer; /* Obsolete, but kept for backwards header compatibility. */
|
||||
size_t buffer_size;
|
||||
size_t buffer_size;
|
||||
fifo_buffer_t *fifo_buffer;
|
||||
|
||||
volatile int thread_active;
|
||||
@@ -196,13 +201,13 @@ typedef struct rsound
|
||||
rsd_set_param(rd, RSD_HOST, "foohost");
|
||||
*sets more params*
|
||||
rsd_start(rd);
|
||||
rsd_write(rd, buf, size);
|
||||
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,
|
||||
/* 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. */
|
||||
|
||||
@@ -211,29 +216,29 @@ int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const c
|
||||
|
||||
/* 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_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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
@@ -244,14 +249,14 @@ 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.
|
||||
/* 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.
|
||||
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. */
|
||||
|
||||
@@ -260,37 +265,37 @@ void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_ca
|
||||
/* 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.
|
||||
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
|
||||
/* 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(). */
|
||||
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.
|
||||
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.
|
||||
/* 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,
|
||||
/* 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.
|
||||
/* 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);
|
||||
|
||||
@@ -306,18 +311,20 @@ 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
|
||||
/* 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
|
||||
/* 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
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+12
-15
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -19,6 +18,7 @@
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
/* forward declarations */
|
||||
unsigned RWebAudioSampleRate(void);
|
||||
@@ -37,17 +37,16 @@ static void rwebaudio_free(void *data)
|
||||
RWebAudioFree();
|
||||
}
|
||||
|
||||
static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
void *data = RWebAudioInit(latency);
|
||||
|
||||
(void)device;
|
||||
(void)rate;
|
||||
|
||||
if (data)
|
||||
*new_rate = RWebAudioSampleRate();
|
||||
settings->audio.out_rate = RWebAudioSampleRate();
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -76,13 +75,19 @@ static bool rwebaudio_alive(void *data)
|
||||
return !rwebaudio_is_paused;
|
||||
}
|
||||
|
||||
static bool rwebaudio_start(void *data, bool is_shutdown)
|
||||
static bool rwebaudio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
rwebaudio_is_paused = false;
|
||||
return RWebAudioStart();
|
||||
}
|
||||
|
||||
static bool rwebaudio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t rwebaudio_write_avail(void *data)
|
||||
{
|
||||
(void)data;
|
||||
@@ -95,12 +100,6 @@ static size_t rwebaudio_buffer_size(void *data)
|
||||
return RWebAudioBufferSize();
|
||||
}
|
||||
|
||||
static bool rwebaudio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
audio_driver_t audio_rwebaudio = {
|
||||
rwebaudio_init,
|
||||
rwebaudio_write,
|
||||
@@ -111,8 +110,6 @@ audio_driver_t audio_rwebaudio = {
|
||||
rwebaudio_free,
|
||||
rwebaudio_use_float,
|
||||
"rwebaudio",
|
||||
NULL,
|
||||
NULL,
|
||||
rwebaudio_write_avail,
|
||||
rwebaudio_buffer_size,
|
||||
};
|
||||
+33
-50
@@ -1,7 +1,6 @@
|
||||
/* 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.
|
||||
@@ -14,15 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boolean.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_math.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,28 +21,33 @@
|
||||
#include "SDL.h"
|
||||
#include "SDL_audio.h"
|
||||
|
||||
#include <boolean.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <queues/fifo_buffer.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.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);
|
||||
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);
|
||||
@@ -68,15 +63,14 @@ static INLINE int find_num_frames(int rate, int latency)
|
||||
}
|
||||
|
||||
static void *sdl_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
int frames;
|
||||
size_t bufsize;
|
||||
void *tmp;
|
||||
SDL_AudioSpec out;
|
||||
SDL_AudioSpec spec = {0};
|
||||
void *tmp = NULL;
|
||||
SDL_AudioSpec spec = {0};
|
||||
settings_t *settings = config_get_ptr();
|
||||
sdl_audio_t *sdl = NULL;
|
||||
|
||||
(void)device;
|
||||
@@ -93,38 +87,37 @@ static void *sdl_audio_init(const char *device,
|
||||
if (!sdl)
|
||||
return NULL;
|
||||
|
||||
/* We have to buffer up some data ourselves, so we let SDL
|
||||
/* 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);
|
||||
frames = find_num_frames(rate, latency / 4);
|
||||
|
||||
spec.freq = rate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.freq = rate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 2;
|
||||
spec.samples = frames; /* This is in audio frames, not samples ... :( */
|
||||
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;
|
||||
RARCH_ERR("Failed to open SDL audio: %s\n", SDL_GetError());
|
||||
free(sdl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*new_rate = out.freq;
|
||||
settings->audio.out_rate = out.freq;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
sdl->lock = slock_new();
|
||||
sdl->cond = scond_new();
|
||||
#endif
|
||||
sdl->lock = slock_new();
|
||||
sdl->cond = scond_new();
|
||||
|
||||
RARCH_LOG("[SDL audio]: Requested %u ms latency, got %d ms\n",
|
||||
latency, (int)(out.samples * 4 * 1000 / (*new_rate)));
|
||||
RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n",
|
||||
latency, (int)(out.samples * 4 * 1000 / settings->audio.out_rate));
|
||||
|
||||
/* Create a buffer twice as big as needed and prefill the buffer. */
|
||||
bufsize = out.samples * 4 * sizeof(int16_t);
|
||||
tmp = calloc(1, bufsize);
|
||||
bufsize = out.samples * 4 * sizeof(int16_t);
|
||||
tmp = calloc(1, bufsize);
|
||||
sdl->buffer = fifo_new(bufsize);
|
||||
|
||||
if (tmp)
|
||||
@@ -135,15 +128,11 @@ static void *sdl_audio_init(const char *device,
|
||||
|
||||
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;
|
||||
ssize_t ret = 0;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
|
||||
if (sdl->nonblock)
|
||||
@@ -171,11 +160,9 @@ static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
|
||||
if (avail == 0)
|
||||
{
|
||||
SDL_UnlockAudio();
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(sdl->lock);
|
||||
scond_wait(sdl->cond, sdl->lock);
|
||||
slock_unlock(sdl->lock);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -207,7 +194,7 @@ static bool sdl_audio_alive(void *data)
|
||||
return !sdl->is_paused;
|
||||
}
|
||||
|
||||
static bool sdl_audio_start(void *data, bool is_shutdown)
|
||||
static bool sdl_audio_start(void *data)
|
||||
{
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
sdl->is_paused = false;
|
||||
@@ -233,10 +220,8 @@ static void sdl_audio_free(void *data)
|
||||
if (sdl)
|
||||
{
|
||||
fifo_free(sdl->buffer);
|
||||
#ifdef HAVE_THREADS
|
||||
slock_free(sdl->lock);
|
||||
scond_free(sdl->cond);
|
||||
#endif
|
||||
}
|
||||
free(sdl);
|
||||
}
|
||||
@@ -268,8 +253,6 @@ audio_driver_t audio_sdl = {
|
||||
#else
|
||||
"sdl",
|
||||
#endif
|
||||
NULL,
|
||||
NULL,
|
||||
sdl_audio_write_avail,
|
||||
NULL
|
||||
};
|
||||
@@ -1,366 +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 "../audio_driver.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)
|
||||
{
|
||||
RARCH_LOG("No buffer, blocking...\n");
|
||||
|
||||
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 */
|
||||
};
|
||||
@@ -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
|
||||
@@ -1,448 +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 "../audio_driver.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 */
|
||||
Loaded 100 of 6623 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user