mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-25 04:10:39 +00:00
Merge branch 'master' into WiiSkipCrc
This commit is contained in:
commit
79b5a05aeb
58
.github/ISSUE_TEMPLATE.md
vendored
58
.github/ISSUE_TEMPLATE.md
vendored
@ -2,34 +2,34 @@
|
||||
- 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
|
||||
## 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
|
||||
|
||||
[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]
|
||||
- Compiler: [In case you are running local builds]
|
||||
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -4,7 +4,6 @@
|
||||
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]
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -11,6 +11,8 @@
|
||||
.tmp
|
||||
.tmp.c
|
||||
.tmp.cxx
|
||||
.moc.h
|
||||
.moc.cpp
|
||||
config.log
|
||||
/.project
|
||||
/.externalToolBuilders/
|
||||
@ -53,7 +55,6 @@ DerivedData
|
||||
apple/tmp
|
||||
apple/*.mobileprovision
|
||||
apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
|
||||
menu/driverspzarch.c
|
||||
/Cg/
|
||||
/GL/
|
||||
/SDL/
|
||||
@ -74,6 +75,8 @@ libretro-super
|
||||
run.sh
|
||||
convert_rumble.awk
|
||||
*~
|
||||
assets
|
||||
info
|
||||
|
||||
# Wii U
|
||||
*.depend
|
||||
@ -85,7 +88,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
||||
/pkg/wiiu/rpx
|
||||
/wiiu-devel.properties
|
||||
|
||||
|
||||
# 3ds
|
||||
/.lst
|
||||
*.3dsx
|
||||
@ -119,7 +121,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
||||
/media/libretrodb/
|
||||
|
||||
pkg/apple/iOS/build/
|
||||
pkg/apple/iOS/modules/
|
||||
pkg/apple/build/
|
||||
ui/drivers/qt/moc_*
|
||||
ui/drivers/moc_*
|
||||
|
62
.travis.yml
62
.travis.yml
@ -10,7 +10,9 @@ matrix:
|
||||
- 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
|
||||
- ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 --enable-builtinzlib
|
||||
- make
|
||||
env: CROSS_COMPILE=i686-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
|
||||
- compiler: mingw-x64
|
||||
addons:
|
||||
apt:
|
||||
@ -18,41 +20,33 @@ matrix:
|
||||
- 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
|
||||
- ./configure --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12 --enable-builtinzlib
|
||||
- make
|
||||
env: CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
|
||||
- compiler: gcc
|
||||
addons:
|
||||
# Install a more recent gcc than the default
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
# Install a more recent gcc than the default
|
||||
before_install:
|
||||
- sudo apt-get install -y g++-8
|
||||
env: CC=gcc-8 CXX=g++-8
|
||||
- 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
|
||||
# Install a more recent clang than the default
|
||||
before_install:
|
||||
- sudo apt-get install -y libstdc++-7-dev
|
||||
- sudo apt-get install -y clang-6.0
|
||||
env: CC=clang-6.0 CXX=clang++-6.0
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
script:
|
||||
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
|
||||
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
|
||||
- os: osx
|
||||
osx_image: xcode9.3
|
||||
osx_image: xcode10.1
|
||||
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
|
||||
- xcodebuild -target RetroArchQt -configuration Release -project pkg/apple/RetroArch_Metal.xcodeproj
|
||||
deploy:
|
||||
skip_cleanup: true
|
||||
provider: script
|
||||
script: cd ../retroarch; bash travis_metal_deploy.sh
|
||||
script: bash travis_metal_deploy.sh
|
||||
on:
|
||||
branch: master
|
||||
|
||||
@ -67,19 +61,13 @@ env:
|
||||
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
|
||||
- libsdl2-dev
|
||||
- libusb-1.0-0-dev
|
||||
- qt5-default
|
||||
- qt5-qmake
|
||||
- qtbase5-dev-tools
|
||||
- qtbase5-dev
|
||||
- qtdeclarative5-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "RetroArch"
|
||||
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -24,7 +24,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
{
|
||||
"name": "(gdb) Attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
|
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@ -45,7 +45,7 @@
|
||||
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
"isDefault": true
|
||||
},
|
||||
|
||||
"command": "./configure; make -j2",
|
||||
|
@ -48,7 +48,7 @@ index b90a8e40c3..e57c4df194 100644
|
||||
+#endif
|
||||
+
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_OPENGL)
|
||||
@@ -313,6 +354,43 @@ static void create_gl_context(HWND hwnd, bool *quit)
|
||||
RARCH_LOG("[WGL]: Adaptive VSync supported.\n");
|
||||
|
49
CHANGES.md
49
CHANGES.md
@ -1,13 +1,27 @@
|
||||
# 1.7.6 (future)
|
||||
- ANDROID: Fix Xperia Play input binding
|
||||
- CHEEVOS: Reset when hardcore mode is toggled
|
||||
- CORE UPDATER: Allow sideloading cores from the menu
|
||||
# 1.7.7 (future)
|
||||
|
||||
# 1.7.6
|
||||
- ANDROID: Fix Xperia Play input binding.
|
||||
- CHEEVOS: Reset when hardcore mode is toggled.
|
||||
- CHEEVOS: Update the hashing methods to identify NES, SNES and Lynx games (more accurate and accepting headerless ROMs).
|
||||
- COMMON: Add new JSON playlist format.
|
||||
- COMMON: Fix playlist corruption when deleting items.
|
||||
- COMMON: Fix archive progress display calculation.
|
||||
- COMMON: Fix playlist entries appearing with previously used names.
|
||||
- COMMON: Fix screenshot filename with no core or content.
|
||||
- COMMON: Allow compiling without menu support.
|
||||
- CORE UPDATER: Allow sideloading cores from the menu.
|
||||
- CPU FILTERS: Add Normal2x filter.
|
||||
- CRT/LINUX: New Linux switching method partially implemented.
|
||||
- CRT/LINUX: Linux restore desktop resolution fixed.
|
||||
- CRT/LINUX: Monitor index switching and auto enumerate for output detection in Linux (still working on the windows method).
|
||||
- CRT/RASPBERRY PI: Initial support.
|
||||
- DATE: Add Date / Time style options.
|
||||
- DEBUGGING: Add an integrated crash handler for debug builds (see https://docs.libretro.com/tech/debugging)
|
||||
- DISCORD: Register the application name properly.
|
||||
- DISK CONTROL: Remember the last used folder / current active folder to make disk-swapping faster.
|
||||
- INPUT: Add new menu toggle (hold start button for 2 seconds)
|
||||
- INPUT: Fix arrow keys being incorrectly bound as numpad keys
|
||||
- INPUT/SDL: Flush the joypad events. Decreases cpu usage over time with the SDL joypad driver.
|
||||
- LOCALIZATION: Add Greek translation.
|
||||
- LOCALIZATION: Update German translation.
|
||||
@ -15,10 +29,24 @@
|
||||
- LOCALIZATION: Update Japanese translation.
|
||||
- LOCALIZATION: Update Simplified Chinese translation.
|
||||
- LOCALIZATION: Update Spanish translation.
|
||||
- MENU: New "ozone" menu driver.
|
||||
- MENU: Only show CRT SwitchRes if video display server is implemented (Windows/Linux for now)
|
||||
- MENU: User Interface -> Appearance -> 'Menu Font Green/Blue Color' settings now work properly.
|
||||
- MENU: Add option to enable in-menu sound effects.
|
||||
- MENU/D3D: Scissoring support (will be used for Ozone and menu widgets).
|
||||
- MENU/QT/WIMP: Allow building with MSVC2017.
|
||||
- MENU/QT/WIMP: Add detailed file browser table.
|
||||
- MENU/QT/WIMP: New grid view implementation that is faster and loads thumbnails on-demand.
|
||||
- MENU/QT/WIMP: Thumbnail drag and drop support.
|
||||
- MENU/RGUI: Overhaul custom theme interface + add wallpaper support.
|
||||
- MENU/RGUI: Thumbnail support and thumbnail downscaling.
|
||||
- MENU: Hide password values.
|
||||
- MENU/SOUNDS: Implement in-menu sound effects (not enabled by default for now, still experimental).
|
||||
- MIDI: Add a Linux ALSA driver for MIDI.
|
||||
- NETPLAY: Force fast-save-states when netlay is enabled
|
||||
- NETPLAY: Force fast-save-states when netplay is enabled.
|
||||
- NETPLAY: Allow quick joining subsystem lobbies.
|
||||
- OSX: Initial CoreAudio V3 audio driver (not yet used in release builds).
|
||||
- OSX: OpenGL 3.2 Core support for cores.
|
||||
- PS2: Initial PlayStation2 port.
|
||||
- PS4: Initial PlayStation4 port.
|
||||
- RECORDING: Implement recording options in the menu complete with quality profiles, streaming, and proper file naming
|
||||
@ -29,17 +57,24 @@
|
||||
- SUBSYSTEM: Remember the last used folder to make loading subsystem type content faster
|
||||
- SWITCH/LIBNX: Improve touch scaling calculation.
|
||||
- SWITCH: Proper button labels.
|
||||
- TVOS: Initial tvOS port.
|
||||
- VULKAN: Fix RGUI crashing at startup.
|
||||
- VULKAN/RGUI: Enable 'Menu Linear Filter' option.
|
||||
- VULKAN: Fix secondary screens in overlays not working.
|
||||
- WAYLAND: Implement idle-inhibit support (needed for screensaver suspend).
|
||||
- WAYLAND: Fix fullscreen toggle.
|
||||
- WIIU: Initial netplay peer-to-peer support. Network information working.
|
||||
- WINDOWS/WSA: Network Information info is blank until first network operation.
|
||||
- WINDOWS: Fix an ancient bug that caused wrong mappings for keyboard arrows
|
||||
- WINDOWS: Remember window size and position if so desired
|
||||
- WINDOWS: Fix an ancient bug that caused wrong mappings for keyboard arrows.
|
||||
- WINDOWS: Remember window size and position if so desired.
|
||||
- WINDOWS: SSL/TLS connections now work properly.
|
||||
- WINDOWS: Fall back to GDI driver if no accelerated graphics driver is found.
|
||||
- UWP: Initial UWP port.
|
||||
- VFS: Update to version 3.
|
||||
- XBONE: Initial Xbox One port.
|
||||
- XMB/OZONE: Add more icons
|
||||
- XMB: Add Automatic Inverted theme
|
||||
- ???: Easter Egg
|
||||
|
||||
# 1.7.5
|
||||
- CAMERA: Fix Video4Linux2 driver that broke years ago.
|
||||
|
114
CONTRIBUTING.md
114
CONTRIBUTING.md
@ -1,58 +1,58 @@
|
||||
# Contributing to RetroArch
|
||||
|
||||
If you are a developer and want to contribute to the development of RetroArch, please read this.
|
||||
If you have found a bug and want to submit a minor patch or a bug report, please read this as well.
|
||||
|
||||
# Submitting a bug report
|
||||
When submitting a bug report, make sure that the bug is local to RetroArch.
|
||||
A bug in a libretro core or something deemed to be external is likely to be closed very fast.
|
||||
If you still suspect a bug in RetroArch, make sure to test with several cores to make sure.
|
||||
|
||||
If you have troubles building RetroArch on Linux/BSD/OSX, make sure to paste shell output of ./configure,
|
||||
as well as config.log and shell output of make. If building on Windows, just paste shell output of make.
|
||||
|
||||
If the issue occurs during runtime, make sure to paste RetroArch's verbose log.
|
||||
If using Phoenix frontend, you can find log in (File -> Show Log) after running.
|
||||
In console, make sure to run with verbose (-v) flag.
|
||||
|
||||
# Pull Requests
|
||||
Outside contributions are generally only accepted in the form of a pull request. The process is very simple.
|
||||
Fork RetroArch, make your changes, and issue a pull request on GitHub. This can all be done within the browser.
|
||||
The changes are reviewed, and might be merged in. If the pull request isn't acceptable at the time,
|
||||
note that it's possible to continue pushing up commits to your branch.
|
||||
|
||||
If you want to develop a larger feature,
|
||||
we'd like to discuss this first (ideally on IRC) so that you don't risk developing something
|
||||
that won't be merged. A pull request with a proof-of-concept is fine, but please indicate so.
|
||||
|
||||
## libretro API
|
||||
If you wish to add functionality to libretro's API, it can take some time to merge in, because changes
|
||||
to libretro API will affect other projects as well, and we highly value API/ABI stability.
|
||||
Features will only be added when deemed *necessary* for a concrete libretro core to function properly.
|
||||
Features will not be added on basis of hypothetical libretro implementations.
|
||||
|
||||
# Coding style
|
||||
Having a consistent code style throughout the code base is highly valued.
|
||||
Please look through the code to get a feel for the coding style.
|
||||
A pull request may be asked to fix the coding style before submission.
|
||||
In other cases, a pull request may be followed up with a "style nit commit".
|
||||
|
||||
## Non-obvious things:
|
||||
- Code should be both ISO C99 and ISO C++ compatible. This dual requirement is for XBox360 and MSVC in general. Think of it as a C++ compatible subset of C99.
|
||||
- Warnings are not allowed (-Wall). Make sure your code is warning-free. Note that warning sensitivity differs a bit across compiler versions.
|
||||
- Using deprecated APIs is discouraged.
|
||||
|
||||
# Copyright Headers and AUTHORS
|
||||
If you have contributed to a part of a source file (a chunk of code that's written by you),
|
||||
you should add yourself to the copyright header in that file.
|
||||
If you have contributed significantly
|
||||
(a feature, a contribution you can "name", e.g. "Added audio driver foo"), you should add yourself to AUTHORS file.
|
||||
We'd like your full name and email, and which features you have been part of.
|
||||
|
||||
# IRC
|
||||
Active development happens on IRC. (#retroarch @ irc.freenode.org)
|
||||
We value discussing things in "real-time".
|
||||
|
||||
# Commit Access
|
||||
Contributors who show a track record of making good pull requests over time will eventually get commit access to the repo.
|
||||
# Contributing to RetroArch
|
||||
|
||||
If you are a developer and want to contribute to the development of RetroArch, please read this.
|
||||
If you have found a bug and want to submit a minor patch or a bug report, please read this as well.
|
||||
|
||||
# Submitting a bug report
|
||||
When submitting a bug report, make sure that the bug is local to RetroArch.
|
||||
A bug in a libretro core or something deemed to be external is likely to be closed very fast.
|
||||
If you still suspect a bug in RetroArch, make sure to test with several cores to make sure.
|
||||
|
||||
If you have troubles building RetroArch on Linux/BSD/OSX, make sure to paste shell output of ./configure,
|
||||
as well as config.log and shell output of make. If building on Windows, just paste shell output of make.
|
||||
|
||||
If the issue occurs during runtime, make sure to paste RetroArch's verbose log.
|
||||
If using Phoenix frontend, you can find log in (File -> Show Log) after running.
|
||||
In console, make sure to run with verbose (-v) flag.
|
||||
|
||||
# Pull Requests
|
||||
Outside contributions are generally only accepted in the form of a pull request. The process is very simple.
|
||||
Fork RetroArch, make your changes, and issue a pull request on GitHub. This can all be done within the browser.
|
||||
The changes are reviewed, and might be merged in. If the pull request isn't acceptable at the time,
|
||||
note that it's possible to continue pushing up commits to your branch.
|
||||
|
||||
If you want to develop a larger feature,
|
||||
we'd like to discuss this first (ideally on IRC) so that you don't risk developing something
|
||||
that won't be merged. A pull request with a proof-of-concept is fine, but please indicate so.
|
||||
|
||||
## libretro API
|
||||
If you wish to add functionality to libretro's API, it can take some time to merge in, because changes
|
||||
to libretro API will affect other projects as well, and we highly value API/ABI stability.
|
||||
Features will only be added when deemed *necessary* for a concrete libretro core to function properly.
|
||||
Features will not be added on basis of hypothetical libretro implementations.
|
||||
|
||||
# Coding style
|
||||
Having a consistent code style throughout the code base is highly valued.
|
||||
Please look through the code to get a feel for the coding style.
|
||||
A pull request may be asked to fix the coding style before submission.
|
||||
In other cases, a pull request may be followed up with a "style nit commit".
|
||||
|
||||
## Non-obvious things:
|
||||
- Code should be both ISO C99 and ISO C++ compatible. This dual requirement is for XBox360 and MSVC in general. Think of it as a C++ compatible subset of C99.
|
||||
- Warnings are not allowed (-Wall). Make sure your code is warning-free. Note that warning sensitivity differs a bit across compiler versions.
|
||||
- Using deprecated APIs is discouraged.
|
||||
|
||||
# Copyright Headers and AUTHORS
|
||||
If you have contributed to a part of a source file (a chunk of code that's written by you),
|
||||
you should add yourself to the copyright header in that file.
|
||||
If you have contributed significantly
|
||||
(a feature, a contribution you can "name", e.g. "Added audio driver foo"), you should add yourself to AUTHORS file.
|
||||
We'd like your full name and email, and which features you have been part of.
|
||||
|
||||
# IRC
|
||||
Active development happens on IRC. (#retroarch @ irc.freenode.org)
|
||||
We value discussing things in "real-time".
|
||||
|
||||
# Commit Access
|
||||
Contributors who show a track record of making good pull requests over time will eventually get commit access to the repo.
|
||||
This typically happens when the "overhead" of looking through pull requests over time becomes a burden.
|
9
Makefile
9
Makefile
@ -19,6 +19,7 @@ TARGET = retroarch
|
||||
OBJ :=
|
||||
LIBS :=
|
||||
DEF_FLAGS :=
|
||||
ASFLAGS :=
|
||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
|
||||
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
||||
|
||||
@ -171,7 +172,7 @@ all: $(TARGET) config.mk
|
||||
$(MOC_SRC):
|
||||
@$(if $(Q), $(shell echo echo MOC $<),)
|
||||
$(eval MOC_TMP := $(patsubst %.h,%_moc.cpp,$@))
|
||||
$(Q)$(MOC) -o $(MOC_TMP) $<
|
||||
$(Q)QT_SELECT=$(QT_VERSION) $(MOC) -o $(MOC_TMP) $<
|
||||
|
||||
$(foreach x,$(join $(addsuffix :,$(MOC_SRC)),$(MOC_HEADERS)),$(eval $x))
|
||||
|
||||
@ -253,15 +254,9 @@ install: $(TARGET)
|
||||
@if test -d media/assets && test $(HAVE_ASSETS); then \
|
||||
echo "Installing media assets..."; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
if test $(HAVE_ZARCH) = 1; then \
|
||||
cp -r media/assets/zarch/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_MATERIALUI) = 1; then \
|
||||
cp -r media/assets/glui/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_NUKLEAR) = 1; then \
|
||||
cp -r media/assets/nuklear/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_XMB) = 1; then \
|
||||
cp -r media/assets/xmb/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
|
@ -19,6 +19,6 @@ $(foreach x,$(join $(addsuffix :,$(MOC_SRC)),$(MOC_HEADERS)),$(eval $x))
|
||||
|
||||
generate: $(MOC_SRC)
|
||||
@echo $(MOC_SRC)
|
||||
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
||||
@echo '$*=$($*)'
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This build was put together and is maintained by ModMyClassic.com for Libretro.
|
||||
# The purpose is to give Libretro a proper "official" build platform for classic consoles.
|
||||
# If you need any help in building for the classics or have any questions then please visit
|
||||
# https://modmyclassic.com/comp and we will help in any way possible!
|
||||
# https://modmyclassic.com/comp and we will help in any way possible!
|
||||
|
||||
# Building Prerequisites ##############
|
||||
# arm-linux-gnueabihf-gcc-8
|
||||
@ -79,7 +79,7 @@ retroarch:
|
||||
rm -fr /tmp/$(HAKCHI_DIR) #clean up tmp
|
||||
|
||||
#COMMODORE 64 MINI BUILD (WIP)
|
||||
|
||||
|
||||
#Clean down dirty files
|
||||
rm -f version.all version.dtd
|
||||
mv version_BACKUP.all version.all && mv version_BACKUP.dtd version.dtd
|
||||
|
235
Makefile.common
235
Makefile.common
@ -27,10 +27,6 @@ ifeq ($(HAVE_LIBRETRODB),)
|
||||
HAVE_LIBRETRODB = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEO_PROCESSOR), 1)
|
||||
DEFINES += -DHAVE_VIDEO_PROCESSOR
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SOCKET_LEGACY), 1)
|
||||
DEFINES += -DHAVE_SOCKET_LEGACY
|
||||
endif
|
||||
@ -67,8 +63,14 @@ ifeq ($(VULKAN_DEBUG), 1)
|
||||
DEF_FLAGS += -DVULKAN_DEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_HARD_FLOAT), 1)
|
||||
DEFINES += -mfloat-abi=hard
|
||||
ifeq ($(HAVE_FLOATHARD), 1)
|
||||
DEF_FLAGS += $(FLOATHARD_CFLAGS)
|
||||
ASFLAGS += $(FLOATHARD_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FLOATSOFTFP), 1)
|
||||
DEF_FLAGS += $(FLOATSOFTFP_CFLAGS)
|
||||
ASFLAGS += $(FLOATSOFTFP_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(TDM_GCC),)
|
||||
@ -233,7 +235,6 @@ OBJ += frontend/frontend.o \
|
||||
tasks/task_screenshot.o \
|
||||
tasks/task_powerstate.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/scaler/scaler.o \
|
||||
gfx/drivers_shader/shader_null.o \
|
||||
gfx/video_shader_parse.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/scaler/pixconv.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/scaler/scaler_int.o \
|
||||
@ -343,7 +344,7 @@ ifeq ($(HAVE_QT), 1)
|
||||
ui/drivers/qt/coreinfodialog.o \
|
||||
ui/drivers/qt/playlistentrydialog.o \
|
||||
ui/drivers/qt/viewoptionsdialog.o \
|
||||
ui/drivers/qt/playlist.o \
|
||||
ui/drivers/qt/qt_playlist.o \
|
||||
ui/drivers/qt/updateretroarch.o \
|
||||
ui/drivers/qt/thumbnaildownload.o \
|
||||
ui/drivers/qt/thumbnailpackdownload.o \
|
||||
@ -374,6 +375,10 @@ ifeq ($(HAVE_SSA),1)
|
||||
LIBS += $(SSA_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SSE),1)
|
||||
DEF_FLAGS += $(SSE_LIBS)
|
||||
endif
|
||||
|
||||
# LibretroDB
|
||||
|
||||
ifeq ($(HAVE_LIBRETRODB), 1)
|
||||
@ -506,7 +511,16 @@ endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO), 1)
|
||||
OBJ += audio/drivers/coreaudio.o
|
||||
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
|
||||
HAVE_COREAUDIO_LIBS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO3), 1)
|
||||
OBJ += audio/drivers/coreaudio3.o
|
||||
HAVE_COREAUDIO_LIBS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO_LIBS), 1)
|
||||
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CORETEXT), 1)
|
||||
@ -625,7 +639,10 @@ ifeq ($(HAVE_NEON),1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler_neon.o \
|
||||
audio/drivers_resampler/cc_resampler_neon.o \
|
||||
memory/neon/memcpy-neon.o
|
||||
DEFINES += -DHAVE_NEON
|
||||
|
||||
DEFINES += -DHAVE_NEON
|
||||
ASFLAGS += $(NEON_ASFLAGS)
|
||||
DEF_FLAGS += $(NEON_CFLAGS)
|
||||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float.o \
|
||||
@ -651,10 +668,6 @@ endif
|
||||
|
||||
# XMB and MaterialUI are always enabled if supported and not explicitly disabled
|
||||
ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
ifeq ($(HAVE_ZARCH),)
|
||||
HAVE_ZARCH = 0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RGUI),)
|
||||
HAVE_RGUI = 1
|
||||
endif
|
||||
@ -663,14 +676,10 @@ ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
HAVE_MATERIALUI = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NUKLEAR),)
|
||||
HAVE_NUKLEAR = 0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XMB),)
|
||||
HAVE_XMB = 1
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(HAVE_STRIPES),)
|
||||
HAVE_STRIPES = 0
|
||||
endif
|
||||
@ -679,10 +688,8 @@ ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
HAVE_OZONE = 1
|
||||
endif
|
||||
else
|
||||
HAVE_ZARCH ?= 0
|
||||
HAVE_RGUI ?= 0
|
||||
HAVE_MATERIALUI ?= 0
|
||||
HAVE_NUKLEAR ?= 0
|
||||
HAVE_XMB ?= 0
|
||||
HAVE_STRIPES ?= 0
|
||||
HAVE_OZONE ?= 0
|
||||
@ -703,21 +710,6 @@ ifeq ($(HAVE_MENU), 1)
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NUKLEAR), 1)
|
||||
OBJ += menu/drivers/nuklear/nk_common.o \
|
||||
menu/drivers/nuklear/nk_menu.o \
|
||||
menu/drivers/nuklear/nk_wnd_debug.o \
|
||||
menu/drivers/nuklear.o
|
||||
DEFINES += -DHAVE_NUKLEAR
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZARCH), 1)
|
||||
OBJ += menu/drivers/zarch.o
|
||||
DEFINES += -DHAVE_ZARCH
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XMB), 1)
|
||||
OBJ += menu/drivers/xmb.o
|
||||
DEFINES += -DHAVE_XMB
|
||||
@ -1061,9 +1053,7 @@ endif
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_GLSL
|
||||
OBJ += gfx/drivers/gl.o \
|
||||
gfx/drivers_renderchain/gl2_renderchain.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o \
|
||||
gfx/common/gl_common.o \
|
||||
gfx/drivers_font/gl_raster_font.o \
|
||||
$(LIBRETRO_COMM_DIR)/glsym/rglgen.o
|
||||
|
||||
@ -1160,7 +1150,6 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
endif
|
||||
|
||||
OBJ += gfx/drivers_shader/shader_glsl.o
|
||||
DEFINES += -DHAVE_GLSL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
@ -1170,36 +1159,27 @@ ifeq ($(HAVE_EGL), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
HAVE_SDL=0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/drivers/sdl_gfx.o \
|
||||
input/drivers/sdl_input.o \
|
||||
input/drivers_joypad/sdl_joypad.o \
|
||||
audio/drivers/sdl_audio.o
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
endif
|
||||
|
||||
DEFINES += $(SDL_CFLAGS) $(BSD_LOCAL_INC)
|
||||
HAVE_SDL_COMMON = 1
|
||||
OBJ += gfx/drivers/sdl2_gfx.o
|
||||
DEFINES += $(SDL2_CFLAGS)
|
||||
LIBS += $(SDL2_LIBS)
|
||||
else ifeq ($(HAVE_SDL), 1)
|
||||
HAVE_SDL_COMMON = 1
|
||||
OBJ += gfx/drivers/sdl_gfx.o
|
||||
DEFINES += $(SDL_CFLAGS)
|
||||
LIBS += $(SDL_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
OBJ += gfx/drivers/sdl2_gfx.o \
|
||||
input/drivers/sdl_input.o \
|
||||
ifeq ($(HAVE_SDL_COMMON), 1)
|
||||
OBJ += input/drivers/sdl_input.o \
|
||||
input/drivers_joypad/sdl_joypad.o \
|
||||
audio/drivers/sdl_audio.o
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
endif
|
||||
|
||||
DEFINES += $(SDL2_CFLAGS) $(BSD_LOCAL_INC)
|
||||
LIBS += $(SDL2_LIBS)
|
||||
HAVE_SDL = 0
|
||||
DEFINES += $(BSD_LOCAL_INC)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XSHM), 1)
|
||||
@ -1254,8 +1234,6 @@ endif
|
||||
ifeq ($(HAVE_DISPMANX), 1)
|
||||
OBJ += gfx/drivers/dispmanx_gfx.o
|
||||
HAVE_VIDEOCORE = 1
|
||||
LIBS += $(DISPMANX_LIBS)
|
||||
DEFINES += $(DISPMANX_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SUNXI), 1)
|
||||
@ -1547,8 +1525,6 @@ ifeq ($(HAVE_ZLIB), 1)
|
||||
else
|
||||
LIBS += $(ZLIB_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CHD), 1)
|
||||
DEF_FLAGS += -I$(LIBRETRO_COMM_DIR)/formats/libchdr
|
||||
DEFINES += -DHAVE_CHD -DWANT_SUBCODE -DWANT_RAW_DATA_SECTOR
|
||||
@ -1557,19 +1533,16 @@ ifeq ($(HAVE_CHD), 1)
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_chd.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_huffman.o \
|
||||
$(LIBRETRO_COMM_DIR)/streams/chd_stream.o
|
||||
|
||||
ifeq ($(HAVE_FLAC), 1)
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zlib.o
|
||||
ifeq ($(HAVE_FLAC),1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac_codec.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_7ZIP), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_lzma.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZLIB), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zlib.o
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RTGA), 1)
|
||||
@ -1612,7 +1585,8 @@ endif
|
||||
|
||||
ifeq ($(HAVE_V4L2),1)
|
||||
OBJ += camera/drivers/video4linux2.o
|
||||
ifeq ($(HAVE_VIDEO_PROCESSOR),1)
|
||||
ifeq ($(HAVE_VIDEOPROCESSOR),1)
|
||||
DEFINES += -DHAVE_VIDEOPROCESSOR
|
||||
OBJ += cores/libretro-video-processor/video_processor_v4l2.o
|
||||
endif
|
||||
DEFINES += -DHAVE_V4L2
|
||||
@ -1665,54 +1639,78 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
network/netplay/netplay_buf.o \
|
||||
network/netplay/netplay_room_parse.o
|
||||
|
||||
# Retro Achievements
|
||||
# RetroAchievements
|
||||
ifeq ($(HAVE_CHEEVOS), 1)
|
||||
DEFINES += -DHAVE_CHEEVOS
|
||||
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/badges.o \
|
||||
cheevos/var.o \
|
||||
cheevos/cond.o
|
||||
|
||||
ifeq ($(HAVE_LUA), 1)
|
||||
DEFINES += -DHAVE_LUA \
|
||||
-DLUA_32BITS \
|
||||
-Ideps/lua/src
|
||||
OBJ += deps/lua/src/lapi.o \
|
||||
deps/lua/src/lcode.o \
|
||||
deps/lua/src/lctype.o \
|
||||
deps/lua/src/ldebug.o \
|
||||
deps/lua/src/ldo.o \
|
||||
deps/lua/src/ldump.o \
|
||||
deps/lua/src/lfunc.o \
|
||||
deps/lua/src/lgc.o \
|
||||
deps/lua/src/llex.o \
|
||||
deps/lua/src/lmem.o \
|
||||
deps/lua/src/lobject.o \
|
||||
deps/lua/src/lopcodes.o \
|
||||
deps/lua/src/lparser.o \
|
||||
deps/lua/src/lstate.o \
|
||||
deps/lua/src/lstring.o \
|
||||
deps/lua/src/ltable.o \
|
||||
deps/lua/src/ltm.o \
|
||||
deps/lua/src/lundump.o \
|
||||
deps/lua/src/lvm.o \
|
||||
deps/lua/src/lzio.o \
|
||||
deps/lua/src/lauxlib.o \
|
||||
deps/lua/src/lbaselib.o \
|
||||
deps/lua/src/lbitlib.o \
|
||||
deps/lua/src/lcorolib.o \
|
||||
deps/lua/src/ldblib.o \
|
||||
deps/lua/src/liolib.o \
|
||||
deps/lua/src/lmathlib.o \
|
||||
deps/lua/src/loslib.o \
|
||||
deps/lua/src/lstrlib.o \
|
||||
deps/lua/src/ltablib.o \
|
||||
deps/lua/src/lutf8lib.o \
|
||||
deps/lua/src/loadlib.o \
|
||||
deps/lua/src/linit.o
|
||||
ifeq ($(HAVE_NEW_CHEEVOS), 1)
|
||||
DEFINES += -DHAVE_NEW_CHEEVOS \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ideps/lua/src
|
||||
OBJ += cheevos-new/cheevos.o \
|
||||
cheevos-new/badges.o \
|
||||
cheevos-new/fixup.o \
|
||||
cheevos-new/parser.o \
|
||||
cheevos-new/hash.o \
|
||||
deps/rcheevos/src/rcheevos/trigger.o \
|
||||
deps/rcheevos/src/rcheevos/condset.o \
|
||||
deps/rcheevos/src/rcheevos/condition.o \
|
||||
deps/rcheevos/src/rcheevos/operand.o \
|
||||
deps/rcheevos/src/rcheevos/term.o \
|
||||
deps/rcheevos/src/rcheevos/expression.o \
|
||||
deps/rcheevos/src/rcheevos/value.o \
|
||||
deps/rcheevos/src/rcheevos/lboard.o \
|
||||
deps/rcheevos/src/rcheevos/alloc.o \
|
||||
deps/rcheevos/src/rcheevos/format.o \
|
||||
deps/rcheevos/src/rurl/url.o
|
||||
|
||||
ifeq ($(HAVE_LUA), 1)
|
||||
DEFINES += -DHAVE_LUA \
|
||||
-DLUA_32BITS \
|
||||
-Ideps/lua/src
|
||||
OBJ += deps/lua/src/lapi.o \
|
||||
deps/lua/src/lcode.o \
|
||||
deps/lua/src/lctype.o \
|
||||
deps/lua/src/ldebug.o \
|
||||
deps/lua/src/ldo.o \
|
||||
deps/lua/src/ldump.o \
|
||||
deps/lua/src/lfunc.o \
|
||||
deps/lua/src/lgc.o \
|
||||
deps/lua/src/llex.o \
|
||||
deps/lua/src/lmem.o \
|
||||
deps/lua/src/lobject.o \
|
||||
deps/lua/src/lopcodes.o \
|
||||
deps/lua/src/lparser.o \
|
||||
deps/lua/src/lstate.o \
|
||||
deps/lua/src/lstring.o \
|
||||
deps/lua/src/ltable.o \
|
||||
deps/lua/src/ltm.o \
|
||||
deps/lua/src/lundump.o \
|
||||
deps/lua/src/lvm.o \
|
||||
deps/lua/src/lzio.o \
|
||||
deps/lua/src/lauxlib.o \
|
||||
deps/lua/src/lbaselib.o \
|
||||
deps/lua/src/lbitlib.o \
|
||||
deps/lua/src/lcorolib.o \
|
||||
deps/lua/src/ldblib.o \
|
||||
deps/lua/src/liolib.o \
|
||||
deps/lua/src/lmathlib.o \
|
||||
deps/lua/src/loslib.o \
|
||||
deps/lua/src/lstrlib.o \
|
||||
deps/lua/src/ltablib.o \
|
||||
deps/lua/src/lutf8lib.o \
|
||||
deps/lua/src/loadlib.o \
|
||||
deps/lua/src/linit.o
|
||||
else
|
||||
DEFINES += -DRC_DISABLE_LUA
|
||||
endif
|
||||
|
||||
# if not HAVE_NEW_CHEEVOS
|
||||
else
|
||||
DEFINES += -DRC_DISABLE_LUA
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/badges.o \
|
||||
cheevos/var.o \
|
||||
cheevos/cond.o
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1720,6 +1718,11 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
NEED_CXX_LINKER = 1
|
||||
DEFINES += -DHAVE_DISCORD
|
||||
DEFINES += -Ideps/discord-rpc/include/ -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/
|
||||
|
||||
ifneq ($(HAVE_THREADS), 1)
|
||||
DEFINES += -DDISCORD_DISABLE_IO_THREAD
|
||||
endif
|
||||
|
||||
OBJ += deps/discord-rpc/src/discord_rpc.o \
|
||||
deps/discord-rpc/src/rpc_connection.o \
|
||||
deps/discord-rpc/src/serialization.o \
|
||||
|
@ -68,7 +68,6 @@ else
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
@ -137,7 +136,6 @@ CFLAGS += -I. \
|
||||
-Ideps/libz \
|
||||
-Ideps/7zip \
|
||||
-Ideps/stb \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ilibretro-common/include
|
||||
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
|
||||
@ -280,4 +278,3 @@ clean:
|
||||
rm -f ctr/3dsx_custom_crt0.o
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -40,7 +40,7 @@ OBJ := ctr/ctr_system.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 \
|
||||
@ -219,4 +219,3 @@ clean:
|
||||
rm -f ctr/3dsx_custom_crt0.o
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -112,7 +112,7 @@ else ifeq ($(libogc_platform), 1)
|
||||
EXT_INTER_TARGET := $(TARGET_NAME)_$(platform).elf
|
||||
|
||||
INCLUDE += -I. -I$(DEVKITPRO)/libogc/include -Ideps/libz -Iwii/libogc/include
|
||||
|
||||
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
CFLAGS += -DEXTERNAL_LIBOGC
|
||||
CXXFLAGS += -DEXTERNAL_LIBOGC
|
||||
@ -384,7 +384,7 @@ else ifeq ($(platform), windows_msvc2003_x86)
|
||||
|
||||
PLATCFLAGS += -D_WIN32 -DWINVER=0x0400 -D_WIN32_WINNT=0x0400 -D__STDC_CONSTANT_MACROS -D_MBCS -D_VC80_UPGRADE=0x0710
|
||||
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib
|
||||
|
||||
|
||||
PATH := $(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../../Vc7/bin"):$(PATH)
|
||||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS71COMNTOOLS)../IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS71COMNTOOLS)../../Vc7/include")
|
||||
@ -432,7 +432,7 @@ else ifeq ($(platform), windows_msvc2005_x86)
|
||||
|
||||
PLATCFLAGS += -D_WIN32 -D_WIN32_WINNT=0x0410 -D__STDC_CONSTANT_MACROS -D_MBCS -DHAVE_EASTEREGG
|
||||
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib msimg32.lib
|
||||
|
||||
|
||||
PATH := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin"):$(PATH)
|
||||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/include")
|
||||
@ -766,7 +766,7 @@ else
|
||||
CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(PLATCFLAGS) $(INCLUDE)
|
||||
INCLUDE += -I./libretro-common/include \
|
||||
-Ideps \
|
||||
-Ideps/stb
|
||||
-Ideps/stb
|
||||
endif
|
||||
|
||||
OBJ = griffin/griffin.o $(PLATOBJS)
|
||||
@ -973,8 +973,8 @@ ifneq (,$(findstring msvc,$(platform)))
|
||||
LINKOUT = -out:
|
||||
LINK = link.exe
|
||||
else
|
||||
OBJOUT = -o
|
||||
LINKOUT = -o
|
||||
OBJOUT = -o
|
||||
LINKOUT = -o
|
||||
LINK = $(CXX)
|
||||
endif
|
||||
|
||||
|
@ -17,12 +17,12 @@ DEBUG ?= 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
GRIFFIN_BUILD = 0
|
||||
|
||||
OBJ :=
|
||||
OBJ :=
|
||||
|
||||
# For threading we need to overwrite some vars with global defines because devkitPro's includes
|
||||
# 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 := -D__SWITCH__=1 -U__linux__ -U__linux -DGLM_FORCE_PURE=1 -DRARCH_CONSOLE -DRARCH_INTERNAL -DGLOBAL_CONFIG_DIR='"/switch"' $(DEFINES_THREAD)
|
||||
DEFINES := -D__SWITCH__=1 -U__linux__ -U__linux -DGLM_FORCE_PURE=1 -DRARCH_CONSOLE -DRARCH_INTERNAL -DGLOBAL_CONFIG_DIR='"/switch"' $(DEFINES_THREAD) -DHAVE_STB_VORBIS
|
||||
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
HAVE_MENU_COMMON = 1
|
||||
@ -41,7 +41,8 @@ HAVE_NETWORKING = 1
|
||||
HAVE_NETPLAYDISCOVERY = 1
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
HAVE_CHD = 1
|
||||
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
||||
HAVE_STB_VORBIS = 1
|
||||
|
||||
# RetroArch libnx useful flags
|
||||
HAVE_THREADS = 1
|
||||
@ -55,18 +56,13 @@ HAVE_LANGEXTRA = 1
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
HAVE_EGL = 1
|
||||
HAVE_SHADERPIPELINE = 1
|
||||
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 1
|
||||
|
||||
HAVE_XMB = 1
|
||||
HAVE_OZONE = 1
|
||||
|
||||
HAVE_OVERLAY = 1
|
||||
else
|
||||
HAVE_RGUI = 1
|
||||
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 0
|
||||
HAVE_XMB = 0
|
||||
HAVE_OZONE = 0
|
||||
|
@ -29,7 +29,7 @@ ifneq (,$(findstring Darwin,$(UNAME_S)))
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# path to tools
|
||||
# path to tools
|
||||
#---------------------------------------------------------------------------------
|
||||
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
||||
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
||||
@ -56,7 +56,7 @@ ISVC=$(or $(VCBUILDHELPER_COMMAND),$(MSBUILDEXTENSIONSPATH32),$(MSBUILDEXTENSION
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
@ -30,18 +30,17 @@ else
|
||||
HAVE_RBMP := 1
|
||||
HAVE_RTGA := 1
|
||||
HAVE_ZLIB := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_EGL := 1
|
||||
HAVE_OPENGLES := 1
|
||||
HAVE_OPENGLES := 1
|
||||
HAVE_NETWORKING := 0
|
||||
HAVE_SOCKET_LEGACY := 0
|
||||
HAVE_MENU := 1
|
||||
HAVE_MENU_COMMON := 1
|
||||
HAVE_RGUI := 0
|
||||
HAVE_MATERIALUI := 0
|
||||
HAVE_XMB := 1
|
||||
HAVE_ZARCH := 0
|
||||
HAVE_MATERIALUI := 0
|
||||
HAVE_XMB := 1
|
||||
HAVE_THREADS := 1
|
||||
HAVE_LIBRETRODB := 1
|
||||
HAVE_CC_RESAMPLER := 1
|
||||
@ -118,12 +117,12 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
WHOLE_START := -Wl,--whole-archive
|
||||
WHOLE_END := -Wl,--no-whole-archive
|
||||
endif
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
|
||||
PS4_LIBS := -lps4link -ldebugnet -lorbisFile -lelfloader -lorbisKeyboard -lorbis2d -lpng -lz -lorbisGl -lorbisPad -lorbisAudio -lmod -lorbisFileBrowser -lorbisXbmFont -lSceNet_stub -lScePigletv2VSH_stub -lSceSystemService_stub -lSceUserService_stub -lScePad_stub -lSceAudioOut_stub -lSceIme_stub -lSceSysmodule_stub \
|
||||
-lPs4_extension_kernel_call_standard -lPs4_extension_kernel_execute_dynlib_prepare_dlclose -lPs4_common_kernel -lPs4_common_user -lPs4_common_generic -lPs4LibCInternalAdaptive_stub -lPs4LibKernelAdaptive_stub -lSceLibcInternal_stub -lkernel_stub -lps4Kernel_stub -lPs4_base_stub_resolve_minimal -lPs4_base_kernel_dlsym_standard -lPs4_base_kernel_seek_elf_address_standard -lPs4_base_assembler_register_parameter_standard -lPs4_base_assembler_system_call_standard
|
||||
|
||||
LIBS := $(WHOLE_START) -lretro_orbis $(WHOLE_END) $(PS4_LIBS)
|
||||
LIBS := $(WHOLE_START) -lretro_orbis $(WHOLE_END) $(PS4_LIBS)
|
||||
|
||||
TARGETS := $(TARGET).elf
|
||||
|
||||
@ -158,10 +157,10 @@ $(TARGET).elf: $(OBJ) libretro_orbis.a
|
||||
$(LD) $(CRTFILE) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(TARGET).elf
|
||||
rm -f $(OBJ) $(TARGET).elf
|
||||
rm -f $(OBJ:.o=.depend)
|
||||
|
||||
.PHONY: clean all
|
||||
.PHONY: clean all
|
||||
.PRECIOUS: %.depend
|
||||
|
||||
-include $(OBJ:.o=.depend)
|
||||
|
@ -36,7 +36,7 @@ retroarch.pnd: install
|
||||
pnd_make -c -p retroarch.pnd -d $(PNDDIR)/ -x $(PNDDIR)/PXML.xml -i $(PNDDIR)/icon.png
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.o
|
||||
rm -f audio/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
@ -52,4 +52,3 @@ clean:
|
||||
rm -f $(BINDIR)/retroarch-joyconfig
|
||||
rm -f $(PNDDIR)/readme.html
|
||||
rm -f retroarch
|
||||
|
||||
|
@ -77,7 +77,7 @@ EE_LDFLAGS = $(LDFLAGS)
|
||||
EE_LIBS = $(LIBS)
|
||||
EE_ASFLAGS = $(ASFLAGS)
|
||||
EE_INCS = $(INCDIR)
|
||||
EE_IRX_OBJ = $(IRX_OBJ)
|
||||
EE_IRX_OBJ = $(IRX_OBJ)
|
||||
EE_BIN = $(TARGET)
|
||||
EE_GPVAL = $(GPVAL)
|
||||
|
||||
@ -105,7 +105,7 @@ $(EE_IRX_OBJ):
|
||||
$(EE_BIN2O) $(EE_GPVAL) $(IRX_DIR)/$(@:.o=.irx) $@ $(@:.o=_irx)
|
||||
|
||||
#Include preferences
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.eeglobal
|
||||
|
||||
#Linking with C++
|
||||
|
@ -159,7 +159,7 @@ create-core:
|
||||
|
||||
create-npdrm-salamander:
|
||||
$(MAKE_FSELF_NPDRM) $(SALAMANDER_TARGET) $(EBOOT_PATH)
|
||||
|
||||
|
||||
create-salamander:
|
||||
$(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL)
|
||||
|
||||
|
@ -155,7 +155,7 @@ create-core:
|
||||
|
||||
create-npdrm-salamander:
|
||||
$(MAKE_FSELF_NPDRM) $(SALAMANDER_TARGET) $(EBOOT_PATH)
|
||||
|
||||
|
||||
create-salamander:
|
||||
$(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL)
|
||||
|
||||
|
@ -1,91 +1,91 @@
|
||||
CELL_BUILD_TOOLS = GCC
|
||||
CELL_SDK ?= /usr/local/cell
|
||||
HAVE_LOGGER = 0
|
||||
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.makedef.mk
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
EXE_EXT = .exe
|
||||
system_platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
system_platform = osx
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
system_platform = win
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
PPU_OPTIMIZE_LV := -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
STRIP = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-strip.exe
|
||||
|
||||
INCFLAGS = -I. -Idefines -Ilibretro-common/include -Ideps/libz
|
||||
DEFINES = -D__CELLOS_LV2__ -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_SYSUTILS -DHAVE_SYSMODULES -DHAVE_RARCH_EXEC
|
||||
|
||||
ifeq ($(DEX_BUILD), 1)
|
||||
DEFINES += -DDEX_BUILD
|
||||
endif
|
||||
|
||||
ifeq ($(CEX_BUILD), 1)
|
||||
DEFINES += -DCEX_BUILD
|
||||
endif
|
||||
|
||||
ifeq ($(ODE_BUILD), 1)
|
||||
DEFINES += -DODE_BUILD
|
||||
endif
|
||||
|
||||
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
|
||||
PPU_CXXFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
|
||||
|
||||
PPU_SRCS = frontend/frontend_salamander.c \
|
||||
frontend/frontend_driver.c \
|
||||
frontend/drivers/platform_ps3.c \
|
||||
frontend/drivers/platform_null.c \
|
||||
libretro-common/file/file_path.c \
|
||||
libretro-common/lists/dir_list.c \
|
||||
libretro-common/lists/string_list.c \
|
||||
libretro-common/file/retro_dirent.c \
|
||||
libretro-common/hash/rhash.c \
|
||||
libretro-common/string/stdstring.c \
|
||||
libretro-common/encodings/encoding_utf.c \
|
||||
libretro-common/compat/compat_strl.c \
|
||||
libretro-common/compat/compat_strcasestr.c \
|
||||
libretro-common/compat/fopen_utf8.c \
|
||||
libretro-common/streams/file_stream.c \
|
||||
libretro-common/vfs/vfs_implementation.c \
|
||||
libretro-common/file/config_file.c \
|
||||
file_path_str.c \
|
||||
verbosity.c
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
PPU_CFLAGS += -DHAVE_LOGGER
|
||||
PPU_SRCS += network/net_logger.c \
|
||||
libretro-common/net/net_compat.c \
|
||||
libretro-common/net/net_socket.c
|
||||
endif
|
||||
|
||||
PPU_TARGET = retroarch-salamander_ps3.elf
|
||||
|
||||
ifeq ($(CELL_BUILD_TOOLS),SNC)
|
||||
PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
else
|
||||
PPU_CFLAGS += -std=gnu99
|
||||
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
PPU_CLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
endif
|
||||
|
||||
PPU_LDLIBS += -lm -lnet_stub -lnetctl_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lsysutil_game_stub -lfs_stub -lsysutil_np_stub
|
||||
|
||||
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
CELL_BUILD_TOOLS = GCC
|
||||
CELL_SDK ?= /usr/local/cell
|
||||
HAVE_LOGGER = 0
|
||||
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.makedef.mk
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
EXE_EXT = .exe
|
||||
system_platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
system_platform = osx
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
system_platform = win
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
PPU_OPTIMIZE_LV := -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
STRIP = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-strip.exe
|
||||
|
||||
INCFLAGS = -I. -Idefines -Ilibretro-common/include -Ideps/libz
|
||||
DEFINES = -D__CELLOS_LV2__ -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_SYSUTILS -DHAVE_SYSMODULES -DHAVE_RARCH_EXEC
|
||||
|
||||
ifeq ($(DEX_BUILD), 1)
|
||||
DEFINES += -DDEX_BUILD
|
||||
endif
|
||||
|
||||
ifeq ($(CEX_BUILD), 1)
|
||||
DEFINES += -DCEX_BUILD
|
||||
endif
|
||||
|
||||
ifeq ($(ODE_BUILD), 1)
|
||||
DEFINES += -DODE_BUILD
|
||||
endif
|
||||
|
||||
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
|
||||
PPU_CXXFLAGS := $(PPU_OPTIMIZE_LV) $(INCFLAGS) $(DEFINES)
|
||||
|
||||
PPU_SRCS = frontend/frontend_salamander.c \
|
||||
frontend/frontend_driver.c \
|
||||
frontend/drivers/platform_ps3.c \
|
||||
frontend/drivers/platform_null.c \
|
||||
libretro-common/file/file_path.c \
|
||||
libretro-common/lists/dir_list.c \
|
||||
libretro-common/lists/string_list.c \
|
||||
libretro-common/file/retro_dirent.c \
|
||||
libretro-common/hash/rhash.c \
|
||||
libretro-common/string/stdstring.c \
|
||||
libretro-common/encodings/encoding_utf.c \
|
||||
libretro-common/compat/compat_strl.c \
|
||||
libretro-common/compat/compat_strcasestr.c \
|
||||
libretro-common/compat/fopen_utf8.c \
|
||||
libretro-common/streams/file_stream.c \
|
||||
libretro-common/vfs/vfs_implementation.c \
|
||||
libretro-common/file/config_file.c \
|
||||
file_path_str.c \
|
||||
verbosity.c
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
PPU_CFLAGS += -DHAVE_LOGGER
|
||||
PPU_SRCS += network/net_logger.c \
|
||||
libretro-common/net/net_compat.c \
|
||||
libretro-common/net/net_socket.c
|
||||
endif
|
||||
|
||||
PPU_TARGET = retroarch-salamander_ps3.elf
|
||||
|
||||
ifeq ($(CELL_BUILD_TOOLS),SNC)
|
||||
PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
else
|
||||
PPU_CFLAGS += -std=gnu99
|
||||
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
PPU_CLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
endif
|
||||
|
||||
PPU_LDLIBS += -lm -lnet_stub -lnetctl_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lsysutil_game_stub -lfs_stub -lsysutil_np_stub
|
||||
|
||||
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
|
@ -96,7 +96,7 @@ CXXFLAGS += $(SHARED_FLAGS)
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
CFLAGS += -O3 -g
|
||||
CFLAGS += -O3 -g
|
||||
CXXFLAGS += -03 -g
|
||||
endif
|
||||
|
||||
@ -128,4 +128,3 @@ clean:
|
||||
rm -f $(OBJ)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -25,7 +25,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
|
||||
@ -51,7 +51,7 @@ OBJS = frontend/frontend_salamander.o \
|
||||
libretro-common/hash/rhash.o \
|
||||
file_path_str.o \
|
||||
verbosity.o \
|
||||
bootstrap/psp1/kernel_functions.o
|
||||
bootstrap/psp1/kernel_functions.o
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build.mak
|
||||
|
@ -24,7 +24,6 @@ else
|
||||
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
|
||||
|
@ -32,10 +32,10 @@ ELF_TARGET := retroarch-salamander_wii.elf
|
||||
|
||||
INCLUDE := -I. -Ilibretro-common/include -Ideps/libz
|
||||
ifeq ($(EXTERNAL_LIBOGC), 1)
|
||||
INCLUDE += -I$(DEVKITPRO)/libogc/include
|
||||
INCLUDE += -I$(DEVKITPRO)/libogc/include
|
||||
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L.
|
||||
else
|
||||
INCLUDE += -Iwii/libogc/include
|
||||
INCLUDE += -Iwii/libogc/include
|
||||
LIBDIRS := -Lwii/libogc/libs/wii -L.
|
||||
endif
|
||||
|
||||
|
@ -122,7 +122,6 @@ endif
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 0
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_STB_FONT = 1
|
||||
|
@ -172,4 +172,3 @@ clean:
|
||||
rm -f *.d
|
||||
|
||||
.PHONY: all install uninstall clean
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
USAGE NOTES
|
||||
===========
|
||||
|
||||
This driver is meant for devices with Allwinner SoCs with Mali400 3D block and a
|
||||
This driver is meant for devices with Allwinner SoCs with Mali400 3D block and a
|
||||
good fbdev implementation. It is derived from the old Android GLES driver.
|
||||
|
||||
It was meant to be used on Cubieboard/Cubieboard2/Cubietruck, but it should not
|
||||
@ -19,7 +19,7 @@ First we will clone and build the kernel:
|
||||
git clone https://github.com/mireq/linux-sunxi.git -b sunxi-3.4 --depth 1
|
||||
|
||||
Now we edit drivers/video/sunxi/disp/dev_fb.c, and uncomment the line 1074:
|
||||
// Fb_wait_for_vsync(info);
|
||||
// Fb_wait_for_vsync(info);
|
||||
|
||||
It is assumed you have a cross-compiler installed, so we configure and build the kernel and modules:
|
||||
|
||||
@ -50,7 +50,7 @@ Now we need the headers. We can get them from here:
|
||||
|
||||
http://malideveloper.arm.com/develop-for-mali/sdks/opengl-es-sdk-for-linux/#opengl-es-sdk-for-linux-download
|
||||
|
||||
Download whatever version you want. We just get the headers from here, not machine-dependant compiled code.
|
||||
Download whatever version you want. We just get the headers from here, not machine-dependant compiled code.
|
||||
|
||||
Extract the files and copy the directories inside inc to /usr/include .
|
||||
|
||||
@ -60,20 +60,20 @@ In the end you should have this on your system:
|
||||
|
||||
/usr/include/EGL/
|
||||
eglext.h
|
||||
egl.h
|
||||
eglplatform.h
|
||||
egl.h
|
||||
eglplatform.h
|
||||
fbdev_window.h
|
||||
/usr/include/GLES/
|
||||
glext.h
|
||||
gl.h
|
||||
gl.h
|
||||
glplatform.h
|
||||
/usr/include/GLES2
|
||||
gl2ext.h
|
||||
gl2.h
|
||||
gl2.h
|
||||
gl2platform.h
|
||||
/usr/include/GLES3
|
||||
gl3ext.h
|
||||
gl3.h
|
||||
gl3.h
|
||||
gl3platform.h
|
||||
|
||||
To enable mali_fbdev you must configure RetroArch with --enable-gles and --enable-mali_fbdev.
|
||||
|
@ -148,7 +148,7 @@ Instructions for compiling and installing RetroArch can be found in the [Libretr
|
||||
|
||||
## CRT 15Khz Resolution Switching
|
||||
|
||||
CRT SwitchRes will turn on, on the fly. However, you will need to restart RetroArch to disable it. With CRT SwitchRes enable RetroArch will start in 2560 x 480 @ 60.
|
||||
CRT SwitchRes will turn on, on the fly. However, you will need to restart RetroArch to disable it. With CRT SwitchRes enable RetroArch will start in 2560 x 480 @ 60.
|
||||
|
||||
If you are running Windows, before enabling the CRT SwitchRes options please make sure you have installed CRTEmudriver and installed some modelines. The minimum modelines for all games to switch correctly are:
|
||||
|
||||
|
88
audio/audio_defines.h
Normal file
88
audio/audio_defines.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_DEFINES__H
|
||||
#define __AUDIO_DEFINES__H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 512
|
||||
|
||||
/* So we don't get complete line-noise when fast-forwarding audio. */
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
|
||||
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_STREAMS 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 4)
|
||||
|
||||
/* do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
|
||||
enum audio_mixer_system_slot
|
||||
{
|
||||
AUDIO_MIXER_SYSTEM_SLOT_OK = AUDIO_MIXER_MAX_STREAMS,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_CANCEL,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_NOTICE,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_BGM
|
||||
};
|
||||
|
||||
enum audio_action
|
||||
{
|
||||
AUDIO_ACTION_NONE = 0,
|
||||
AUDIO_ACTION_RATE_CONTROL_DELTA,
|
||||
AUDIO_ACTION_MIXER_MUTE_ENABLE,
|
||||
AUDIO_ACTION_MUTE_ENABLE,
|
||||
AUDIO_ACTION_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER
|
||||
};
|
||||
|
||||
enum audio_mixer_slot_selection_type
|
||||
{
|
||||
AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC = 0,
|
||||
AUDIO_MIXER_SLOT_SELECTION_MANUAL
|
||||
};
|
||||
|
||||
enum audio_mixer_stream_type
|
||||
{
|
||||
AUDIO_STREAM_TYPE_NONE = 0,
|
||||
AUDIO_STREAM_TYPE_USER,
|
||||
AUDIO_STREAM_TYPE_SYSTEM
|
||||
};
|
||||
|
||||
enum audio_mixer_state
|
||||
{
|
||||
AUDIO_STREAM_STATE_NONE = 0,
|
||||
AUDIO_STREAM_STATE_STOPPED,
|
||||
AUDIO_STREAM_STATE_PLAYING,
|
||||
AUDIO_STREAM_STATE_PLAYING_LOOPED,
|
||||
AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL
|
||||
};
|
||||
|
||||
typedef struct audio_statistics
|
||||
{
|
||||
float average_buffer_saturation;
|
||||
float std_deviation_percentage;
|
||||
float close_to_underrun;
|
||||
float close_to_blocking;
|
||||
unsigned samples;
|
||||
} audio_statistics_t;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
@ -21,10 +21,12 @@
|
||||
#include <lists/string_list.h>
|
||||
#include <audio/conversion/float_to_s16.h>
|
||||
#include <audio/conversion/s16_to_float.h>
|
||||
#include <audio/audio_resampler.h>
|
||||
#include <audio/dsp_filter.h>
|
||||
#include <file/file_path.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -35,6 +37,8 @@
|
||||
#include "../gfx/video_driver.h"
|
||||
#include "../record/record_driver.h"
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "../tasks/task_audio_mixer.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
|
||||
#include "../command.h"
|
||||
#include "../driver.h"
|
||||
@ -42,9 +46,17 @@
|
||||
#include "../retroarch.h"
|
||||
#include "../verbosity.h"
|
||||
#include "../list_special.h"
|
||||
#include "../file_path_special.h"
|
||||
#include "../content.h"
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#include <rthreads/rthreads.h>
|
||||
#endif
|
||||
|
||||
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
|
||||
|
||||
#define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac"
|
||||
|
||||
/**
|
||||
* db_to_gain:
|
||||
* @db : Decibels.
|
||||
@ -77,6 +89,9 @@ static const audio_driver_t *audio_drivers[] = {
|
||||
#ifdef HAVE_COREAUDIO
|
||||
&audio_coreaudio,
|
||||
#endif
|
||||
#ifdef HAVE_COREAUDIO3
|
||||
&audio_coreaudio3,
|
||||
#endif
|
||||
#ifdef HAVE_AL
|
||||
&audio_openal,
|
||||
#endif
|
||||
@ -137,7 +152,7 @@ static const audio_driver_t *audio_drivers[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct audio_mixer_stream audio_mixer_streams[AUDIO_MIXER_MAX_STREAMS] = {{0}};
|
||||
static struct audio_mixer_stream audio_mixer_streams[AUDIO_MIXER_MAX_SYSTEM_STREAMS] = {{0}};
|
||||
|
||||
static size_t audio_driver_chunk_size = 0;
|
||||
static size_t audio_driver_chunk_nonblock_size = 0;
|
||||
@ -185,13 +200,36 @@ static const audio_driver_t *current_audio = NULL;
|
||||
static void *audio_driver_context_audio_data = NULL;
|
||||
|
||||
static bool audio_suspended = false;
|
||||
static bool audio_is_threaded = false;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static slock_t* s_audio_driver_lock = NULL;
|
||||
#endif
|
||||
|
||||
static void audio_mixer_play_stop_sequential_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
static void audio_mixer_play_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
static void audio_mixer_menu_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
|
||||
enum resampler_quality audio_driver_get_resampler_quality(void)
|
||||
#ifdef HAVE_THREADS
|
||||
#define audio_driver_lock() \
|
||||
if (s_audio_driver_lock) \
|
||||
slock_lock(s_audio_driver_lock)
|
||||
#else
|
||||
#define audio_driver_lock()
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#define audio_driver_unlock() \
|
||||
if (s_audio_driver_lock) \
|
||||
slock_unlock(s_audio_driver_lock)
|
||||
#else
|
||||
#define audio_driver_unlock()
|
||||
#endif
|
||||
|
||||
static enum resampler_quality audio_driver_get_resampler_quality(void)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
@ -203,14 +241,14 @@ enum resampler_quality audio_driver_get_resampler_quality(void)
|
||||
|
||||
audio_mixer_stream_t *audio_driver_mixer_get_stream(unsigned i)
|
||||
{
|
||||
if (i > (AUDIO_MIXER_MAX_STREAMS-1))
|
||||
if (i > (AUDIO_MIXER_MAX_SYSTEM_STREAMS-1))
|
||||
return NULL;
|
||||
return &audio_mixer_streams[i];
|
||||
}
|
||||
|
||||
const char *audio_driver_mixer_get_stream_name(unsigned i)
|
||||
{
|
||||
if (i > (AUDIO_MIXER_MAX_STREAMS-1))
|
||||
if (i > (AUDIO_MIXER_MAX_SYSTEM_STREAMS-1))
|
||||
return "N/A";
|
||||
if (!string_is_empty(audio_mixer_streams[i].name))
|
||||
return audio_mixer_streams[i].name;
|
||||
@ -240,12 +278,12 @@ bool compute_audio_buffer_statistics(audio_statistics_t *stats)
|
||||
stats->samples = (unsigned)audio_driver_free_samples_count;
|
||||
|
||||
#ifdef WARPUP
|
||||
/* uint64 to double not implemented, fair chance
|
||||
/* uint64 to double not implemented, fair chance
|
||||
* signed int64 to double doesn't exist either */
|
||||
/* https://forums.libretro.com/t/unsupported-platform-help/13903/ */
|
||||
(void)stddev;
|
||||
#elif defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
/* FIXME: error C2520: conversion from unsigned __int64
|
||||
/* FIXME: error C2520: conversion from unsigned __int64
|
||||
* to double not implemented, use signed __int64 */
|
||||
(void)stddev;
|
||||
#else
|
||||
@ -263,9 +301,9 @@ bool compute_audio_buffer_statistics(audio_statistics_t *stats)
|
||||
stddev = (unsigned)
|
||||
sqrt((double)accum_var / (samples - 2));
|
||||
|
||||
stats->average_buffer_saturation = (1.0f - (float)avg
|
||||
stats->average_buffer_saturation = (1.0f - (float)avg
|
||||
/ audio_driver_buffer_size) * 100.0;
|
||||
stats->std_deviation_percentage = ((float)stddev
|
||||
stats->std_deviation_percentage = ((float)stddev
|
||||
/ audio_driver_buffer_size) * 100.0;
|
||||
#endif
|
||||
|
||||
@ -392,9 +430,9 @@ static bool audio_driver_deinit_internal(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void audio_driver_mixer_init(unsigned out_rate)
|
||||
static void audio_driver_mixer_init(unsigned audio_out_rate)
|
||||
{
|
||||
audio_mixer_init(out_rate);
|
||||
audio_mixer_init(audio_out_rate);
|
||||
}
|
||||
|
||||
static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
@ -447,6 +485,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
#ifdef HAVE_THREADS
|
||||
if (audio_cb_inited)
|
||||
{
|
||||
audio_is_threaded = true;
|
||||
RARCH_LOG("[Audio]: Starting threaded audio driver ...\n");
|
||||
if (!audio_init_thread(
|
||||
¤t_audio,
|
||||
@ -465,6 +504,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
audio_is_threaded = false;
|
||||
audio_driver_context_audio_data =
|
||||
current_audio->init(*settings->arrays.audio_device ?
|
||||
settings->arrays.audio_device : NULL,
|
||||
@ -507,6 +547,15 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
audio_source_ratio_original = audio_source_ratio_current =
|
||||
(double)settings->uints.audio_out_rate / audio_driver_input;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
if (s_audio_driver_lock)
|
||||
slock_free(s_audio_driver_lock);
|
||||
s_audio_driver_lock = slock_new();
|
||||
#endif
|
||||
|
||||
audio_resampler_lock_init();
|
||||
audio_resampler_lock();
|
||||
|
||||
if (!retro_resampler_realloc(
|
||||
&audio_driver_resampler_data,
|
||||
&audio_driver_resampler,
|
||||
@ -519,6 +568,8 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
audio_driver_active = false;
|
||||
}
|
||||
|
||||
audio_resampler_unlock();
|
||||
|
||||
aud_inp_data = (float*)malloc(max_bufsamples * sizeof(float));
|
||||
retro_assert(aud_inp_data != NULL);
|
||||
|
||||
@ -589,9 +640,13 @@ void audio_driver_set_nonblocking_state(bool enable)
|
||||
audio_driver_context_audio_data,
|
||||
settings->bools.audio_sync ? enable : true);
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
audio_driver_chunk_size = enable ?
|
||||
audio_driver_chunk_nonblock_size :
|
||||
audio_driver_chunk_block_size;
|
||||
|
||||
audio_driver_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -609,6 +664,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
bool is_paused = false;
|
||||
bool is_idle = false;
|
||||
bool is_slowmotion = false;
|
||||
bool is_active = false;
|
||||
const void *output_data = NULL;
|
||||
unsigned output_frames = 0;
|
||||
float audio_volume_gain = !audio_driver_mute_enable ?
|
||||
@ -617,9 +673,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.data_out = NULL;
|
||||
src_data.output_frames = 0;
|
||||
|
||||
recording_driver_lock();
|
||||
|
||||
if (recording_data)
|
||||
recording_push_audio(data, samples);
|
||||
|
||||
recording_driver_unlock();
|
||||
|
||||
runloop_get_status(&is_paused, &is_idle, &is_slowmotion,
|
||||
&is_perfcnt_enable);
|
||||
|
||||
@ -629,9 +689,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
!audio_driver_output_samples_buf)
|
||||
return;
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
convert_s16_to_float(audio_driver_input_data, data, samples,
|
||||
audio_volume_gain);
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
src_data.data_in = audio_driver_input_data;
|
||||
src_data.input_frames = samples >> 1;
|
||||
|
||||
@ -695,9 +759,15 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.ratio *= settings->floats.slowmotion_ratio;
|
||||
}
|
||||
|
||||
audio_driver_resampler->process(audio_driver_resampler_data, &src_data);
|
||||
audio_driver_lock();
|
||||
|
||||
if (audio_mixer_active)
|
||||
audio_resampler_lock();
|
||||
audio_driver_resampler->process(audio_driver_resampler_data, &src_data);
|
||||
audio_resampler_unlock();
|
||||
|
||||
is_active = audio_mixer_active;
|
||||
|
||||
if (is_active)
|
||||
{
|
||||
bool override = audio_driver_mixer_mute_enable ? true :
|
||||
(audio_driver_mixer_volume_gain != 1.0f) ? true : false;
|
||||
@ -707,6 +777,8 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.output_frames, mixer_gain, override);
|
||||
}
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
output_data = audio_driver_output_samples_buf;
|
||||
output_frames = (unsigned)src_data.output_frames;
|
||||
|
||||
@ -721,9 +793,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
output_frames *= sizeof(int16_t);
|
||||
}
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
if (current_audio->write(audio_driver_context_audio_data,
|
||||
output_data, output_frames * 2) < 0)
|
||||
audio_driver_active = false;
|
||||
|
||||
audio_driver_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -735,14 +811,24 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
**/
|
||||
void audio_driver_sample(int16_t left, int16_t right)
|
||||
{
|
||||
audio_driver_lock();
|
||||
|
||||
if (audio_suspended)
|
||||
{
|
||||
audio_driver_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
audio_driver_output_samples_conv_buf[audio_driver_data_ptr++] = left;
|
||||
audio_driver_output_samples_conv_buf[audio_driver_data_ptr++] = right;
|
||||
|
||||
if (audio_driver_data_ptr < audio_driver_chunk_size)
|
||||
{
|
||||
audio_driver_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
audio_driver_flush(audio_driver_output_samples_conv_buf,
|
||||
audio_driver_data_ptr);
|
||||
@ -753,9 +839,8 @@ void audio_driver_sample(int16_t left, int16_t right)
|
||||
void audio_driver_menu_sample(void)
|
||||
{
|
||||
static int16_t samples_buf[1024] = {0};
|
||||
struct retro_system_av_info
|
||||
*av_info = video_viewport_get_system_av_info();
|
||||
const struct retro_system_timing *info =
|
||||
struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
|
||||
const struct retro_system_timing *info =
|
||||
(const struct retro_system_timing*)&av_info->timing;
|
||||
unsigned sample_count = (info->sample_rate / info->fps) * 2;
|
||||
while (sample_count > 1024)
|
||||
@ -890,7 +975,7 @@ void audio_driver_monitor_adjust_system_rates(void)
|
||||
float video_refresh_rate = settings->floats.video_refresh_rate;
|
||||
float max_timing_skew = settings->floats.audio_max_timing_skew;
|
||||
struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
|
||||
const struct retro_system_timing *info =
|
||||
const struct retro_system_timing *info =
|
||||
(const struct retro_system_timing*)&av_info->timing;
|
||||
|
||||
if (info->sample_rate <= 0.0)
|
||||
@ -966,10 +1051,13 @@ bool audio_driver_find_driver(void)
|
||||
|
||||
void audio_driver_deinit_resampler(void)
|
||||
{
|
||||
audio_resampler_lock();
|
||||
if (audio_driver_resampler && audio_driver_resampler_data)
|
||||
audio_driver_resampler->free(audio_driver_resampler_data);
|
||||
audio_driver_resampler = NULL;
|
||||
audio_driver_resampler_data = NULL;
|
||||
audio_resampler_unlock();
|
||||
audio_resampler_lock_free();
|
||||
}
|
||||
|
||||
bool audio_driver_free_devices_list(void)
|
||||
@ -1053,7 +1141,7 @@ static int audio_mixer_find_index(audio_mixer_sound_t *sound)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++)
|
||||
for (i = 0; i < AUDIO_MIXER_MAX_SYSTEM_STREAMS; i++)
|
||||
{
|
||||
audio_mixer_sound_t *handle = audio_mixer_streams[i].handle;
|
||||
if (handle == sound)
|
||||
@ -1095,6 +1183,28 @@ static void audio_mixer_play_stop_cb(
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_mixer_menu_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason)
|
||||
{
|
||||
int idx = audio_mixer_find_index(sound);
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case AUDIO_MIXER_SOUND_FINISHED:
|
||||
if (idx >= 0)
|
||||
{
|
||||
unsigned i = (unsigned)idx;
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_STOPPED;
|
||||
audio_mixer_streams[i].volume = 0.0f;
|
||||
}
|
||||
break;
|
||||
case AUDIO_MIXER_SOUND_STOPPED:
|
||||
break;
|
||||
case AUDIO_MIXER_SOUND_REPEATED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_mixer_play_stop_sequential_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason)
|
||||
{
|
||||
@ -1112,6 +1222,11 @@ static void audio_mixer_play_stop_sequential_cb(
|
||||
if (!string_is_empty(audio_mixer_streams[i].name))
|
||||
free(audio_mixer_streams[i].name);
|
||||
|
||||
if (i < AUDIO_MIXER_MAX_STREAMS)
|
||||
audio_mixer_streams[i].stream_type = AUDIO_STREAM_TYPE_USER;
|
||||
else
|
||||
audio_mixer_streams[i].stream_type = AUDIO_STREAM_TYPE_SYSTEM;
|
||||
|
||||
audio_mixer_streams[i].name = NULL;
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE;
|
||||
audio_mixer_streams[i].volume = 0.0f;
|
||||
@ -1122,7 +1237,7 @@ static void audio_mixer_play_stop_sequential_cb(
|
||||
|
||||
i++;
|
||||
|
||||
for (; i < AUDIO_MIXER_MAX_STREAMS; i++)
|
||||
for (; i < AUDIO_MIXER_MAX_SYSTEM_STREAMS; i++)
|
||||
{
|
||||
if (audio_mixer_streams[i].state == AUDIO_STREAM_STATE_STOPPED)
|
||||
{
|
||||
@ -1139,10 +1254,11 @@ static void audio_mixer_play_stop_sequential_cb(
|
||||
}
|
||||
}
|
||||
|
||||
bool audio_driver_mixer_get_free_stream_slot(unsigned *id)
|
||||
static bool audio_driver_mixer_get_free_stream_slot(unsigned *id, enum audio_mixer_stream_type type)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++)
|
||||
unsigned i = (type == AUDIO_STREAM_TYPE_USER) ? 0 : AUDIO_MIXER_MAX_STREAMS;
|
||||
unsigned count = (type == AUDIO_STREAM_TYPE_USER) ? AUDIO_MIXER_MAX_STREAMS : AUDIO_MIXER_MAX_SYSTEM_STREAMS;
|
||||
for (; i < count; i++)
|
||||
{
|
||||
if (audio_mixer_streams[i].state == AUDIO_STREAM_STATE_NONE)
|
||||
{
|
||||
@ -1162,10 +1278,23 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
audio_mixer_stop_cb_t stop_cb = audio_mixer_play_stop_cb;
|
||||
bool looped = false;
|
||||
void *buf = NULL;
|
||||
|
||||
if (!audio_driver_mixer_get_free_stream_slot(&free_slot))
|
||||
|
||||
if (params->stream_type == AUDIO_STREAM_TYPE_NONE)
|
||||
return false;
|
||||
|
||||
switch (params->slot_selection_type)
|
||||
{
|
||||
case AUDIO_MIXER_SLOT_SELECTION_MANUAL:
|
||||
free_slot = params->slot_selection_idx;
|
||||
break;
|
||||
case AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC:
|
||||
default:
|
||||
if (!audio_driver_mixer_get_free_stream_slot(
|
||||
&free_slot, params->stream_type))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (params->state == AUDIO_STREAM_STATE_NONE)
|
||||
return false;
|
||||
|
||||
@ -1224,22 +1353,28 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
break;
|
||||
}
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
audio_mixer_active = true;
|
||||
|
||||
audio_mixer_streams[free_slot].name = !string_is_empty(params->basename) ? strdup(params->basename) : NULL;
|
||||
audio_mixer_streams[free_slot].name = !string_is_empty(params->basename) ? strdup(params->basename) : NULL;
|
||||
audio_mixer_streams[free_slot].buf = buf;
|
||||
audio_mixer_streams[free_slot].handle = handle;
|
||||
audio_mixer_streams[free_slot].voice = voice;
|
||||
audio_mixer_streams[free_slot].stream_type = params->stream_type;
|
||||
audio_mixer_streams[free_slot].type = params->type;
|
||||
audio_mixer_streams[free_slot].state = params->state;
|
||||
audio_mixer_streams[free_slot].volume = params->volume;
|
||||
audio_mixer_streams[free_slot].stop_cb = stop_cb;
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i)
|
||||
{
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return AUDIO_STREAM_STATE_NONE;
|
||||
|
||||
return audio_mixer_streams[i].state;
|
||||
@ -1249,7 +1384,7 @@ static void audio_driver_mixer_play_stream_internal(unsigned i, unsigned type)
|
||||
{
|
||||
bool set_state = false;
|
||||
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return;
|
||||
|
||||
switch (audio_mixer_streams[i].state)
|
||||
@ -1271,12 +1406,128 @@ static void audio_driver_mixer_play_stream_internal(unsigned i, unsigned type)
|
||||
audio_mixer_streams[i].state = (enum audio_mixer_state)type;
|
||||
}
|
||||
|
||||
static void audio_driver_load_menu_bgm_callback(void *task_data, void *user_data, const char *error)
|
||||
{
|
||||
bool contentless = false;
|
||||
bool is_inited = false;
|
||||
|
||||
content_get_status(&contentless, &is_inited);
|
||||
|
||||
if (!is_inited)
|
||||
audio_driver_mixer_play_menu_sound_looped(AUDIO_MIXER_SYSTEM_SLOT_BGM);
|
||||
}
|
||||
|
||||
void audio_driver_load_menu_sounds(void)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
char *sounds_path = NULL;
|
||||
char *sounds_fallback_path = NULL;
|
||||
const char *path_ok = NULL;
|
||||
const char *path_cancel = NULL;
|
||||
const char *path_notice = NULL;
|
||||
const char *path_bgm = NULL;
|
||||
struct string_list *list = NULL;
|
||||
struct string_list *list_fallback = NULL;
|
||||
unsigned i = 0;
|
||||
|
||||
sounds_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
sounds_fallback_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
sounds_path[0] = sounds_fallback_path[0] = '\0';
|
||||
|
||||
fill_pathname_join(
|
||||
sounds_fallback_path,
|
||||
settings->paths.directory_assets,
|
||||
"sounds",
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
|
||||
fill_pathname_application_special(sounds_path, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_SOUNDS);
|
||||
|
||||
list = dir_list_new(sounds_path, MENU_SOUND_FORMATS, false, false, false, false);
|
||||
list_fallback = dir_list_new(sounds_fallback_path, MENU_SOUND_FORMATS, false, false, false, false);
|
||||
|
||||
if (!list)
|
||||
{
|
||||
list = list_fallback;
|
||||
list_fallback = NULL;
|
||||
}
|
||||
|
||||
if (!list || list->size == 0)
|
||||
goto end;
|
||||
|
||||
if (list_fallback && list_fallback->size > 0)
|
||||
{
|
||||
for (i = 0; i < list_fallback->size; i++)
|
||||
{
|
||||
if (list->size == 0 || !string_list_find_elem(list, list_fallback->elems[i].data))
|
||||
{
|
||||
union string_list_elem_attr attr = {0};
|
||||
string_list_append(list, list_fallback->elems[i].data, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *path = list->elems[i].data;
|
||||
const char *ext = path_get_extension(path);
|
||||
char basename_noext[PATH_MAX_LENGTH];
|
||||
|
||||
basename_noext[0] = '\0';
|
||||
|
||||
fill_pathname_base_noext(basename_noext, path, sizeof(basename_noext));
|
||||
|
||||
if (audio_driver_mixer_extension_supported(ext))
|
||||
{
|
||||
if (string_is_equal_noncase(basename_noext, "ok"))
|
||||
path_ok = path;
|
||||
if (string_is_equal_noncase(basename_noext, "cancel"))
|
||||
path_cancel = path;
|
||||
if (string_is_equal_noncase(basename_noext, "notice"))
|
||||
path_notice = path;
|
||||
if (string_is_equal_noncase(basename_noext, "bgm"))
|
||||
path_bgm = path;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_ok && settings->bools.audio_enable_menu_ok)
|
||||
task_push_audio_mixer_load(path_ok, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_OK);
|
||||
if (path_cancel && settings->bools.audio_enable_menu_cancel)
|
||||
task_push_audio_mixer_load(path_cancel, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_CANCEL);
|
||||
if (path_notice && settings->bools.audio_enable_menu_notice)
|
||||
task_push_audio_mixer_load(path_notice, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_NOTICE);
|
||||
if (path_bgm && settings->bools.audio_enable_menu_bgm)
|
||||
task_push_audio_mixer_load(path_bgm, audio_driver_load_menu_bgm_callback, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_BGM);
|
||||
|
||||
end:
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
if (list_fallback)
|
||||
string_list_free(list_fallback);
|
||||
if (sounds_path)
|
||||
free(sounds_path);
|
||||
if (sounds_fallback_path)
|
||||
free(sounds_fallback_path);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_stream(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_menu_sound_looped(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_menu_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING_LOOPED);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_menu_sound(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_menu_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_stream_looped(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb;
|
||||
@ -1291,7 +1542,7 @@ void audio_driver_mixer_play_stream_sequential(unsigned i)
|
||||
|
||||
float audio_driver_mixer_get_stream_volume(unsigned i)
|
||||
{
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return 0.0f;
|
||||
|
||||
return audio_mixer_streams[i].volume;
|
||||
@ -1301,7 +1552,7 @@ void audio_driver_mixer_set_stream_volume(unsigned i, float vol)
|
||||
{
|
||||
audio_mixer_voice_t *voice = NULL;
|
||||
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return;
|
||||
|
||||
audio_mixer_streams[i].volume = vol;
|
||||
@ -1316,7 +1567,7 @@ void audio_driver_mixer_stop_stream(unsigned i)
|
||||
{
|
||||
bool set_state = false;
|
||||
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return;
|
||||
|
||||
switch (audio_mixer_streams[i].state)
|
||||
@ -1346,7 +1597,7 @@ void audio_driver_mixer_remove_stream(unsigned i)
|
||||
{
|
||||
bool destroy = false;
|
||||
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
if (i >= AUDIO_MIXER_MAX_SYSTEM_STREAMS)
|
||||
return;
|
||||
|
||||
switch (audio_mixer_streams[i].state)
|
||||
@ -1388,7 +1639,7 @@ static void audio_driver_mixer_deinit(void)
|
||||
|
||||
audio_mixer_active = false;
|
||||
|
||||
for (i = 0; i < AUDIO_MIXER_MAX_STREAMS; i++)
|
||||
for (i = 0; i < AUDIO_MIXER_MAX_SYSTEM_STREAMS; i++)
|
||||
{
|
||||
audio_driver_mixer_stop_stream(i);
|
||||
audio_driver_mixer_remove_stream(i);
|
||||
@ -1401,6 +1652,11 @@ bool audio_driver_deinit(void)
|
||||
{
|
||||
audio_driver_mixer_deinit();
|
||||
audio_driver_free_devices_list();
|
||||
#ifdef HAVE_THREADS
|
||||
slock_free(s_audio_driver_lock);
|
||||
s_audio_driver_lock = NULL;
|
||||
#endif
|
||||
|
||||
if (!audio_driver_deinit_internal())
|
||||
return false;
|
||||
return true;
|
||||
|
@ -22,46 +22,21 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <audio/audio_mixer.h>
|
||||
#include <audio/audio_resampler.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <audio/audio_mixer.h>
|
||||
|
||||
#include "audio_defines.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 512
|
||||
|
||||
/* So we don't get complete line-noise when fast-forwarding audio. */
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
|
||||
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_STREAMS 16
|
||||
|
||||
enum audio_action
|
||||
{
|
||||
AUDIO_ACTION_NONE = 0,
|
||||
AUDIO_ACTION_RATE_CONTROL_DELTA,
|
||||
AUDIO_ACTION_MIXER_MUTE_ENABLE,
|
||||
AUDIO_ACTION_MUTE_ENABLE,
|
||||
AUDIO_ACTION_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER
|
||||
};
|
||||
|
||||
enum audio_mixer_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_stream_type stream_type;
|
||||
enum audio_mixer_type type;
|
||||
enum audio_mixer_state state;
|
||||
float volume;
|
||||
void *buf;
|
||||
@ -69,14 +44,19 @@ typedef struct audio_mixer_stream
|
||||
size_t bufsize;
|
||||
} audio_mixer_stream_t;
|
||||
|
||||
typedef struct audio_statistics
|
||||
typedef struct audio_mixer_stream_params
|
||||
{
|
||||
float average_buffer_saturation;
|
||||
float std_deviation_percentage;
|
||||
float close_to_underrun;
|
||||
float close_to_blocking;
|
||||
unsigned samples;
|
||||
} audio_statistics_t;
|
||||
float volume;
|
||||
enum audio_mixer_slot_selection_type slot_selection_type;
|
||||
unsigned slot_selection_idx;
|
||||
enum audio_mixer_stream_type stream_type;
|
||||
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;
|
||||
|
||||
typedef struct audio_driver
|
||||
{
|
||||
@ -160,17 +140,6 @@ typedef struct audio_driver
|
||||
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);
|
||||
@ -295,6 +264,10 @@ 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_menu_sound(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_menu_sound_looped(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_sequential(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_looped(unsigned i);
|
||||
@ -307,14 +280,14 @@ 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);
|
||||
|
||||
void audio_driver_load_menu_sounds(void);
|
||||
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_audioio;
|
||||
extern audio_driver_t audio_oss;
|
||||
@ -331,6 +304,7 @@ extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_wasapi;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_coreaudio3;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
|
@ -43,4 +43,3 @@ bool audio_init_thread(const audio_driver_t **out_driver, void **out_data,
|
||||
const audio_driver_t *driver);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -125,7 +125,9 @@ static OSStatus audio_write_cb(void *userdata,
|
||||
static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
|
||||
{
|
||||
(void)data;
|
||||
#if TARGET_OS_IOS
|
||||
g_interrupted = (interrupt_state == kAudioSessionBeginInterruption);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||
@ -218,7 +220,7 @@ static void *coreaudio_init(const char *device,
|
||||
dev->lock = slock_new();
|
||||
dev->cond = scond_new();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_OS_IOS
|
||||
if (!session_initialized)
|
||||
{
|
||||
session_initialized = true;
|
||||
|
382
audio/drivers/coreaudio3.m
Normal file
382
audio/drivers/coreaudio3.m
Normal file
@ -0,0 +1,382 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2019 - Stuart Carnie
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
|
||||
#pragma mark - ringbuffer
|
||||
|
||||
typedef struct ringbuffer
|
||||
{
|
||||
float *buffer;
|
||||
size_t cap;
|
||||
atomic_int len;
|
||||
size_t writePtr;
|
||||
size_t readPtr;
|
||||
} ringbuffer_t;
|
||||
|
||||
typedef ringbuffer_t * ringbuffer_h;
|
||||
|
||||
static inline size_t rb_len(ringbuffer_h r)
|
||||
{
|
||||
return atomic_load_explicit(&r->len, memory_order_relaxed);
|
||||
}
|
||||
|
||||
static inline size_t rb_cap(ringbuffer_h r)
|
||||
{
|
||||
return (r->readPtr + r->cap - r->writePtr) % r->cap;
|
||||
}
|
||||
|
||||
static inline size_t rb_avail(ringbuffer_h r)
|
||||
{
|
||||
return r->cap - rb_len(r);
|
||||
}
|
||||
|
||||
static inline void rb_advance_write(ringbuffer_h r)
|
||||
{
|
||||
r->writePtr = (r->writePtr + 1) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_advance_write_n(ringbuffer_h r, size_t n)
|
||||
{
|
||||
r->writePtr = (r->writePtr + n) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_advance_read(ringbuffer_h r)
|
||||
{
|
||||
r->readPtr = (r->readPtr + 1) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_len_add(ringbuffer_h r, int n)
|
||||
{
|
||||
atomic_fetch_add(&r->len, n);
|
||||
}
|
||||
|
||||
static inline void rb_len_sub(ringbuffer_h r, int n)
|
||||
{
|
||||
atomic_fetch_sub(&r->len, n);
|
||||
}
|
||||
|
||||
static void rb_init(ringbuffer_h r, size_t cap)
|
||||
{
|
||||
r->buffer = malloc(cap * sizeof(float));
|
||||
r->cap = cap;
|
||||
atomic_init(&r->len, 0);
|
||||
r->writePtr = 0;
|
||||
r->readPtr = 0;
|
||||
}
|
||||
|
||||
static void rb_free(ringbuffer_h r)
|
||||
{
|
||||
free(r->buffer);
|
||||
bzero(r, sizeof(*r));
|
||||
}
|
||||
|
||||
#define UNLIKELY(x) __builtin_expect((x), 0)
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
|
||||
static void rb_write_data(ringbuffer_h r, const float *data, size_t len)
|
||||
{
|
||||
size_t avail = rb_avail(r);
|
||||
size_t n = MIN(len, avail);
|
||||
size_t first_write = n;
|
||||
size_t rest_write = 0;
|
||||
|
||||
if (r->writePtr + n > r->cap)
|
||||
{
|
||||
first_write = r->cap - r->writePtr;
|
||||
rest_write = n - first_write;
|
||||
}
|
||||
|
||||
memcpy(r->buffer + r->writePtr, data, first_write*sizeof(float));
|
||||
memcpy(r->buffer, data + first_write, rest_write*sizeof(float));
|
||||
|
||||
rb_advance_write_n(r, n);
|
||||
rb_len_add(r, (int)n);
|
||||
}
|
||||
|
||||
static void rb_read_data(ringbuffer_h r, float *d0, float *d1, size_t len)
|
||||
{
|
||||
size_t need = len*2;
|
||||
|
||||
do {
|
||||
size_t have = rb_len(r);
|
||||
size_t n = MIN(have, need);
|
||||
int i = 0;
|
||||
for (; i < n/2; i++)
|
||||
{
|
||||
d0[i] = r->buffer[r->readPtr];
|
||||
rb_advance_read(r);
|
||||
d1[i] = r->buffer[r->readPtr];
|
||||
rb_advance_read(r);
|
||||
}
|
||||
|
||||
need -= n;
|
||||
rb_len_sub(r, (int)n);
|
||||
|
||||
if (UNLIKELY(need > 0))
|
||||
{
|
||||
/* we got more data */
|
||||
if (rb_len(r) > 0)
|
||||
continue;
|
||||
|
||||
// underflow
|
||||
const float quiet = 0.0f;
|
||||
size_t fill = (need/2)*sizeof(float);
|
||||
memset_pattern4(&d0[i], &quiet, fill);
|
||||
memset_pattern4(&d1[i], &quiet, fill);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
#pragma mark - CoreAudio3
|
||||
|
||||
static bool g_interrupted;
|
||||
|
||||
@interface CoreAudio3 : NSObject {
|
||||
ringbuffer_t _rb;
|
||||
dispatch_semaphore_t _sema;
|
||||
AUAudioUnit *_au;
|
||||
size_t _bufferSize;
|
||||
BOOL _nonBlock;
|
||||
}
|
||||
|
||||
@property (nonatomic, readwrite) BOOL nonBlock;
|
||||
@property (nonatomic, readonly) BOOL paused;
|
||||
@property (nonatomic, readonly) size_t writeAvailableInBytes;
|
||||
@property (nonatomic, readonly) size_t bufferSizeInBytes;
|
||||
|
||||
- (instancetype)initWithRate:(NSUInteger)rate
|
||||
latency:(NSUInteger)latency;
|
||||
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples;
|
||||
- (void)start;
|
||||
- (void)stop;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CoreAudio3
|
||||
|
||||
- (instancetype)initWithRate:(NSUInteger)rate
|
||||
latency:(NSUInteger)latency {
|
||||
if (self = [super init])
|
||||
{
|
||||
_sema = dispatch_semaphore_create(0);
|
||||
|
||||
_bufferSize = (latency * rate) / 1000;
|
||||
_bufferSize *= 2; // stereo
|
||||
rb_init(&_rb, _bufferSize);
|
||||
|
||||
AudioComponentDescription desc = {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
.componentSubType = kAudioUnitSubType_DefaultOutput,
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
};
|
||||
|
||||
NSError *err;
|
||||
AUAudioUnit *au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
AVAudioFormat *format = au.outputBusses[0].format;
|
||||
if (format.channelCount != 2)
|
||||
return nil;
|
||||
|
||||
AVAudioFormat *renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2];
|
||||
[au.inputBusses[0] setFormat:renderFormat error:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
ringbuffer_h rb = &_rb;
|
||||
__block dispatch_semaphore_t sema = _sema;
|
||||
au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) {
|
||||
rb_read_data(rb, inputData->mBuffers[0].mData, inputData->mBuffers[1].mData, frameCount);
|
||||
dispatch_semaphore_signal(sema);
|
||||
return 0;
|
||||
};
|
||||
|
||||
[au allocateRenderResourcesAndReturnError:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
_au = au;
|
||||
|
||||
RARCH_LOG("[CoreAudio3]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)self.bufferSizeInBytes, latency);
|
||||
|
||||
[self start];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
rb_free(&_rb);
|
||||
}
|
||||
|
||||
- (BOOL)paused {
|
||||
return !_au.running;
|
||||
}
|
||||
|
||||
- (size_t)bufferSizeInBytes {
|
||||
return _bufferSize * sizeof(float);
|
||||
}
|
||||
|
||||
- (size_t)writeAvailableInBytes {
|
||||
return rb_avail(&_rb) * sizeof(float);
|
||||
}
|
||||
|
||||
- (void)start {
|
||||
NSError *err;
|
||||
[_au startHardwareAndReturnError:&err];
|
||||
}
|
||||
|
||||
- (void)stop {
|
||||
[_au stopHardware];
|
||||
}
|
||||
|
||||
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
|
||||
size_t written = 0;
|
||||
while (!g_interrupted && samples > 0)
|
||||
{
|
||||
size_t write_avail = rb_avail(&_rb);
|
||||
if (write_avail > samples)
|
||||
write_avail = samples;
|
||||
|
||||
rb_write_data(&_rb, data, write_avail);
|
||||
data += write_avail;
|
||||
written += write_avail;
|
||||
samples -= write_avail;
|
||||
|
||||
if (_nonBlock)
|
||||
break;
|
||||
|
||||
if (write_avail == 0)
|
||||
dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void coreaudio3_free(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge_transfer CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return;
|
||||
|
||||
[dev stop];
|
||||
dev = nil;
|
||||
}
|
||||
|
||||
static void *coreaudio3_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
CoreAudio3 *dev = [[CoreAudio3 alloc] initWithRate:rate
|
||||
latency:latency];
|
||||
|
||||
*new_rate = rate;
|
||||
|
||||
return (__bridge_retained void *)dev;
|
||||
}
|
||||
|
||||
static ssize_t coreaudio3_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
return [dev writeFloat:(const float *)buf_ samples:size/sizeof(float)] * sizeof(float);
|
||||
}
|
||||
|
||||
static void coreaudio3_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return;
|
||||
|
||||
dev.nonBlock = state;
|
||||
}
|
||||
|
||||
static bool coreaudio3_alive(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_stop(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
[dev stop];
|
||||
return dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_start(void *data, bool is_shutdown)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
[dev start];
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_use_float(void *data)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
static size_t coreaudio3_write_avail(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return 0;
|
||||
|
||||
return dev.writeAvailableInBytes;
|
||||
}
|
||||
|
||||
static size_t coreaudio3_buffer_size(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return 0;
|
||||
|
||||
return dev.bufferSizeInBytes;
|
||||
}
|
||||
|
||||
audio_driver_t audio_coreaudio3 = {
|
||||
coreaudio3_init,
|
||||
coreaudio3_write,
|
||||
coreaudio3_stop,
|
||||
coreaudio3_start,
|
||||
coreaudio3_alive,
|
||||
coreaudio3_set_nonblock_state,
|
||||
coreaudio3_free,
|
||||
coreaudio3_use_float,
|
||||
"coreaudio3",
|
||||
coreaudio3_write_avail,
|
||||
coreaudio3_buffer_size,
|
||||
};
|
@ -210,4 +210,3 @@ audio_driver_t audio_ctr_dsp = {
|
||||
ctr_dsp_audio_write_avail,
|
||||
ctr_dsp_audio_buffer_size
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,7 @@ static void audioMainLoop(void *data)
|
||||
size_t size;
|
||||
|
||||
WaitSema(ps2->lock);
|
||||
size = MIN(fifo_read_avail(ps2->buffer), sizeof(out_tmp));
|
||||
size = MIN(fifo_read_avail(ps2->buffer), sizeof(out_tmp));
|
||||
fifo_read(ps2->buffer, out_tmp, size);
|
||||
iSignalSema(ps2->lock);
|
||||
iSignalSema(ps2->cond_lock);
|
||||
@ -84,22 +84,21 @@ static void audioCreateThread(ps2_audio_t *ps2)
|
||||
ps2->running = true;
|
||||
ps2->worker_thread = CreateThread(&thread);
|
||||
|
||||
if (ps2->worker_thread >= 0) {
|
||||
if (ps2->worker_thread >= 0)
|
||||
{
|
||||
ret = StartThread(ps2->worker_thread, NULL);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
printf("sound_init: StartThread returned %d\n", ret);
|
||||
}
|
||||
} else {
|
||||
printf("CreateThread failed: %d\n", ps2->worker_thread);
|
||||
}
|
||||
else
|
||||
printf("CreateThread failed: %d\n", ps2->worker_thread);
|
||||
}
|
||||
|
||||
static void audioStopNDeleteThread(ps2_audio_t *ps2)
|
||||
{
|
||||
ps2->running = false;
|
||||
if (ps2->worker_thread) {
|
||||
if (ps2->worker_thread)
|
||||
ps2->worker_thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void audioConfigure(ps2_audio_t *ps2, unsigned rate)
|
||||
@ -187,14 +186,14 @@ static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
|
||||
if (!ps2->running)
|
||||
return -1;
|
||||
|
||||
if (ps2->nonblocking){
|
||||
if (ps2->nonblocking)
|
||||
{
|
||||
if (fifo_write_avail(ps2->buffer) < size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fifo_write_avail(ps2->buffer) < size) {
|
||||
while (fifo_write_avail(ps2->buffer) < size)
|
||||
WaitSema(ps2->cond_lock);
|
||||
}
|
||||
|
||||
WaitSema(ps2->lock);
|
||||
fifo_write(ps2->buffer, buf, size);
|
||||
@ -205,22 +204,22 @@ static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool ps2_audio_alive(void *data)
|
||||
{
|
||||
bool alive = false;
|
||||
|
||||
bool alive = false;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
if (ps2) {
|
||||
|
||||
if (ps2)
|
||||
alive = ps2->running;
|
||||
}
|
||||
|
||||
return alive;
|
||||
}
|
||||
|
||||
static bool ps2_audio_stop(void *data)
|
||||
{
|
||||
bool stop = true;
|
||||
bool stop = true;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2) {
|
||||
if (ps2)
|
||||
{
|
||||
audioStopNDeleteThread(ps2);
|
||||
audsrv_stop_audio();
|
||||
}
|
||||
@ -231,12 +230,12 @@ static bool ps2_audio_stop(void *data)
|
||||
static bool ps2_audio_start(void *data, bool is_shutdown)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
bool start = true;
|
||||
bool start = true;
|
||||
|
||||
if (ps2) {
|
||||
if (!ps2->running && !ps2->worker_thread) {
|
||||
if (ps2)
|
||||
{
|
||||
if (!ps2->running && !ps2->worker_thread)
|
||||
audioCreateThread(ps2);
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
@ -246,9 +245,8 @@ static void ps2_audio_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2) {
|
||||
if (ps2)
|
||||
ps2->nonblocking = toggle;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ps2_audio_use_float(void *data)
|
||||
@ -260,10 +258,11 @@ static size_t ps2_audio_write_avail(void *data)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2 && ps2->running) {
|
||||
if (ps2 && ps2->running)
|
||||
{
|
||||
size_t size;
|
||||
WaitSema(ps2->lock);
|
||||
size = AUDIO_BUFFER - fifo_read_avail(ps2->buffer);
|
||||
size = AUDIO_BUFFER - fifo_read_avail(ps2->buffer);
|
||||
iSignalSema(ps2->lock);
|
||||
return size;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ static void psp_audio_free(void *data)
|
||||
psp->running = false;
|
||||
sthread_join(psp->worker_thread);
|
||||
}
|
||||
|
||||
|
||||
if (psp->cond)
|
||||
scond_free(psp->cond);
|
||||
if (psp->fifo_lock)
|
||||
@ -205,7 +205,7 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
uint16_t write_pos = psp->write_pos;
|
||||
uint16_t sampleCount = size / sizeof(uint32_t);
|
||||
|
||||
|
||||
if (!psp->running)
|
||||
return -1;
|
||||
|
||||
@ -241,7 +241,6 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
|
||||
slock_unlock(psp->fifo_lock);
|
||||
return size;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static bool psp_audio_alive(void *data)
|
||||
|
@ -120,7 +120,7 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
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
|
||||
@ -137,7 +137,7 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
|
||||
}
|
||||
|
||||
swa->last_append = svcGetSystemTick();
|
||||
|
||||
|
||||
return to_write;
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ static void *switch_audio_init(const char *device,
|
||||
swa->is_paused = true;
|
||||
|
||||
RARCH_LOG("[Audio]: Audio initialized\n");
|
||||
|
||||
|
||||
return swa;
|
||||
|
||||
fail_audio_output:
|
||||
|
@ -237,7 +237,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
|
||||
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);
|
||||
|
||||
|
@ -360,4 +360,3 @@ static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -149,7 +149,7 @@ done:
|
||||
}
|
||||
|
||||
static void *resampler_CC_init(const struct resampler_config *config,
|
||||
double bandwidth_mod,
|
||||
double bandwidth_mod,
|
||||
enum resampler_quality quality,
|
||||
resampler_simd_mask_t mask)
|
||||
{
|
||||
@ -488,7 +488,7 @@ static void resampler_CC_process(void *re_, struct resampler_data *data)
|
||||
}
|
||||
|
||||
static void *resampler_CC_init(const struct resampler_config *config,
|
||||
double bandwidth_mod,
|
||||
double bandwidth_mod,
|
||||
enum resampler_quality quality,
|
||||
resampler_simd_mask_t mask)
|
||||
{
|
||||
|
@ -78,7 +78,6 @@
|
||||
# d23: (temp) # d31: buffer[6]
|
||||
# (temp) # buffer[7]
|
||||
|
||||
|
||||
resampler_CC_downsample_neon:
|
||||
_resampler_CC_downsample_neon:
|
||||
|
||||
@ -89,7 +88,6 @@ push {r4}
|
||||
|
||||
mov r4, r0
|
||||
|
||||
|
||||
veor q0, q0, q0
|
||||
vmov.f32 s1, #1.0
|
||||
vmov.f32 s2, #2.0
|
||||
@ -102,18 +100,15 @@ vmov.f32 q5, #1.0
|
||||
vmov.f32 q6, #3.0
|
||||
vmov.f32 q7, #0.25
|
||||
|
||||
|
||||
vldr s5, [r2, #32]
|
||||
vdiv.f32 s6, s20, s4
|
||||
vadd.f32 s7, s6, s8
|
||||
vdup.f32 q4, d2[0]
|
||||
vmin.f32 q4, q4, q5
|
||||
|
||||
|
||||
lsl r3, #3
|
||||
add r3, r3, r1
|
||||
|
||||
|
||||
cmp r3, r1
|
||||
beq 3f
|
||||
1:
|
||||
@ -199,7 +194,6 @@ vpop {q4,q5,q6,q7}
|
||||
|
||||
bx lr
|
||||
|
||||
|
||||
.align 4
|
||||
.globl resampler_CC_upsample_neon
|
||||
#ifndef __MACH__
|
||||
@ -256,7 +250,6 @@ bx lr
|
||||
# d23: (temp) # d31: buffer[6]
|
||||
# (temp) # buffer[7]
|
||||
|
||||
|
||||
resampler_CC_upsample_neon:
|
||||
_resampler_CC_upsample_neon:
|
||||
|
||||
@ -267,7 +260,6 @@ push {r4}
|
||||
|
||||
mov r4, r0
|
||||
|
||||
|
||||
veor q0, q0, q0
|
||||
vmov.f32 s0, #1.0
|
||||
vmov.f32 s2, #-1.0
|
||||
@ -280,18 +272,15 @@ vmov.f32 q5, #1.0
|
||||
vmov.f32 q6, #3.0
|
||||
vmov.f32 q7, #0.25
|
||||
|
||||
|
||||
vldr s5, [r2, #32]
|
||||
vdiv.f32 s6, s20, s4
|
||||
vadd.f32 s7, s6, s8
|
||||
vdup.f32 q4, d2[0]
|
||||
vmin.f32 q4, q4, q5
|
||||
|
||||
|
||||
lsl r3, #3
|
||||
add r3, r3, r1
|
||||
|
||||
|
||||
cmp r3, r1
|
||||
beq 4f
|
||||
1:
|
||||
@ -356,7 +345,6 @@ vst1.f32 d20, [r4, :64]!
|
||||
|
||||
vadd.f32 s5, s5, s6
|
||||
|
||||
|
||||
vcmpe.f32 s5, s20
|
||||
vmrs APSR_nzcv, fpscr
|
||||
blt 2b
|
||||
@ -368,7 +356,6 @@ vsub.f32 s5, s5, s20
|
||||
cmp r3, r1
|
||||
bne 1b
|
||||
|
||||
|
||||
4:
|
||||
vst1.f32 {q14-q15}, [r2, :256]
|
||||
vstr s5, [r2, #32]
|
||||
|
@ -52,7 +52,11 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <sys/poll.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
|
@ -86,7 +86,7 @@ SECTIONS
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
@ -167,7 +167,6 @@ SECTIONS
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
|
||||
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
@ -182,7 +181,7 @@ SECTIONS
|
||||
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
|
||||
.sbss :
|
||||
{
|
||||
__sbss_start = .;
|
||||
|
@ -97,7 +97,7 @@ SECTIONS
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
|
||||
} = 0
|
||||
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
@ -178,7 +178,6 @@ SECTIONS
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
|
||||
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
@ -193,7 +192,7 @@ SECTIONS
|
||||
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
|
||||
.sbss :
|
||||
{
|
||||
__sbss_start = .;
|
||||
|
@ -56,7 +56,7 @@ void exitspawn_kernel(const char *fileName, SceSize args, void *argp)
|
||||
game_param.unk5 = 0x10000;
|
||||
|
||||
int k1 = pspSdkSetK1(0);
|
||||
//sceKernelSuspendAllUserThreads();
|
||||
//sceKernelSuspendAllUserThreads();
|
||||
int ret = sceKernelLoadExecVSHMs2(fileName, &game_param);
|
||||
pspSdkSetK1(k1);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ typedef struct
|
||||
#endif
|
||||
|
||||
bool core_supports;
|
||||
|
||||
|
||||
cheevos_rapatchdata_t patchdata;
|
||||
cheevos_cheevo_t* core;
|
||||
cheevos_cheevo_t* unofficial;
|
||||
@ -289,7 +289,7 @@ static int cheevos_parse(const char* json)
|
||||
cheevos_racheevo_t* rac = NULL;
|
||||
|
||||
cheevos_fixup_init(&cheevos_locals.fixups);
|
||||
|
||||
|
||||
res = cheevos_get_patchdata(json, &cheevos_locals.patchdata);
|
||||
|
||||
if (res != 0)
|
||||
@ -312,13 +312,13 @@ static int cheevos_parse(const char* json)
|
||||
/* Allocate memory. */
|
||||
cheevos_locals.core = (cheevos_cheevo_t*)
|
||||
calloc(cheevos_locals.patchdata.core_count, sizeof(cheevos_cheevo_t));
|
||||
|
||||
|
||||
cheevos_locals.unofficial = (cheevos_cheevo_t*)
|
||||
calloc(cheevos_locals.patchdata.unofficial_count, sizeof(cheevos_cheevo_t));
|
||||
|
||||
cheevos_locals.lboards = (cheevos_lboard_t*)
|
||||
calloc(cheevos_locals.patchdata.lboard_count, sizeof(cheevos_lboard_t));
|
||||
|
||||
|
||||
if ( !cheevos_locals.core
|
||||
|| !cheevos_locals.unofficial
|
||||
|| !cheevos_locals.lboards)
|
||||
@ -726,7 +726,7 @@ void cheevos_populate_menu(void* data)
|
||||
cheevos_cheevo_t* cheevo = NULL;
|
||||
|
||||
if ( settings->bools.cheevos_enable
|
||||
&& settings->bools.cheevos_hardcore_mode_enable
|
||||
&& settings->bools.cheevos_hardcore_mode_enable
|
||||
&& cheevos_loaded)
|
||||
{
|
||||
if (!cheevos_hardcore_paused)
|
||||
@ -773,7 +773,7 @@ void cheevos_populate_menu(void* data)
|
||||
cheevo->info->description,
|
||||
MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
|
||||
|
||||
set_badge_info(&badges_ctx, i, cheevo->info->badge,
|
||||
(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
@ -811,7 +811,7 @@ void cheevos_populate_menu(void* data)
|
||||
cheevo->info->description,
|
||||
MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
|
||||
|
||||
set_badge_info(&badges_ctx, i, cheevo->info->badge,
|
||||
(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
@ -979,7 +979,7 @@ void cheevos_test(void)
|
||||
{
|
||||
if (settings->bools.cheevos_test_unofficial)
|
||||
cheevos_test_cheevo_set(false);
|
||||
|
||||
|
||||
if (settings->bools.cheevos_hardcore_mode_enable &&
|
||||
settings->bools.cheevos_leaderboards_enable &&
|
||||
!cheevos_hardcore_paused)
|
||||
@ -1118,6 +1118,8 @@ enum
|
||||
|
||||
static int cheevos_iterate(coro_t* coro)
|
||||
{
|
||||
const int snes_header_len = 0x200;
|
||||
const int lynx_header_len = 0x40;
|
||||
ssize_t num_read = 0;
|
||||
size_t to_read = 4096;
|
||||
uint8_t *buffer = NULL;
|
||||
@ -1159,10 +1161,10 @@ static int cheevos_iterate(coro_t* coro)
|
||||
|
||||
static cheevos_finder_t finders[] =
|
||||
{
|
||||
{SNES_MD5, "SNES (8Mb padding)", snes_exts},
|
||||
{SNES_MD5, "SNES (discards header)", snes_exts},
|
||||
{GENESIS_MD5, "Genesis (6Mb padding)", genesis_exts},
|
||||
{LYNX_MD5, "Atari Lynx (only first 512 bytes)", lynx_exts},
|
||||
{NES_MD5, "NES (discards VROM)", NULL},
|
||||
{LYNX_MD5, "Atari Lynx (discards header)", lynx_exts},
|
||||
{NES_MD5, "NES (discards header)", NULL},
|
||||
{GENERIC_MD5, "Generic (plain content)", NULL},
|
||||
{FILENAME_MD5, "Generic (filename)", NULL}
|
||||
};
|
||||
@ -1403,33 +1405,22 @@ found:
|
||||
* Output CHEEVOS_VAR_GAMEID the Retro Achievements game ID, or 0 if not found
|
||||
*************************************************************************/
|
||||
CORO_SUB(SNES_MD5)
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0;
|
||||
coro->count = 0;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count == 0)
|
||||
/* Checks for the existence of a headered SNES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != snes_header_len)
|
||||
{
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
if (coro->count < CHEEVOS_MB(8))
|
||||
{
|
||||
/*
|
||||
* Inputs: CHEEVOS_VAR_MD5, CHEEVOS_VAR_OFFSET, CHEEVOS_VAR_COUNT
|
||||
* Outputs: CHEEVOS_VAR_MD5
|
||||
*/
|
||||
coro->offset = 0;
|
||||
coro->count = CHEEVOS_MB(8) - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
coro->offset = snes_header_len;
|
||||
coro->count = 0;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
|
||||
/**************************************************************************
|
||||
@ -1469,16 +1460,18 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(LYNX_MD5)
|
||||
|
||||
if (coro->len < 0x0240)
|
||||
/* Checks for the existence of a headered Lynx file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len <= lynx_header_len ||
|
||||
memcmp("LYNX", (void *)coro->data, 5) != 0)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0x0040;
|
||||
coro->count = 0x0200;
|
||||
coro->offset = lynx_header_len;
|
||||
coro->count = coro->len - lynx_header_len;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
@ -1491,13 +1484,8 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(NES_MD5)
|
||||
|
||||
/* Note about the references to the FCEU emulator below. There is no
|
||||
* core-specific code in this function, it's rather Retro Achievements
|
||||
* specific code that must be followed to the letter so we compute
|
||||
* the correct ROM hash. Retro Achievements does indeed use some
|
||||
* FCEU related method to compute the hash, since its NES emulator
|
||||
* is based on it. */
|
||||
|
||||
/* Checks for the existence of a headered NES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len < sizeof(coro->header))
|
||||
{
|
||||
coro->gameid = 0;
|
||||
@ -1506,84 +1494,23 @@ found:
|
||||
|
||||
memcpy((void*)&coro->header, coro->data,
|
||||
sizeof(coro->header));
|
||||
|
||||
if (coro->header.id[0] == 'N'
|
||||
&& coro->header.id[1] == 'E'
|
||||
&& coro->header.id[2] == 'S'
|
||||
&& coro->header.id[3] == 0x1a)
|
||||
|
||||
if ( coro->header.id[0] != 'N'
|
||||
|| coro->header.id[1] != 'E'
|
||||
|| coro->header.id[2] != 'S'
|
||||
|| coro->header.id[3] != 0x1a)
|
||||
{
|
||||
size_t romsize = 256;
|
||||
/* from FCEU core - compute size using the cart mapper */
|
||||
int mapper = (coro->header.rom_type >> 4) | (coro->header.rom_type2 & 0xF0);
|
||||
|
||||
if (coro->header.rom_size)
|
||||
romsize = next_pow2(coro->header.rom_size);
|
||||
|
||||
/* for games not to the power of 2, so we just read enough
|
||||
* PRG rom from it, but we have to keep ROM_size to the power of 2
|
||||
* since PRGCartMapping wants ROM_size to be to the power of 2
|
||||
* so instead if not to power of 2, we just use head.ROM_size when
|
||||
* we use FCEU_read. */
|
||||
coro->round = mapper != 53 && mapper != 198 && mapper != 228;
|
||||
coro->bytes = coro->round ? romsize : coro->header.rom_size;
|
||||
|
||||
coro->offset = sizeof(coro->header) + (coro->header.rom_type & 4
|
||||
? sizeof(coro->header) : 0);
|
||||
|
||||
/* from FCEU core - check if Trainer included in ROM data */
|
||||
MD5_Init(&coro->md5);
|
||||
coro->count = 0x4000 * coro->bytes;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count < 0x4000 * coro->bytes)
|
||||
{
|
||||
coro->offset = 0xff;
|
||||
coro->count = 0x4000 * coro->bytes - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
size_t chunks = coro->len >> 14;
|
||||
size_t chunk_size = 0x4000;
|
||||
|
||||
/* Fall back to headerless hashing
|
||||
* PRG ROM size is unknown, so test by 16KB chunks */
|
||||
MD5_Init(&coro->md5);
|
||||
coro->offset = sizeof(coro->header);
|
||||
coro->count = coro->len - coro->offset;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
coro->round = 0;
|
||||
coro->offset = 0;
|
||||
|
||||
for (i = 0; i < chunks; i++)
|
||||
{
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->bytes = i + 1;
|
||||
coro->count = coro->bytes * chunk_size;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count < 0x4000 * coro->bytes)
|
||||
{
|
||||
coro->offset = 0xff;
|
||||
coro->count = 0x4000 * coro->bytes - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOSUB(GET_GAMEID);
|
||||
|
||||
if (coro->gameid > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CORO_RET();
|
||||
}
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
|
||||
/**************************************************************************
|
||||
* Info Tries to identify a "generic" game
|
||||
@ -1744,7 +1671,7 @@ found:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
if (!(
|
||||
string_is_equal(settings->arrays.menu_driver, "xmb") ||
|
||||
string_is_equal(settings->arrays.menu_driver, "xmb") ||
|
||||
string_is_equal(settings->arrays.menu_driver, "ozone")
|
||||
) ||
|
||||
!settings->bools.cheevos_badges_enable)
|
||||
|
@ -197,7 +197,7 @@ const uint8_t* cheevos_patch_address(unsigned address, int console)
|
||||
{
|
||||
unsigned addr = address;
|
||||
pointer = desc->core.ptr;
|
||||
|
||||
|
||||
address = (unsigned)cheevos_var_reduce(
|
||||
(addr - desc->core.start) & desc->disconnect_mask,
|
||||
desc->core.disconnect);
|
||||
|
@ -148,7 +148,7 @@ int cheevos_get_token(const char* json, char* token, size_t length)
|
||||
|
||||
if (!string_is_empty(token))
|
||||
return -1;
|
||||
|
||||
|
||||
return cheevos_get_value(json, CHEEVOS_JSON_KEY_TOKEN, token, length);
|
||||
}
|
||||
|
||||
|
@ -2571,10 +2571,12 @@ enum
|
||||
|
||||
static int cheevos_iterate(coro_t *coro)
|
||||
{
|
||||
ssize_t num_read = 0;
|
||||
size_t to_read = 4096;
|
||||
uint8_t *buffer = NULL;
|
||||
const char *end = NULL;
|
||||
const int snes_header_len = 0x200;
|
||||
const int lynx_header_len = 0x40;
|
||||
ssize_t num_read = 0;
|
||||
size_t to_read = 4096;
|
||||
uint8_t *buffer = NULL;
|
||||
const char *end = NULL;
|
||||
|
||||
static const uint32_t genesis_exts[] =
|
||||
{
|
||||
@ -2614,7 +2616,7 @@ static int cheevos_iterate(coro_t *coro)
|
||||
{
|
||||
{SNES_MD5, "SNES (discards header)", snes_exts},
|
||||
{GENESIS_MD5, "Genesis (6Mb padding)", genesis_exts},
|
||||
{LYNX_MD5, "Atari Lynx (only first 512 bytes)", lynx_exts},
|
||||
{LYNX_MD5, "Atari Lynx (discards header)", lynx_exts},
|
||||
{NES_MD5, "NES (discards header)", NULL},
|
||||
{GENERIC_MD5, "Generic (plain content)", NULL},
|
||||
{FILENAME_MD5, "Generic (filename)", NULL}
|
||||
@ -2903,9 +2905,7 @@ found:
|
||||
/* Checks for the existence of a headered SNES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
|
||||
const int SNES_HEADER_LEN = 0x200;
|
||||
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != SNES_HEADER_LEN)
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != snes_header_len)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
@ -2956,16 +2956,19 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(LYNX_MD5)
|
||||
|
||||
if (coro->len < 0x0240)
|
||||
/* Checks for the existence of a headered Lynx file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
|
||||
if (coro->len <= (unsigned)lynx_header_len ||
|
||||
memcmp("LYNX", (void *)coro->data, 5) != 0)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0x0040;
|
||||
coro->count = 0x0200;
|
||||
coro->offset = lynx_header_len;
|
||||
coro->count = coro->len - lynx_header_len;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
|
@ -1,171 +1,171 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2018 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_OLD_H
|
||||
#define __RARCH_CHEEVOS_OLD_H
|
||||
|
||||
#ifdef HAVE_NEW_CHEEVOS
|
||||
#include "../cheevos-new/cheevos.h"
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/*****************************************************************************
|
||||
Setup - mainly for debugging
|
||||
*****************************************************************************/
|
||||
|
||||
/* Define this macro to get extra-verbose log for cheevos. */
|
||||
#undef CHEEVOS_VERBOSE
|
||||
|
||||
/*****************************************************************************
|
||||
End of setup
|
||||
*****************************************************************************/
|
||||
|
||||
#define CHEEVOS_TAG "[CHEEVOS]: "
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
|
||||
#define CHEEVOS_LOG RARCH_LOG
|
||||
#define CHEEVOS_ERR RARCH_ERR
|
||||
|
||||
#else
|
||||
|
||||
void cheevos_log(const char *fmt, ...);
|
||||
|
||||
#define CHEEVOS_LOG cheevos_log
|
||||
#define CHEEVOS_ERR cheevos_log
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct cheevos_ctx_desc
|
||||
{
|
||||
unsigned idx;
|
||||
char *s;
|
||||
size_t len;
|
||||
} cheevos_ctx_desc_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_CONSOLE_NONE = 0,
|
||||
/* Don't change those, the values match the console IDs
|
||||
* at retroachievements.org. */
|
||||
CHEEVOS_CONSOLE_MEGA_DRIVE = 1,
|
||||
CHEEVOS_CONSOLE_NINTENDO_64 = 2,
|
||||
CHEEVOS_CONSOLE_SUPER_NINTENDO = 3,
|
||||
CHEEVOS_CONSOLE_GAMEBOY = 4,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_ADVANCE = 5,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_COLOR = 6,
|
||||
CHEEVOS_CONSOLE_NINTENDO = 7,
|
||||
CHEEVOS_CONSOLE_PC_ENGINE = 8,
|
||||
CHEEVOS_CONSOLE_SEGA_CD = 9,
|
||||
CHEEVOS_CONSOLE_SEGA_32X = 10,
|
||||
CHEEVOS_CONSOLE_MASTER_SYSTEM = 11,
|
||||
CHEEVOS_CONSOLE_PLAYSTATION = 12,
|
||||
CHEEVOS_CONSOLE_ATARI_LYNX = 13,
|
||||
CHEEVOS_CONSOLE_NEOGEO_POCKET = 14,
|
||||
CHEEVOS_CONSOLE_GAME_GEAR = 15,
|
||||
CHEEVOS_CONSOLE_GAMECUBE = 16,
|
||||
CHEEVOS_CONSOLE_ATARI_JAGUAR = 17,
|
||||
CHEEVOS_CONSOLE_NINTENDO_DS = 18,
|
||||
CHEEVOS_CONSOLE_WII = 19,
|
||||
CHEEVOS_CONSOLE_WII_U = 20,
|
||||
CHEEVOS_CONSOLE_PLAYSTATION_2 = 21,
|
||||
CHEEVOS_CONSOLE_XBOX = 22,
|
||||
CHEEVOS_CONSOLE_SKYNET = 23,
|
||||
CHEEVOS_CONSOLE_XBOX_ONE = 24,
|
||||
CHEEVOS_CONSOLE_ATARI_2600 = 25,
|
||||
CHEEVOS_CONSOLE_MS_DOS = 26,
|
||||
CHEEVOS_CONSOLE_ARCADE = 27,
|
||||
CHEEVOS_CONSOLE_VIRTUAL_BOY = 28,
|
||||
CHEEVOS_CONSOLE_MSX = 29,
|
||||
CHEEVOS_CONSOLE_COMMODORE_64 = 30,
|
||||
CHEEVOS_CONSOLE_ZX81 = 31,
|
||||
CHEEVOS_CONSOLE_ATARI_7800 = 51
|
||||
} cheevos_console_t;
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_DIRTY_TITLE = 1 << 0,
|
||||
CHEEVOS_DIRTY_DESC = 1 << 1,
|
||||
CHEEVOS_DIRTY_POINTS = 1 << 2,
|
||||
CHEEVOS_DIRTY_AUTHOR = 1 << 3,
|
||||
CHEEVOS_DIRTY_ID = 1 << 4,
|
||||
CHEEVOS_DIRTY_BADGE = 1 << 5,
|
||||
CHEEVOS_DIRTY_CONDITIONS = 1 << 6,
|
||||
CHEEVOS_DIRTY_VOTES = 1 << 7,
|
||||
CHEEVOS_DIRTY_DESCRIPTION = 1 << 8,
|
||||
|
||||
CHEEVOS_DIRTY_ALL = (1 << 9) - 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_ACTIVE_SOFTCORE = 1 << 0,
|
||||
CHEEVOS_ACTIVE_HARDCORE = 1 << 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_FORMAT_FRAMES = 0,
|
||||
CHEEVOS_FORMAT_SECS,
|
||||
CHEEVOS_FORMAT_MILLIS,
|
||||
CHEEVOS_FORMAT_SCORE,
|
||||
CHEEVOS_FORMAT_VALUE,
|
||||
CHEEVOS_FORMAT_OTHER
|
||||
};
|
||||
|
||||
bool cheevos_load(const void *data);
|
||||
|
||||
void cheevos_reset_game(void);
|
||||
|
||||
void cheevos_populate_menu(void *data);
|
||||
|
||||
bool cheevos_get_description(cheevos_ctx_desc_t *desc);
|
||||
|
||||
bool cheevos_apply_cheats(bool *data_bool);
|
||||
|
||||
bool cheevos_unload(void);
|
||||
|
||||
bool cheevos_toggle_hardcore_mode(void);
|
||||
|
||||
void cheevos_test(void);
|
||||
|
||||
bool cheevos_set_cheats(void);
|
||||
|
||||
void cheevos_set_support_cheevos(bool state);
|
||||
|
||||
bool cheevos_get_support_cheevos(void);
|
||||
|
||||
cheevos_console_t cheevos_get_console(void);
|
||||
|
||||
extern bool cheevos_loaded;
|
||||
extern bool cheevos_hardcore_active;
|
||||
extern bool cheevos_hardcore_paused;
|
||||
extern bool cheevos_state_loaded_flag;
|
||||
extern int cheats_are_enabled;
|
||||
extern int cheats_were_enabled;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_H */
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2018 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_OLD_H
|
||||
#define __RARCH_CHEEVOS_OLD_H
|
||||
|
||||
#ifdef HAVE_NEW_CHEEVOS
|
||||
#include "../cheevos-new/cheevos.h"
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/*****************************************************************************
|
||||
Setup - mainly for debugging
|
||||
*****************************************************************************/
|
||||
|
||||
/* Define this macro to get extra-verbose log for cheevos. */
|
||||
#undef CHEEVOS_VERBOSE
|
||||
|
||||
/*****************************************************************************
|
||||
End of setup
|
||||
*****************************************************************************/
|
||||
|
||||
#define CHEEVOS_TAG "[CHEEVOS]: "
|
||||
|
||||
#ifdef CHEEVOS_VERBOSE
|
||||
|
||||
#define CHEEVOS_LOG RARCH_LOG
|
||||
#define CHEEVOS_ERR RARCH_ERR
|
||||
|
||||
#else
|
||||
|
||||
void cheevos_log(const char *fmt, ...);
|
||||
|
||||
#define CHEEVOS_LOG cheevos_log
|
||||
#define CHEEVOS_ERR cheevos_log
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct cheevos_ctx_desc
|
||||
{
|
||||
unsigned idx;
|
||||
char *s;
|
||||
size_t len;
|
||||
} cheevos_ctx_desc_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_CONSOLE_NONE = 0,
|
||||
/* Don't change those, the values match the console IDs
|
||||
* at retroachievements.org. */
|
||||
CHEEVOS_CONSOLE_MEGA_DRIVE = 1,
|
||||
CHEEVOS_CONSOLE_NINTENDO_64 = 2,
|
||||
CHEEVOS_CONSOLE_SUPER_NINTENDO = 3,
|
||||
CHEEVOS_CONSOLE_GAMEBOY = 4,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_ADVANCE = 5,
|
||||
CHEEVOS_CONSOLE_GAMEBOY_COLOR = 6,
|
||||
CHEEVOS_CONSOLE_NINTENDO = 7,
|
||||
CHEEVOS_CONSOLE_PC_ENGINE = 8,
|
||||
CHEEVOS_CONSOLE_SEGA_CD = 9,
|
||||
CHEEVOS_CONSOLE_SEGA_32X = 10,
|
||||
CHEEVOS_CONSOLE_MASTER_SYSTEM = 11,
|
||||
CHEEVOS_CONSOLE_PLAYSTATION = 12,
|
||||
CHEEVOS_CONSOLE_ATARI_LYNX = 13,
|
||||
CHEEVOS_CONSOLE_NEOGEO_POCKET = 14,
|
||||
CHEEVOS_CONSOLE_GAME_GEAR = 15,
|
||||
CHEEVOS_CONSOLE_GAMECUBE = 16,
|
||||
CHEEVOS_CONSOLE_ATARI_JAGUAR = 17,
|
||||
CHEEVOS_CONSOLE_NINTENDO_DS = 18,
|
||||
CHEEVOS_CONSOLE_WII = 19,
|
||||
CHEEVOS_CONSOLE_WII_U = 20,
|
||||
CHEEVOS_CONSOLE_PLAYSTATION_2 = 21,
|
||||
CHEEVOS_CONSOLE_XBOX = 22,
|
||||
CHEEVOS_CONSOLE_SKYNET = 23,
|
||||
CHEEVOS_CONSOLE_XBOX_ONE = 24,
|
||||
CHEEVOS_CONSOLE_ATARI_2600 = 25,
|
||||
CHEEVOS_CONSOLE_MS_DOS = 26,
|
||||
CHEEVOS_CONSOLE_ARCADE = 27,
|
||||
CHEEVOS_CONSOLE_VIRTUAL_BOY = 28,
|
||||
CHEEVOS_CONSOLE_MSX = 29,
|
||||
CHEEVOS_CONSOLE_COMMODORE_64 = 30,
|
||||
CHEEVOS_CONSOLE_ZX81 = 31,
|
||||
CHEEVOS_CONSOLE_ATARI_7800 = 51
|
||||
} cheevos_console_t;
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_DIRTY_TITLE = 1 << 0,
|
||||
CHEEVOS_DIRTY_DESC = 1 << 1,
|
||||
CHEEVOS_DIRTY_POINTS = 1 << 2,
|
||||
CHEEVOS_DIRTY_AUTHOR = 1 << 3,
|
||||
CHEEVOS_DIRTY_ID = 1 << 4,
|
||||
CHEEVOS_DIRTY_BADGE = 1 << 5,
|
||||
CHEEVOS_DIRTY_CONDITIONS = 1 << 6,
|
||||
CHEEVOS_DIRTY_VOTES = 1 << 7,
|
||||
CHEEVOS_DIRTY_DESCRIPTION = 1 << 8,
|
||||
|
||||
CHEEVOS_DIRTY_ALL = (1 << 9) - 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_ACTIVE_SOFTCORE = 1 << 0,
|
||||
CHEEVOS_ACTIVE_HARDCORE = 1 << 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHEEVOS_FORMAT_FRAMES = 0,
|
||||
CHEEVOS_FORMAT_SECS,
|
||||
CHEEVOS_FORMAT_MILLIS,
|
||||
CHEEVOS_FORMAT_SCORE,
|
||||
CHEEVOS_FORMAT_VALUE,
|
||||
CHEEVOS_FORMAT_OTHER
|
||||
};
|
||||
|
||||
bool cheevos_load(const void *data);
|
||||
|
||||
void cheevos_reset_game(void);
|
||||
|
||||
void cheevos_populate_menu(void *data);
|
||||
|
||||
bool cheevos_get_description(cheevos_ctx_desc_t *desc);
|
||||
|
||||
bool cheevos_apply_cheats(bool *data_bool);
|
||||
|
||||
bool cheevos_unload(void);
|
||||
|
||||
bool cheevos_toggle_hardcore_mode(void);
|
||||
|
||||
void cheevos_test(void);
|
||||
|
||||
bool cheevos_set_cheats(void);
|
||||
|
||||
void cheevos_set_support_cheevos(bool state);
|
||||
|
||||
bool cheevos_get_support_cheevos(void);
|
||||
|
||||
cheevos_console_t cheevos_get_console(void);
|
||||
|
||||
extern bool cheevos_loaded;
|
||||
extern bool cheevos_hardcore_active;
|
||||
extern bool cheevos_hardcore_paused;
|
||||
extern bool cheevos_state_loaded_flag;
|
||||
extern int cheats_are_enabled;
|
||||
extern int cheats_were_enabled;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_H */
|
||||
|
378
cheevos/cond.c
378
cheevos/cond.c
@ -1,189 +1,189 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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 "cond.h"
|
||||
#include "var.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Parsing
|
||||
*****************************************************************************/
|
||||
|
||||
static cheevos_cond_op_t cheevos_cond_parse_operator(const char** memaddr)
|
||||
{
|
||||
const char *str = *memaddr;
|
||||
cheevos_cond_op_t op;
|
||||
|
||||
if (*str == '=' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
str++;
|
||||
}
|
||||
else if (*str == '!' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_NOT_EQUAL_TO;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '<' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '<')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_LESS_THAN;
|
||||
str++;
|
||||
}
|
||||
else if (*str == '>' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '>')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_GREATER_THAN;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHEEVOS_ERR(CHEEVOS_TAG "unknown operator %c\n.", *str);
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
}
|
||||
|
||||
*memaddr = str;
|
||||
return op;
|
||||
}
|
||||
|
||||
void cheevos_cond_parse(cheevos_cond_t* cond, const char** memaddr)
|
||||
{
|
||||
const char* str = *memaddr;
|
||||
cond->type = CHEEVOS_COND_TYPE_STANDARD;
|
||||
|
||||
if (*str != 0 && str[1] == ':')
|
||||
{
|
||||
int skip = 2;
|
||||
|
||||
switch (*str)
|
||||
{
|
||||
case 'R':
|
||||
cond->type = CHEEVOS_COND_TYPE_RESET_IF;
|
||||
break;
|
||||
case 'P':
|
||||
cond->type = CHEEVOS_COND_TYPE_PAUSE_IF;
|
||||
break;
|
||||
case 'A':
|
||||
cond->type = CHEEVOS_COND_TYPE_ADD_SOURCE;
|
||||
break;
|
||||
case 'B':
|
||||
cond->type = CHEEVOS_COND_TYPE_SUB_SOURCE;
|
||||
break;
|
||||
case 'C':
|
||||
cond->type = CHEEVOS_COND_TYPE_ADD_HITS;
|
||||
break;
|
||||
default:
|
||||
skip = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
str += skip;
|
||||
}
|
||||
|
||||
cheevos_var_parse(&cond->source, &str);
|
||||
cond->op = cheevos_cond_parse_operator(&str);
|
||||
cheevos_var_parse(&cond->target, &str);
|
||||
cond->curr_hits = 0;
|
||||
|
||||
if (*str == '(' || *str == '.')
|
||||
{
|
||||
char* end;
|
||||
cond->req_hits = (unsigned)strtol(str + 1, &end, 10);
|
||||
str = end + (*end == ')' || *end == '.');
|
||||
}
|
||||
else
|
||||
cond->req_hits = 0;
|
||||
|
||||
*memaddr = str;
|
||||
}
|
||||
|
||||
unsigned cheevos_cond_count_in_set(const char* memaddr, unsigned which)
|
||||
{
|
||||
cheevos_cond_t dummy;
|
||||
unsigned index = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cheevos_cond_parse(&dummy, &memaddr);
|
||||
|
||||
if (index == which)
|
||||
count++;
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void cheevos_cond_parse_in_set(cheevos_cond_t* cond, const char* memaddr, unsigned which)
|
||||
{
|
||||
cheevos_cond_t dummy;
|
||||
unsigned index = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (index == which)
|
||||
{
|
||||
cheevos_cond_parse(cond, &memaddr);
|
||||
cond++;
|
||||
}
|
||||
else
|
||||
cheevos_cond_parse(&dummy, &memaddr);
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
}
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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 "cond.h"
|
||||
#include "var.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Parsing
|
||||
*****************************************************************************/
|
||||
|
||||
static cheevos_cond_op_t cheevos_cond_parse_operator(const char** memaddr)
|
||||
{
|
||||
const char *str = *memaddr;
|
||||
cheevos_cond_op_t op;
|
||||
|
||||
if (*str == '=' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
str++;
|
||||
}
|
||||
else if (*str == '!' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_NOT_EQUAL_TO;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '<' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '<')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_LESS_THAN;
|
||||
str++;
|
||||
}
|
||||
else if (*str == '>' && str[1] == '=')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL;
|
||||
str += 2;
|
||||
}
|
||||
else if (*str == '>')
|
||||
{
|
||||
op = CHEEVOS_COND_OP_GREATER_THAN;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHEEVOS_ERR(CHEEVOS_TAG "unknown operator %c\n.", *str);
|
||||
op = CHEEVOS_COND_OP_EQUALS;
|
||||
}
|
||||
|
||||
*memaddr = str;
|
||||
return op;
|
||||
}
|
||||
|
||||
void cheevos_cond_parse(cheevos_cond_t* cond, const char** memaddr)
|
||||
{
|
||||
const char* str = *memaddr;
|
||||
cond->type = CHEEVOS_COND_TYPE_STANDARD;
|
||||
|
||||
if (*str != 0 && str[1] == ':')
|
||||
{
|
||||
int skip = 2;
|
||||
|
||||
switch (*str)
|
||||
{
|
||||
case 'R':
|
||||
cond->type = CHEEVOS_COND_TYPE_RESET_IF;
|
||||
break;
|
||||
case 'P':
|
||||
cond->type = CHEEVOS_COND_TYPE_PAUSE_IF;
|
||||
break;
|
||||
case 'A':
|
||||
cond->type = CHEEVOS_COND_TYPE_ADD_SOURCE;
|
||||
break;
|
||||
case 'B':
|
||||
cond->type = CHEEVOS_COND_TYPE_SUB_SOURCE;
|
||||
break;
|
||||
case 'C':
|
||||
cond->type = CHEEVOS_COND_TYPE_ADD_HITS;
|
||||
break;
|
||||
default:
|
||||
skip = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
str += skip;
|
||||
}
|
||||
|
||||
cheevos_var_parse(&cond->source, &str);
|
||||
cond->op = cheevos_cond_parse_operator(&str);
|
||||
cheevos_var_parse(&cond->target, &str);
|
||||
cond->curr_hits = 0;
|
||||
|
||||
if (*str == '(' || *str == '.')
|
||||
{
|
||||
char* end;
|
||||
cond->req_hits = (unsigned)strtol(str + 1, &end, 10);
|
||||
str = end + (*end == ')' || *end == '.');
|
||||
}
|
||||
else
|
||||
cond->req_hits = 0;
|
||||
|
||||
*memaddr = str;
|
||||
}
|
||||
|
||||
unsigned cheevos_cond_count_in_set(const char* memaddr, unsigned which)
|
||||
{
|
||||
cheevos_cond_t dummy;
|
||||
unsigned index = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cheevos_cond_parse(&dummy, &memaddr);
|
||||
|
||||
if (index == which)
|
||||
count++;
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void cheevos_cond_parse_in_set(cheevos_cond_t* cond, const char* memaddr, unsigned which)
|
||||
{
|
||||
cheevos_cond_t dummy;
|
||||
unsigned index = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (index == which)
|
||||
{
|
||||
cheevos_cond_parse(cond, &memaddr);
|
||||
cond++;
|
||||
}
|
||||
else
|
||||
cheevos_cond_parse(&dummy, &memaddr);
|
||||
|
||||
if (*memaddr != '_')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (*memaddr != 'S')
|
||||
break;
|
||||
|
||||
memaddr++;
|
||||
}
|
||||
}
|
||||
|
126
cheevos/cond.h
126
cheevos/cond.h
@ -1,63 +1,63 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_COND_H
|
||||
#define __RARCH_CHEEVOS_COND_H
|
||||
|
||||
#include "var.h"
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_COND_TYPE_STANDARD,
|
||||
CHEEVOS_COND_TYPE_PAUSE_IF,
|
||||
CHEEVOS_COND_TYPE_RESET_IF,
|
||||
CHEEVOS_COND_TYPE_ADD_SOURCE,
|
||||
CHEEVOS_COND_TYPE_SUB_SOURCE,
|
||||
CHEEVOS_COND_TYPE_ADD_HITS
|
||||
} cheevos_cond_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_COND_OP_EQUALS,
|
||||
CHEEVOS_COND_OP_LESS_THAN,
|
||||
CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL,
|
||||
CHEEVOS_COND_OP_GREATER_THAN,
|
||||
CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL,
|
||||
CHEEVOS_COND_OP_NOT_EQUAL_TO
|
||||
} cheevos_cond_op_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cheevos_cond_type_t type;
|
||||
unsigned req_hits;
|
||||
unsigned curr_hits;
|
||||
char pause;
|
||||
|
||||
cheevos_var_t source;
|
||||
cheevos_cond_op_t op;
|
||||
cheevos_var_t target;
|
||||
} cheevos_cond_t;
|
||||
|
||||
void cheevos_cond_parse(cheevos_cond_t* cond, const char** memaddr);
|
||||
unsigned cheevos_cond_count_in_set(const char* memaddr, unsigned which);
|
||||
void cheevos_cond_parse_in_set(cheevos_cond_t* cond, const char* memaddr, unsigned which);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_COND_H */
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_COND_H
|
||||
#define __RARCH_CHEEVOS_COND_H
|
||||
|
||||
#include "var.h"
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_COND_TYPE_STANDARD,
|
||||
CHEEVOS_COND_TYPE_PAUSE_IF,
|
||||
CHEEVOS_COND_TYPE_RESET_IF,
|
||||
CHEEVOS_COND_TYPE_ADD_SOURCE,
|
||||
CHEEVOS_COND_TYPE_SUB_SOURCE,
|
||||
CHEEVOS_COND_TYPE_ADD_HITS
|
||||
} cheevos_cond_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_COND_OP_EQUALS,
|
||||
CHEEVOS_COND_OP_LESS_THAN,
|
||||
CHEEVOS_COND_OP_LESS_THAN_OR_EQUAL,
|
||||
CHEEVOS_COND_OP_GREATER_THAN,
|
||||
CHEEVOS_COND_OP_GREATER_THAN_OR_EQUAL,
|
||||
CHEEVOS_COND_OP_NOT_EQUAL_TO
|
||||
} cheevos_cond_op_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cheevos_cond_type_t type;
|
||||
unsigned req_hits;
|
||||
unsigned curr_hits;
|
||||
char pause;
|
||||
|
||||
cheevos_var_t source;
|
||||
cheevos_cond_op_t op;
|
||||
cheevos_var_t target;
|
||||
} cheevos_cond_t;
|
||||
|
||||
void cheevos_cond_parse(cheevos_cond_t* cond, const char** memaddr);
|
||||
unsigned cheevos_cond_count_in_set(const char* memaddr, unsigned which);
|
||||
void cheevos_cond_parse_in_set(cheevos_cond_t* cond, const char* memaddr, unsigned which);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_COND_H */
|
||||
|
150
cheevos/coro.h
150
cheevos/coro.h
@ -1,75 +1,75 @@
|
||||
#ifndef CORO_H
|
||||
#define CORO_H
|
||||
|
||||
/*
|
||||
Released under the CC0: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/* Use at the beginning of the coroutine, you must have declared a variable coro_t* coro */
|
||||
#define CORO_ENTER() \
|
||||
{ \
|
||||
CORO_again: ; \
|
||||
switch ( coro->step ) { \
|
||||
case CORO_BEGIN: ;
|
||||
|
||||
/* Use to define labels which are targets to GOTO and GOSUB */
|
||||
#define CORO_SUB( x ) \
|
||||
case x: ;
|
||||
|
||||
/* Use at the end of the coroutine */
|
||||
#define CORO_LEAVE() \
|
||||
} } \
|
||||
do { return 0; } while ( 0 )
|
||||
|
||||
/* Go to the x label */
|
||||
#define CORO_GOTO( x ) \
|
||||
do { \
|
||||
coro->step = ( x ); \
|
||||
goto CORO_again; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Go to a subroutine, execution continues until the subroutine returns via RET */
|
||||
#define CORO_GOSUB( x ) \
|
||||
do { \
|
||||
coro->stack[ coro->sp++ ] = __LINE__; \
|
||||
coro->step = ( x ); \
|
||||
goto CORO_again; \
|
||||
case __LINE__: ; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Returns from a subroutine */
|
||||
#define CORO_RET() \
|
||||
do { \
|
||||
coro->step = coro->stack[ --coro->sp ]; \
|
||||
goto CORO_again; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Yields to the caller, execution continues from this point when the coroutine is resumed */
|
||||
#define CORO_YIELD() \
|
||||
do { \
|
||||
coro->step = __LINE__; \
|
||||
return 1; \
|
||||
case __LINE__: ; \
|
||||
} while ( 0 )
|
||||
|
||||
/* The coroutine entry point, never use 0 as a label */
|
||||
#define CORO_BEGIN 0
|
||||
|
||||
/* Sets up the coroutine */
|
||||
#define CORO_SETUP() \
|
||||
do { \
|
||||
coro->step = CORO_BEGIN; \
|
||||
coro->sp = 0; \
|
||||
} while ( 0 )
|
||||
|
||||
#define CORO_STOP() \
|
||||
do { \
|
||||
return 0; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Add this macro to your coro_t structure containing the variables for the coroutine */
|
||||
#define CORO_FIELDS \
|
||||
int step, sp; \
|
||||
int stack[ 8 ];
|
||||
|
||||
#endif /* CORO_H */
|
||||
#ifndef CORO_H
|
||||
#define CORO_H
|
||||
|
||||
/*
|
||||
Released under the CC0: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/* Use at the beginning of the coroutine, you must have declared a variable coro_t* coro */
|
||||
#define CORO_ENTER() \
|
||||
{ \
|
||||
CORO_again: ; \
|
||||
switch ( coro->step ) { \
|
||||
case CORO_BEGIN: ;
|
||||
|
||||
/* Use to define labels which are targets to GOTO and GOSUB */
|
||||
#define CORO_SUB( x ) \
|
||||
case x: ;
|
||||
|
||||
/* Use at the end of the coroutine */
|
||||
#define CORO_LEAVE() \
|
||||
} } \
|
||||
do { return 0; } while ( 0 )
|
||||
|
||||
/* Go to the x label */
|
||||
#define CORO_GOTO( x ) \
|
||||
do { \
|
||||
coro->step = ( x ); \
|
||||
goto CORO_again; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Go to a subroutine, execution continues until the subroutine returns via RET */
|
||||
#define CORO_GOSUB( x ) \
|
||||
do { \
|
||||
coro->stack[ coro->sp++ ] = __LINE__; \
|
||||
coro->step = ( x ); \
|
||||
goto CORO_again; \
|
||||
case __LINE__: ; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Returns from a subroutine */
|
||||
#define CORO_RET() \
|
||||
do { \
|
||||
coro->step = coro->stack[ --coro->sp ]; \
|
||||
goto CORO_again; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Yields to the caller, execution continues from this point when the coroutine is resumed */
|
||||
#define CORO_YIELD() \
|
||||
do { \
|
||||
coro->step = __LINE__; \
|
||||
return 1; \
|
||||
case __LINE__: ; \
|
||||
} while ( 0 )
|
||||
|
||||
/* The coroutine entry point, never use 0 as a label */
|
||||
#define CORO_BEGIN 0
|
||||
|
||||
/* Sets up the coroutine */
|
||||
#define CORO_SETUP() \
|
||||
do { \
|
||||
coro->step = CORO_BEGIN; \
|
||||
coro->sp = 0; \
|
||||
} while ( 0 )
|
||||
|
||||
#define CORO_STOP() \
|
||||
do { \
|
||||
return 0; \
|
||||
} while ( 0 )
|
||||
|
||||
/* Add this macro to your coro_t structure containing the variables for the coroutine */
|
||||
#define CORO_FIELDS \
|
||||
int step, sp; \
|
||||
int stack[ 8 ];
|
||||
|
||||
#endif /* CORO_H */
|
||||
|
830
cheevos/var.c
830
cheevos/var.c
@ -1,415 +1,415 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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 <ctype.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "var.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../core.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Parsing
|
||||
*****************************************************************************/
|
||||
|
||||
static cheevos_var_size_t cheevos_var_parse_prefix(const char** memaddr)
|
||||
{
|
||||
/* Careful not to use ABCDEF here, this denotes part of an actual variable! */
|
||||
const char* str = *memaddr;
|
||||
cheevos_var_size_t size;
|
||||
|
||||
switch (toupper((unsigned char)*str++))
|
||||
{
|
||||
case 'M':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_0;
|
||||
break;
|
||||
case 'N':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_1;
|
||||
break;
|
||||
case 'O':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_2;
|
||||
break;
|
||||
case 'P':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_3;
|
||||
break;
|
||||
case 'Q':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_4;
|
||||
break;
|
||||
case 'R':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_5;
|
||||
break;
|
||||
case 'S':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_6;
|
||||
break;
|
||||
case 'T':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_7;
|
||||
break;
|
||||
case 'L':
|
||||
size = CHEEVOS_VAR_SIZE_NIBBLE_LOWER;
|
||||
break;
|
||||
case 'U':
|
||||
size = CHEEVOS_VAR_SIZE_NIBBLE_UPPER;
|
||||
break;
|
||||
case 'H':
|
||||
size = CHEEVOS_VAR_SIZE_EIGHT_BITS;
|
||||
break;
|
||||
case 'X':
|
||||
size = CHEEVOS_VAR_SIZE_THIRTYTWO_BITS;
|
||||
break;
|
||||
default:
|
||||
str--;
|
||||
/* fall through */
|
||||
case ' ':
|
||||
size = CHEEVOS_VAR_SIZE_SIXTEEN_BITS;
|
||||
break;
|
||||
}
|
||||
|
||||
*memaddr = str;
|
||||
return size;
|
||||
}
|
||||
|
||||
static size_t cheevos_var_reduce(size_t addr, size_t mask)
|
||||
{
|
||||
while (mask)
|
||||
{
|
||||
size_t tmp = (mask - 1) & ~mask;
|
||||
addr = (addr & tmp) | ((addr >> 1) & ~tmp);
|
||||
mask = (mask & (mask - 1)) >> 1;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static size_t cheevos_var_highest_bit(size_t n)
|
||||
{
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
|
||||
return n ^ (n >> 1);
|
||||
}
|
||||
|
||||
void cheevos_var_parse(cheevos_var_t* var, const char** memaddr)
|
||||
{
|
||||
char *end = NULL;
|
||||
const char *str = *memaddr;
|
||||
unsigned base = 16;
|
||||
|
||||
var->is_bcd = false;
|
||||
|
||||
if (toupper((unsigned char)*str) == 'D' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* d0x + 4 hex digits */
|
||||
str += 3;
|
||||
var->type = CHEEVOS_VAR_TYPE_DELTA_MEM;
|
||||
}
|
||||
else if (toupper((unsigned char)*str) == 'B' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* b0x (binary-coded decimal) */
|
||||
str += 3;
|
||||
var->is_bcd = true;
|
||||
var->type = CHEEVOS_VAR_TYPE_ADDRESS;
|
||||
}
|
||||
else if (*str == '0' && toupper((unsigned char)str[1]) == 'X')
|
||||
{
|
||||
/* 0x + 4 hex digits */
|
||||
str += 2;
|
||||
var->type = CHEEVOS_VAR_TYPE_ADDRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
var->type = CHEEVOS_VAR_TYPE_VALUE_COMP;
|
||||
|
||||
if (toupper((unsigned char)*str) == 'H')
|
||||
str++;
|
||||
else
|
||||
{
|
||||
if (toupper((unsigned char)*str) == 'V')
|
||||
str++;
|
||||
|
||||
base = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->type != CHEEVOS_VAR_TYPE_VALUE_COMP)
|
||||
{
|
||||
var->size = cheevos_var_parse_prefix(&str);
|
||||
}
|
||||
|
||||
var->value = (unsigned)strtol(str, &end, base);
|
||||
*memaddr = end;
|
||||
}
|
||||
|
||||
void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console)
|
||||
{
|
||||
rarch_system_info_t *system = runloop_get_system_info();
|
||||
|
||||
var->bank_id = -1;
|
||||
|
||||
if (console == CHEEVOS_CONSOLE_NINTENDO)
|
||||
{
|
||||
if (var->value >= 0x0800 && var->value < 0x2000)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "NES memory address in mirrorred RAM %X, adjusted to %X\n", var->value, var->value & 0x07ff);
|
||||
var->value &= 0x07ff;
|
||||
}
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_GAMEBOY_COLOR)
|
||||
{
|
||||
if (var->value >= 0xe000 && var->value <= 0xfdff)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBC memory address in echo RAM %X, adjusted to %X\n", var->value, var->value - 0x2000);
|
||||
var->value -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if (system->mmaps.num_descriptors != 0)
|
||||
{
|
||||
const rarch_memory_descriptor_t *desc = NULL;
|
||||
const rarch_memory_descriptor_t *end = NULL;
|
||||
|
||||
/* Patch the address to correctly map it to the mmaps */
|
||||
if (console == CHEEVOS_CONSOLE_GAMEBOY_ADVANCE)
|
||||
{
|
||||
if (var->value < 0x8000) /* Internal RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBA memory address %X adjusted to %X\n", var->value, var->value + 0x3000000);
|
||||
var->value += 0x3000000;
|
||||
}
|
||||
else /* Work RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBA memory address %X adjusted to %X\n", var->value, var->value + 0x2000000 - 0x8000);
|
||||
var->value += 0x2000000 - 0x8000;
|
||||
}
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_PC_ENGINE)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "PCE memory address %X adjusted to %X\n", var->value, var->value + 0x1f0000);
|
||||
var->value += 0x1f0000;
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_SUPER_NINTENDO)
|
||||
{
|
||||
if (var->value < 0x020000) /* Work RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "SNES memory address %X adjusted to %X\n", var->value, var->value + 0x7e0000);
|
||||
var->value += 0x7e0000;
|
||||
}
|
||||
else /* Save RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "SNES memory address %X adjusted to %X\n", var->value, var->value + 0x006000 - 0x020000);
|
||||
var->value += 0x006000 - 0x020000;
|
||||
}
|
||||
}
|
||||
|
||||
desc = system->mmaps.descriptors;
|
||||
end = desc + system->mmaps.num_descriptors;
|
||||
|
||||
for (; desc < end; desc++)
|
||||
{
|
||||
if (((desc->core.start ^ var->value) & desc->core.select) == 0)
|
||||
{
|
||||
unsigned addr = var->value;
|
||||
var->bank_id = (int)(desc - system->mmaps.descriptors);
|
||||
var->value = (unsigned)cheevos_var_reduce(
|
||||
(addr - desc->core.start) & desc->disconnect_mask,
|
||||
desc->core.disconnect);
|
||||
|
||||
if (var->value >= desc->core.len)
|
||||
var->value -= cheevos_var_highest_bit(var->value);
|
||||
|
||||
var->value += desc->core.offset;
|
||||
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "address %X set to descriptor %d at offset %X\n", addr, var->bank_id + 1, var->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
retro_ctx_memory_info_t meminfo;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
meminfo.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
break;
|
||||
case 1:
|
||||
meminfo.id = RETRO_MEMORY_SAVE_RAM;
|
||||
break;
|
||||
case 2:
|
||||
meminfo.id = RETRO_MEMORY_VIDEO_RAM;
|
||||
break;
|
||||
case 3:
|
||||
meminfo.id = RETRO_MEMORY_RTC;
|
||||
break;
|
||||
}
|
||||
|
||||
core_get_memory(&meminfo);
|
||||
|
||||
if (var->value < meminfo.size)
|
||||
{
|
||||
var->bank_id = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HACK subtract the correct amount of bytes to reach the save RAM */
|
||||
if (i == 0 && console == CHEEVOS_CONSOLE_NINTENDO)
|
||||
var->value -= 0x6000;
|
||||
else
|
||||
var->value -= meminfo.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Testing
|
||||
*****************************************************************************/
|
||||
|
||||
uint8_t* cheevos_var_get_memory(const cheevos_var_t* var)
|
||||
{
|
||||
uint8_t* memory = NULL;
|
||||
|
||||
if (var->bank_id >= 0)
|
||||
{
|
||||
rarch_system_info_t* system = runloop_get_system_info();
|
||||
|
||||
if (system->mmaps.num_descriptors != 0)
|
||||
memory = (uint8_t*)system->mmaps.descriptors[var->bank_id].core.ptr;
|
||||
else
|
||||
{
|
||||
retro_ctx_memory_info_t meminfo = {NULL, 0, 0};
|
||||
|
||||
switch (var->bank_id)
|
||||
{
|
||||
case 0:
|
||||
meminfo.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
break;
|
||||
case 1:
|
||||
meminfo.id = RETRO_MEMORY_SAVE_RAM;
|
||||
break;
|
||||
case 2:
|
||||
meminfo.id = RETRO_MEMORY_VIDEO_RAM;
|
||||
break;
|
||||
case 3:
|
||||
meminfo.id = RETRO_MEMORY_RTC;
|
||||
break;
|
||||
default:
|
||||
CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %s\n", var->bank_id);
|
||||
break;
|
||||
}
|
||||
|
||||
core_get_memory(&meminfo);
|
||||
memory = (uint8_t*)meminfo.data;
|
||||
}
|
||||
|
||||
if (memory)
|
||||
memory += var->value;
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
unsigned cheevos_var_get_value(cheevos_var_t* var)
|
||||
{
|
||||
const uint8_t* memory = NULL;
|
||||
unsigned value = 0;
|
||||
|
||||
switch (var->type)
|
||||
{
|
||||
case CHEEVOS_VAR_TYPE_VALUE_COMP:
|
||||
value = var->value;
|
||||
break;
|
||||
|
||||
case CHEEVOS_VAR_TYPE_ADDRESS:
|
||||
case CHEEVOS_VAR_TYPE_DELTA_MEM:
|
||||
memory = cheevos_var_get_memory(var);
|
||||
|
||||
if (memory)
|
||||
{
|
||||
value = memory[0];
|
||||
|
||||
switch (var->size)
|
||||
{
|
||||
case CHEEVOS_VAR_SIZE_BIT_0:
|
||||
value &= 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_1:
|
||||
value = (value >> 1) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_2:
|
||||
value = (value >> 2) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_3:
|
||||
value = (value >> 3) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_4:
|
||||
value = (value >> 4) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_5:
|
||||
value = (value >> 5) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_6:
|
||||
value = (value >> 6) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_7:
|
||||
value = (value >> 7) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_LOWER:
|
||||
value &= 0x0f;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_UPPER:
|
||||
value = (value >> 4) & 0x0f;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_EIGHT_BITS:
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_SIXTEEN_BITS:
|
||||
value |= memory[1] << 8;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS:
|
||||
value |= memory[1] << 8;
|
||||
value |= memory[2] << 16;
|
||||
value |= memory[3] << 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
{
|
||||
unsigned previous = var->previous;
|
||||
var->previous = value;
|
||||
value = previous;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CHEEVOS_VAR_TYPE_DYNAMIC_VAR:
|
||||
/* We shouldn't get here... */
|
||||
break;
|
||||
}
|
||||
|
||||
if(var->is_bcd)
|
||||
return (((value >> 4) & 0xf) * 10) + (value & 0xf);
|
||||
return value;
|
||||
}
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2017 - Andre Leiradella
|
||||
*
|
||||
* 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 <ctype.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "var.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../core.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Parsing
|
||||
*****************************************************************************/
|
||||
|
||||
static cheevos_var_size_t cheevos_var_parse_prefix(const char** memaddr)
|
||||
{
|
||||
/* Careful not to use ABCDEF here, this denotes part of an actual variable! */
|
||||
const char* str = *memaddr;
|
||||
cheevos_var_size_t size;
|
||||
|
||||
switch (toupper((unsigned char)*str++))
|
||||
{
|
||||
case 'M':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_0;
|
||||
break;
|
||||
case 'N':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_1;
|
||||
break;
|
||||
case 'O':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_2;
|
||||
break;
|
||||
case 'P':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_3;
|
||||
break;
|
||||
case 'Q':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_4;
|
||||
break;
|
||||
case 'R':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_5;
|
||||
break;
|
||||
case 'S':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_6;
|
||||
break;
|
||||
case 'T':
|
||||
size = CHEEVOS_VAR_SIZE_BIT_7;
|
||||
break;
|
||||
case 'L':
|
||||
size = CHEEVOS_VAR_SIZE_NIBBLE_LOWER;
|
||||
break;
|
||||
case 'U':
|
||||
size = CHEEVOS_VAR_SIZE_NIBBLE_UPPER;
|
||||
break;
|
||||
case 'H':
|
||||
size = CHEEVOS_VAR_SIZE_EIGHT_BITS;
|
||||
break;
|
||||
case 'X':
|
||||
size = CHEEVOS_VAR_SIZE_THIRTYTWO_BITS;
|
||||
break;
|
||||
default:
|
||||
str--;
|
||||
/* fall through */
|
||||
case ' ':
|
||||
size = CHEEVOS_VAR_SIZE_SIXTEEN_BITS;
|
||||
break;
|
||||
}
|
||||
|
||||
*memaddr = str;
|
||||
return size;
|
||||
}
|
||||
|
||||
static size_t cheevos_var_reduce(size_t addr, size_t mask)
|
||||
{
|
||||
while (mask)
|
||||
{
|
||||
size_t tmp = (mask - 1) & ~mask;
|
||||
addr = (addr & tmp) | ((addr >> 1) & ~tmp);
|
||||
mask = (mask & (mask - 1)) >> 1;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static size_t cheevos_var_highest_bit(size_t n)
|
||||
{
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
|
||||
return n ^ (n >> 1);
|
||||
}
|
||||
|
||||
void cheevos_var_parse(cheevos_var_t* var, const char** memaddr)
|
||||
{
|
||||
char *end = NULL;
|
||||
const char *str = *memaddr;
|
||||
unsigned base = 16;
|
||||
|
||||
var->is_bcd = false;
|
||||
|
||||
if (toupper((unsigned char)*str) == 'D' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* d0x + 4 hex digits */
|
||||
str += 3;
|
||||
var->type = CHEEVOS_VAR_TYPE_DELTA_MEM;
|
||||
}
|
||||
else if (toupper((unsigned char)*str) == 'B' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* b0x (binary-coded decimal) */
|
||||
str += 3;
|
||||
var->is_bcd = true;
|
||||
var->type = CHEEVOS_VAR_TYPE_ADDRESS;
|
||||
}
|
||||
else if (*str == '0' && toupper((unsigned char)str[1]) == 'X')
|
||||
{
|
||||
/* 0x + 4 hex digits */
|
||||
str += 2;
|
||||
var->type = CHEEVOS_VAR_TYPE_ADDRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
var->type = CHEEVOS_VAR_TYPE_VALUE_COMP;
|
||||
|
||||
if (toupper((unsigned char)*str) == 'H')
|
||||
str++;
|
||||
else
|
||||
{
|
||||
if (toupper((unsigned char)*str) == 'V')
|
||||
str++;
|
||||
|
||||
base = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->type != CHEEVOS_VAR_TYPE_VALUE_COMP)
|
||||
{
|
||||
var->size = cheevos_var_parse_prefix(&str);
|
||||
}
|
||||
|
||||
var->value = (unsigned)strtol(str, &end, base);
|
||||
*memaddr = end;
|
||||
}
|
||||
|
||||
void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console)
|
||||
{
|
||||
rarch_system_info_t *system = runloop_get_system_info();
|
||||
|
||||
var->bank_id = -1;
|
||||
|
||||
if (console == CHEEVOS_CONSOLE_NINTENDO)
|
||||
{
|
||||
if (var->value >= 0x0800 && var->value < 0x2000)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "NES memory address in mirrorred RAM %X, adjusted to %X\n", var->value, var->value & 0x07ff);
|
||||
var->value &= 0x07ff;
|
||||
}
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_GAMEBOY_COLOR)
|
||||
{
|
||||
if (var->value >= 0xe000 && var->value <= 0xfdff)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBC memory address in echo RAM %X, adjusted to %X\n", var->value, var->value - 0x2000);
|
||||
var->value -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if (system->mmaps.num_descriptors != 0)
|
||||
{
|
||||
const rarch_memory_descriptor_t *desc = NULL;
|
||||
const rarch_memory_descriptor_t *end = NULL;
|
||||
|
||||
/* Patch the address to correctly map it to the mmaps */
|
||||
if (console == CHEEVOS_CONSOLE_GAMEBOY_ADVANCE)
|
||||
{
|
||||
if (var->value < 0x8000) /* Internal RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBA memory address %X adjusted to %X\n", var->value, var->value + 0x3000000);
|
||||
var->value += 0x3000000;
|
||||
}
|
||||
else /* Work RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "GBA memory address %X adjusted to %X\n", var->value, var->value + 0x2000000 - 0x8000);
|
||||
var->value += 0x2000000 - 0x8000;
|
||||
}
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_PC_ENGINE)
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "PCE memory address %X adjusted to %X\n", var->value, var->value + 0x1f0000);
|
||||
var->value += 0x1f0000;
|
||||
}
|
||||
else if (console == CHEEVOS_CONSOLE_SUPER_NINTENDO)
|
||||
{
|
||||
if (var->value < 0x020000) /* Work RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "SNES memory address %X adjusted to %X\n", var->value, var->value + 0x7e0000);
|
||||
var->value += 0x7e0000;
|
||||
}
|
||||
else /* Save RAM */
|
||||
{
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "SNES memory address %X adjusted to %X\n", var->value, var->value + 0x006000 - 0x020000);
|
||||
var->value += 0x006000 - 0x020000;
|
||||
}
|
||||
}
|
||||
|
||||
desc = system->mmaps.descriptors;
|
||||
end = desc + system->mmaps.num_descriptors;
|
||||
|
||||
for (; desc < end; desc++)
|
||||
{
|
||||
if (((desc->core.start ^ var->value) & desc->core.select) == 0)
|
||||
{
|
||||
unsigned addr = var->value;
|
||||
var->bank_id = (int)(desc - system->mmaps.descriptors);
|
||||
var->value = (unsigned)cheevos_var_reduce(
|
||||
(addr - desc->core.start) & desc->disconnect_mask,
|
||||
desc->core.disconnect);
|
||||
|
||||
if (var->value >= desc->core.len)
|
||||
var->value -= cheevos_var_highest_bit(var->value);
|
||||
|
||||
var->value += desc->core.offset;
|
||||
|
||||
CHEEVOS_LOG(CHEEVOS_TAG "address %X set to descriptor %d at offset %X\n", addr, var->bank_id + 1, var->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
retro_ctx_memory_info_t meminfo;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
meminfo.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
break;
|
||||
case 1:
|
||||
meminfo.id = RETRO_MEMORY_SAVE_RAM;
|
||||
break;
|
||||
case 2:
|
||||
meminfo.id = RETRO_MEMORY_VIDEO_RAM;
|
||||
break;
|
||||
case 3:
|
||||
meminfo.id = RETRO_MEMORY_RTC;
|
||||
break;
|
||||
}
|
||||
|
||||
core_get_memory(&meminfo);
|
||||
|
||||
if (var->value < meminfo.size)
|
||||
{
|
||||
var->bank_id = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HACK subtract the correct amount of bytes to reach the save RAM */
|
||||
if (i == 0 && console == CHEEVOS_CONSOLE_NINTENDO)
|
||||
var->value -= 0x6000;
|
||||
else
|
||||
var->value -= meminfo.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Testing
|
||||
*****************************************************************************/
|
||||
|
||||
uint8_t* cheevos_var_get_memory(const cheevos_var_t* var)
|
||||
{
|
||||
uint8_t* memory = NULL;
|
||||
|
||||
if (var->bank_id >= 0)
|
||||
{
|
||||
rarch_system_info_t* system = runloop_get_system_info();
|
||||
|
||||
if (system->mmaps.num_descriptors != 0)
|
||||
memory = (uint8_t*)system->mmaps.descriptors[var->bank_id].core.ptr;
|
||||
else
|
||||
{
|
||||
retro_ctx_memory_info_t meminfo = {NULL, 0, 0};
|
||||
|
||||
switch (var->bank_id)
|
||||
{
|
||||
case 0:
|
||||
meminfo.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
break;
|
||||
case 1:
|
||||
meminfo.id = RETRO_MEMORY_SAVE_RAM;
|
||||
break;
|
||||
case 2:
|
||||
meminfo.id = RETRO_MEMORY_VIDEO_RAM;
|
||||
break;
|
||||
case 3:
|
||||
meminfo.id = RETRO_MEMORY_RTC;
|
||||
break;
|
||||
default:
|
||||
CHEEVOS_ERR(CHEEVOS_TAG "invalid bank id: %s\n", var->bank_id);
|
||||
break;
|
||||
}
|
||||
|
||||
core_get_memory(&meminfo);
|
||||
memory = (uint8_t*)meminfo.data;
|
||||
}
|
||||
|
||||
if (memory)
|
||||
memory += var->value;
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
unsigned cheevos_var_get_value(cheevos_var_t* var)
|
||||
{
|
||||
const uint8_t* memory = NULL;
|
||||
unsigned value = 0;
|
||||
|
||||
switch (var->type)
|
||||
{
|
||||
case CHEEVOS_VAR_TYPE_VALUE_COMP:
|
||||
value = var->value;
|
||||
break;
|
||||
|
||||
case CHEEVOS_VAR_TYPE_ADDRESS:
|
||||
case CHEEVOS_VAR_TYPE_DELTA_MEM:
|
||||
memory = cheevos_var_get_memory(var);
|
||||
|
||||
if (memory)
|
||||
{
|
||||
value = memory[0];
|
||||
|
||||
switch (var->size)
|
||||
{
|
||||
case CHEEVOS_VAR_SIZE_BIT_0:
|
||||
value &= 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_1:
|
||||
value = (value >> 1) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_2:
|
||||
value = (value >> 2) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_3:
|
||||
value = (value >> 3) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_4:
|
||||
value = (value >> 4) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_5:
|
||||
value = (value >> 5) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_6:
|
||||
value = (value >> 6) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_BIT_7:
|
||||
value = (value >> 7) & 1;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_LOWER:
|
||||
value &= 0x0f;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_NIBBLE_UPPER:
|
||||
value = (value >> 4) & 0x0f;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_EIGHT_BITS:
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_SIXTEEN_BITS:
|
||||
value |= memory[1] << 8;
|
||||
break;
|
||||
case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS:
|
||||
value |= memory[1] << 8;
|
||||
value |= memory[2] << 16;
|
||||
value |= memory[3] << 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
{
|
||||
unsigned previous = var->previous;
|
||||
var->previous = value;
|
||||
value = previous;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CHEEVOS_VAR_TYPE_DYNAMIC_VAR:
|
||||
/* We shouldn't get here... */
|
||||
break;
|
||||
}
|
||||
|
||||
if(var->is_bcd)
|
||||
return (((value >> 4) & 0xf) * 10) + (value & 0xf);
|
||||
return value;
|
||||
}
|
||||
|
156
cheevos/var.h
156
cheevos/var.h
@ -1,78 +1,78 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2018 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_VAR_H
|
||||
#define __RARCH_CHEEVOS_VAR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cheevos.h"
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_VAR_SIZE_BIT_0 = 0,
|
||||
CHEEVOS_VAR_SIZE_BIT_1,
|
||||
CHEEVOS_VAR_SIZE_BIT_2,
|
||||
CHEEVOS_VAR_SIZE_BIT_3,
|
||||
CHEEVOS_VAR_SIZE_BIT_4,
|
||||
CHEEVOS_VAR_SIZE_BIT_5,
|
||||
CHEEVOS_VAR_SIZE_BIT_6,
|
||||
CHEEVOS_VAR_SIZE_BIT_7,
|
||||
CHEEVOS_VAR_SIZE_NIBBLE_LOWER,
|
||||
CHEEVOS_VAR_SIZE_NIBBLE_UPPER,
|
||||
/* Byte, */
|
||||
CHEEVOS_VAR_SIZE_EIGHT_BITS, /* =Byte, */
|
||||
CHEEVOS_VAR_SIZE_SIXTEEN_BITS,
|
||||
CHEEVOS_VAR_SIZE_THIRTYTWO_BITS
|
||||
} cheevos_var_size_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* compare to the value of a live address in RAM */
|
||||
CHEEVOS_VAR_TYPE_ADDRESS = 0,
|
||||
|
||||
/* a number. assume 32 bit */
|
||||
CHEEVOS_VAR_TYPE_VALUE_COMP,
|
||||
|
||||
/* the value last known at this address. */
|
||||
CHEEVOS_VAR_TYPE_DELTA_MEM,
|
||||
|
||||
/* a custom user-set variable */
|
||||
CHEEVOS_VAR_TYPE_DYNAMIC_VAR
|
||||
} cheevos_var_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cheevos_var_size_t size;
|
||||
cheevos_var_type_t type;
|
||||
int bank_id;
|
||||
bool is_bcd;
|
||||
unsigned value;
|
||||
unsigned previous;
|
||||
} cheevos_var_t;
|
||||
|
||||
void cheevos_var_parse(cheevos_var_t* var, const char** memaddr);
|
||||
void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console);
|
||||
|
||||
uint8_t* cheevos_var_get_memory(const cheevos_var_t* var);
|
||||
unsigned cheevos_var_get_value(cheevos_var_t* var);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_VAR_H */
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2015-2018 - Andre Leiradella
|
||||
*
|
||||
* 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_CHEEVOS_VAR_H
|
||||
#define __RARCH_CHEEVOS_VAR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cheevos.h"
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHEEVOS_VAR_SIZE_BIT_0 = 0,
|
||||
CHEEVOS_VAR_SIZE_BIT_1,
|
||||
CHEEVOS_VAR_SIZE_BIT_2,
|
||||
CHEEVOS_VAR_SIZE_BIT_3,
|
||||
CHEEVOS_VAR_SIZE_BIT_4,
|
||||
CHEEVOS_VAR_SIZE_BIT_5,
|
||||
CHEEVOS_VAR_SIZE_BIT_6,
|
||||
CHEEVOS_VAR_SIZE_BIT_7,
|
||||
CHEEVOS_VAR_SIZE_NIBBLE_LOWER,
|
||||
CHEEVOS_VAR_SIZE_NIBBLE_UPPER,
|
||||
/* Byte, */
|
||||
CHEEVOS_VAR_SIZE_EIGHT_BITS, /* =Byte, */
|
||||
CHEEVOS_VAR_SIZE_SIXTEEN_BITS,
|
||||
CHEEVOS_VAR_SIZE_THIRTYTWO_BITS
|
||||
} cheevos_var_size_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* compare to the value of a live address in RAM */
|
||||
CHEEVOS_VAR_TYPE_ADDRESS = 0,
|
||||
|
||||
/* a number. assume 32 bit */
|
||||
CHEEVOS_VAR_TYPE_VALUE_COMP,
|
||||
|
||||
/* the value last known at this address. */
|
||||
CHEEVOS_VAR_TYPE_DELTA_MEM,
|
||||
|
||||
/* a custom user-set variable */
|
||||
CHEEVOS_VAR_TYPE_DYNAMIC_VAR
|
||||
} cheevos_var_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cheevos_var_size_t size;
|
||||
cheevos_var_type_t type;
|
||||
int bank_id;
|
||||
bool is_bcd;
|
||||
unsigned value;
|
||||
unsigned previous;
|
||||
} cheevos_var_t;
|
||||
|
||||
void cheevos_var_parse(cheevos_var_t* var, const char** memaddr);
|
||||
void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console);
|
||||
|
||||
uint8_t* cheevos_var_get_memory(const cheevos_var_t* var);
|
||||
unsigned cheevos_var_get_value(cheevos_var_t* var);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* __RARCH_CHEEVOS_VAR_H */
|
||||
|
65
command.c
65
command.c
@ -42,7 +42,7 @@
|
||||
#ifdef HAVE_CHEEVOS
|
||||
#include "cheevos/cheevos.h"
|
||||
#ifdef HAVE_NEW_CHEEVOS
|
||||
#include "cheevos/fixup.h"
|
||||
#include "cheevos-new/fixup.h"
|
||||
#else
|
||||
#include "cheevos/var.h"
|
||||
#endif
|
||||
@ -89,7 +89,9 @@
|
||||
#include "managers/cheat_manager.h"
|
||||
#include "managers/state_manager.h"
|
||||
#include "ui/ui_companion_driver.h"
|
||||
#include "tasks/task_content.h"
|
||||
#include "tasks/tasks_internal.h"
|
||||
#include "gfx/video_driver.h"
|
||||
#include "list_special.h"
|
||||
|
||||
#include "core.h"
|
||||
@ -174,7 +176,7 @@ static bool command_version(const char* arg)
|
||||
{
|
||||
char reply[256] = {0};
|
||||
|
||||
sprintf(reply, "%s\n", PACKAGE_VERSION);
|
||||
snprintf(reply, sizeof(reply), "%s\n", PACKAGE_VERSION);
|
||||
#if defined(HAVE_CHEEVOS) && (defined(HAVE_STDIN_CMD) || defined(HAVE_NETWORK_CMD) && defined(HAVE_NETWORKING))
|
||||
command_reply(reply, strlen(reply));
|
||||
#endif
|
||||
@ -291,7 +293,7 @@ static bool command_read_ram(const char *arg)
|
||||
|
||||
if (data)
|
||||
{
|
||||
for (i=0;i<nbytes;i++)
|
||||
for (i = 0; i < nbytes; i++)
|
||||
sprintf(reply_at+3*i, " %.2X", data[i]);
|
||||
reply_at[3*nbytes] = '\n';
|
||||
command_reply(reply, reply_at+3*nbytes+1 - reply);
|
||||
@ -303,7 +305,7 @@ static bool command_read_ram(const char *arg)
|
||||
}
|
||||
free(reply);
|
||||
#else
|
||||
cheevos_var_t var;
|
||||
cheevos_var_t var;
|
||||
unsigned i;
|
||||
char reply[256] = {0};
|
||||
const uint8_t * data = NULL;
|
||||
@ -323,7 +325,7 @@ static bool command_read_ram(const char *arg)
|
||||
{
|
||||
unsigned nbytes = strtol(reply_at, NULL, 10);
|
||||
|
||||
for (i=0;i<nbytes;i++)
|
||||
for (i = 0; i < nbytes; i++)
|
||||
sprintf(reply_at+3*i, " %.2X", data[i]);
|
||||
reply_at[3*nbytes] = '\n';
|
||||
command_reply(reply, reply_at+3*nbytes+1 - reply);
|
||||
@ -1766,56 +1768,6 @@ static bool command_event_resize_windowed_scale(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
void command_playlist_push_write(
|
||||
playlist_t *playlist,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name)
|
||||
{
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
if (playlist_push(
|
||||
playlist,
|
||||
path,
|
||||
label,
|
||||
core_path,
|
||||
core_name,
|
||||
NULL,
|
||||
NULL
|
||||
))
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
void command_playlist_update_write(
|
||||
playlist_t *plist,
|
||||
size_t idx,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_display_name,
|
||||
const char *crc32,
|
||||
const char *db_name)
|
||||
{
|
||||
playlist_t *playlist = plist ? plist : playlist_get_cached();
|
||||
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
playlist_update(
|
||||
playlist,
|
||||
idx,
|
||||
path,
|
||||
label,
|
||||
core_path,
|
||||
core_display_name,
|
||||
crc32,
|
||||
db_name);
|
||||
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* command_event:
|
||||
* @cmd : Event command index.
|
||||
@ -2020,9 +1972,6 @@ bool command_event(enum event_command cmd, void *data)
|
||||
path_clear(RARCH_PATH_CORE);
|
||||
rarch_ctl(RARCH_CTL_SYSTEM_INFO_FREE, NULL);
|
||||
#endif
|
||||
core_unload_game();
|
||||
if (!rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
|
||||
core_unload();
|
||||
#ifdef HAVE_DISCORD
|
||||
if (discord_is_inited)
|
||||
{
|
||||
|
19
command.h
19
command.h
@ -27,8 +27,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "playlist.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef struct command command_t;
|
||||
@ -272,23 +270,6 @@ bool command_free(command_t *handle);
|
||||
**/
|
||||
bool command_event(enum event_command action, void *data);
|
||||
|
||||
void command_playlist_push_write(
|
||||
playlist_t *playlist,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name);
|
||||
|
||||
void command_playlist_update_write(
|
||||
playlist_t *playlist,
|
||||
size_t idx,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_display_name,
|
||||
const char *crc32,
|
||||
const char *db_name);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
32
config.def.h
32
config.def.h
@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
* Copyright (C) 2016 - Brad Parker
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
*
|
||||
* 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-
|
||||
@ -68,8 +68,8 @@ static bool bundle_assets_extract_enable = false;
|
||||
static bool materialui_icons_enable = true;
|
||||
#endif
|
||||
|
||||
static const unsigned crt_switch_resolution = CRT_SWITCH_NONE;
|
||||
static const int crt_switch_resolution_super = 2560;
|
||||
static const unsigned crt_switch_resolution = CRT_SWITCH_NONE;
|
||||
static const int crt_switch_resolution_super = 2560;
|
||||
static const int crt_switch_center_adjust = 0;
|
||||
|
||||
static const bool def_history_list_enable = true;
|
||||
@ -372,15 +372,9 @@ static unsigned menu_shader_pipeline = 1;
|
||||
static unsigned menu_shader_pipeline = 2;
|
||||
#endif
|
||||
|
||||
static bool show_advanced_settings = false;
|
||||
static const uint32_t menu_entry_normal_color = 0xffffffff;
|
||||
static const uint32_t menu_entry_hover_color = 0xff64ff64;
|
||||
static const uint32_t menu_title_color = 0xff64ff64;
|
||||
static const uint32_t menu_bg_dark_color = 0xc0202020;
|
||||
static const uint32_t menu_bg_light_color = 0xc0404040;
|
||||
static const uint32_t menu_border_dark_color = 0xc0204020;
|
||||
static const uint32_t menu_border_light_color = 0xc0408040;
|
||||
static unsigned rgui_color_theme = RGUI_THEME_CUSTOM;
|
||||
static bool show_advanced_settings = false;
|
||||
static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN;
|
||||
static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT;
|
||||
|
||||
#else
|
||||
static bool default_block_config_read = false;
|
||||
@ -402,12 +396,14 @@ static bool default_screenshots_in_content_dir = false;
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX1) || defined(_XBOX360)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L3_R3;
|
||||
#elif defined(PS2)
|
||||
#elif defined(PS2) || defined(PSP)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_HOLD_START;
|
||||
#elif defined(VITA)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L1_R1_START_SELECT;
|
||||
#elif defined(SWITCH) || defined(ORBIS)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_START_SELECT;
|
||||
#elif TARGET_OS_TV
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_DOWN_Y_L_R;
|
||||
#else
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_NONE;
|
||||
#endif
|
||||
@ -508,6 +504,13 @@ static const bool video_3ds_lcd_bottom = true;
|
||||
/* Will enable audio or not. */
|
||||
static const bool audio_enable = true;
|
||||
|
||||
/* Enable menu audio sounds. */
|
||||
static const bool audio_enable_menu = false;
|
||||
static const bool audio_enable_menu_ok = false;
|
||||
static const bool audio_enable_menu_cancel = false;
|
||||
static const bool audio_enable_menu_notice = false;
|
||||
static const bool audio_enable_menu_bgm = false;
|
||||
|
||||
/* Output samplerate. */
|
||||
#ifdef GEKKO
|
||||
static const unsigned out_rate = 32000;
|
||||
@ -689,6 +692,9 @@ static const uint16_t network_remote_base_port = 55400;
|
||||
/* Number of entries that will be kept in content history playlist file. */
|
||||
static const unsigned default_content_history_size = 100;
|
||||
|
||||
/* File format to use when writing playlists to disk */
|
||||
static const bool playlist_use_old_format = false;
|
||||
|
||||
/* Show Menu start-up screen on boot. */
|
||||
static const bool default_menu_show_start_screen = true;
|
||||
|
||||
|
@ -152,6 +152,12 @@ static const bool _coreaudio_supp = true;
|
||||
static const bool _coreaudio_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COREAUDIO3
|
||||
static const bool _coreaudio3_supp = true;
|
||||
#else
|
||||
static const bool _coreaudio3_supp = false;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OSS) || defined(HAVE_OSS_BSD)
|
||||
static const bool _oss_supp = true;
|
||||
#else
|
||||
|
106
configuration.c
106
configuration.c
@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||
* Copyright (C) 2015-2017 - Andrés Suárez
|
||||
* Copyright (C) 2016-2017 - Brad Parker
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
*
|
||||
* 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-
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
#include "file_path_special.h"
|
||||
#include "audio/audio_driver.h"
|
||||
#include "gfx/video_driver.h"
|
||||
#include "input/input_driver.h"
|
||||
#include "configuration.h"
|
||||
#include "content.h"
|
||||
@ -50,6 +51,7 @@
|
||||
#include "verbosity.h"
|
||||
#include "lakka.h"
|
||||
|
||||
#include "tasks/task_content.h"
|
||||
#include "tasks/tasks_internal.h"
|
||||
|
||||
#include "../list_special.h"
|
||||
@ -190,6 +192,7 @@ enum audio_driver_enum
|
||||
AUDIO_DSOUND,
|
||||
AUDIO_WASAPI,
|
||||
AUDIO_COREAUDIO,
|
||||
AUDIO_COREAUDIO3,
|
||||
AUDIO_PS3,
|
||||
AUDIO_XENON360,
|
||||
AUDIO_WII,
|
||||
@ -298,7 +301,6 @@ enum menu_driver_enum
|
||||
MENU_MATERIALUI,
|
||||
MENU_XMB,
|
||||
MENU_STRIPES,
|
||||
MENU_NUKLEAR,
|
||||
MENU_OZONE,
|
||||
MENU_NULL
|
||||
};
|
||||
@ -393,6 +395,8 @@ static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA;
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS;
|
||||
#elif defined(HAVE_JACK)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK;
|
||||
#elif defined(HAVE_COREAUDIO3)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3;
|
||||
#elif defined(HAVE_COREAUDIO)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO;
|
||||
#elif defined(HAVE_XAUDIO)
|
||||
@ -525,14 +529,14 @@ static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_ANDROID;
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL;
|
||||
#elif defined(DJGPP)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DOS;
|
||||
#elif defined(IOS)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI;
|
||||
#elif defined(HAVE_HID)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_HID;
|
||||
#elif defined(__QNX__)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_QNX;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_RWEBPAD;
|
||||
#elif defined(IOS)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI;
|
||||
#else
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_NULL;
|
||||
#endif
|
||||
@ -570,7 +574,7 @@ static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XUI;
|
||||
#elif defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI;
|
||||
#elif defined(HAVE_OZONE) && defined(HAVE_LIBNX)
|
||||
#elif defined(HAVE_OZONE) && (defined(HAVE_LIBNX) || TARGET_OS_TV)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE;
|
||||
#elif defined(HAVE_XMB) && !defined(_XBOX)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XMB;
|
||||
@ -666,6 +670,8 @@ const char *config_get_default_audio(void)
|
||||
return "roar";
|
||||
case AUDIO_COREAUDIO:
|
||||
return "coreaudio";
|
||||
case AUDIO_COREAUDIO3:
|
||||
return "coreaudio3";
|
||||
case AUDIO_AL:
|
||||
return "openal";
|
||||
case AUDIO_SL:
|
||||
@ -1089,8 +1095,6 @@ const char *config_get_default_menu(void)
|
||||
return "xmb";
|
||||
case MENU_STRIPES:
|
||||
return "stripes";
|
||||
case MENU_NUKLEAR:
|
||||
return "nuklear";
|
||||
case MENU_NULL:
|
||||
break;
|
||||
}
|
||||
@ -1133,6 +1137,9 @@ static struct config_array_setting *populate_settings_array(settings_t *settings
|
||||
unsigned count = 0;
|
||||
struct config_array_setting *tmp = (struct config_array_setting*)calloc(1, (*size + 1) * sizeof(struct config_array_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
/* Arrays */
|
||||
SETTING_ARRAY("playlist_names", settings->arrays.playlist_names, false, NULL, true);
|
||||
SETTING_ARRAY("playlist_cores", settings->arrays.playlist_cores, false, NULL, true);
|
||||
@ -1178,6 +1185,9 @@ static struct config_path_setting *populate_settings_path(settings_t *settings,
|
||||
global_t *global = global_get_ptr();
|
||||
struct config_path_setting *tmp = (struct config_path_setting*)calloc(1, (*size + 1) * sizeof(struct config_path_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
/* Paths */
|
||||
#ifdef HAVE_XMB
|
||||
SETTING_PATH("xmb_font", settings->paths.path_menu_xmb_font, false, NULL, true);
|
||||
@ -1209,6 +1219,8 @@ static struct config_path_setting *populate_settings_path(settings_t *settings,
|
||||
#ifdef HAVE_MENU
|
||||
SETTING_PATH("menu_wallpaper",
|
||||
settings->paths.path_menu_wallpaper, false, NULL, true);
|
||||
SETTING_PATH("rgui_menu_theme_preset",
|
||||
settings->paths.path_rgui_theme_preset, false, NULL, true);
|
||||
#endif
|
||||
SETTING_PATH("content_history_path",
|
||||
settings->paths.path_content_history, false, NULL, true);
|
||||
@ -1388,7 +1400,11 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("keyboard_gamepad_enable", &settings->bools.input_keyboard_gamepad_enable, true, true, false);
|
||||
SETTING_BOOL("core_set_supports_no_game_enable", &settings->bools.set_supports_no_game_enable, true, true, false);
|
||||
SETTING_BOOL("audio_enable", &settings->bools.audio_enable, true, audio_enable, false);
|
||||
SETTING_BOOL("audio_enable_menu", &settings->bools.audio_enable_menu, true, false, false);
|
||||
SETTING_BOOL("audio_enable_menu", &settings->bools.audio_enable_menu, true, audio_enable_menu, false);
|
||||
SETTING_BOOL("audio_enable_menu_ok", &settings->bools.audio_enable_menu_ok, true, audio_enable_menu_ok, false);
|
||||
SETTING_BOOL("audio_enable_menu_cancel", &settings->bools.audio_enable_menu_cancel, true, audio_enable_menu_cancel, false);
|
||||
SETTING_BOOL("audio_enable_menu_notice", &settings->bools.audio_enable_menu_notice, true, audio_enable_menu_notice, false);
|
||||
SETTING_BOOL("audio_enable_menu_bgm", &settings->bools.audio_enable_menu_bgm, true, audio_enable_menu_bgm, false);
|
||||
SETTING_BOOL("audio_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MUTE_ENABLE), true, false, false);
|
||||
SETTING_BOOL("audio_mixer_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MIXER_MUTE_ENABLE), true, false, false);
|
||||
SETTING_BOOL("location_allow", &settings->bools.location_allow, true, false, false);
|
||||
@ -1556,6 +1572,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("video_3ds_lcd_bottom", &settings->bools.video_3ds_lcd_bottom, true, video_3ds_lcd_bottom, false);
|
||||
#endif
|
||||
|
||||
SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, playlist_use_old_format, false);
|
||||
|
||||
*size = count;
|
||||
|
||||
return tmp;
|
||||
@ -1566,6 +1584,9 @@ static struct config_float_setting *populate_settings_float(settings_t *settings
|
||||
unsigned count = 0;
|
||||
struct config_float_setting *tmp = (struct config_float_setting*)calloc(1, (*size + 1) * sizeof(struct config_float_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
SETTING_FLOAT("video_aspect_ratio", &settings->floats.video_aspect_ratio, true, aspect_ratio, false);
|
||||
SETTING_FLOAT("video_scale", &settings->floats.video_scale, false, 0.0f, false);
|
||||
SETTING_FLOAT("crt_video_refresh_rate", &settings->floats.crt_video_refresh_rate, true, crt_refresh_rate, false);
|
||||
@ -1602,6 +1623,9 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
unsigned count = 0;
|
||||
struct config_uint_setting *tmp = (struct config_uint_setting*)malloc((*size + 1) * sizeof(struct config_uint_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
SETTING_UINT("streaming_mode", &settings->uints.streaming_mode, true, STREAMING_MODE_TWITCH, false);
|
||||
#endif
|
||||
@ -1638,7 +1662,10 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
SETTING_UINT("dpi_override_value", &settings->uints.menu_dpi_override_value, true, menu_dpi_override_value, false);
|
||||
SETTING_UINT("menu_thumbnails", &settings->uints.menu_thumbnails, true, menu_thumbnails_default, false);
|
||||
SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, menu_timedate_style, false);
|
||||
#ifdef HAVE_RGUI
|
||||
SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false);
|
||||
SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
|
||||
#endif
|
||||
#ifdef HAVE_LIBNX
|
||||
SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false);
|
||||
SETTING_UINT("split_joycon_p2", &settings->uints.input_split_joycon[1], true, 0, false);
|
||||
@ -1663,7 +1690,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
SETTING_UINT("materialui_menu_color_theme", &settings->uints.menu_materialui_color_theme, true, MATERIALUI_THEME_BLUE, false);
|
||||
SETTING_UINT("menu_shader_pipeline", &settings->uints.menu_xmb_shader_pipeline, true, menu_shader_pipeline, false);
|
||||
#ifdef HAVE_OZONE
|
||||
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 0, false);
|
||||
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 1, false);
|
||||
#endif
|
||||
#endif
|
||||
SETTING_UINT("audio_out_rate", &settings->uints.audio_out_rate, true, out_rate, false);
|
||||
@ -1727,6 +1754,9 @@ static struct config_size_setting *populate_settings_size(settings_t *settings,
|
||||
unsigned count = 0;
|
||||
struct config_size_setting *tmp = (struct config_size_setting*)calloc((*size + 1), sizeof(struct config_size_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
SETTING_SIZE("rewind_buffer_size", &settings->sizes.rewind_buffer_size, true, rewind_buffer_size, false);
|
||||
|
||||
*size = count;
|
||||
@ -1739,6 +1769,9 @@ static struct config_int_setting *populate_settings_int(settings_t *settings, in
|
||||
unsigned count = 0;
|
||||
struct config_int_setting *tmp = (struct config_int_setting*)calloc((*size + 1), sizeof(struct config_int_setting));
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
SETTING_INT("state_slot", &settings->ints.state_slot, false, 0 /* TODO */, false);
|
||||
#ifdef HAVE_NETWORKING
|
||||
SETTING_INT("netplay_check_frames", &settings->ints.netplay_check_frames, true, netplay_check_frames, false);
|
||||
@ -1939,13 +1972,6 @@ void config_set_defaults(void)
|
||||
#ifdef HAVE_MENU
|
||||
if (first_initialized)
|
||||
settings->bools.menu_show_start_screen = default_menu_show_start_screen;
|
||||
settings->uints.menu_entry_normal_color = menu_entry_normal_color;
|
||||
settings->uints.menu_entry_hover_color = menu_entry_hover_color;
|
||||
settings->uints.menu_title_color = menu_title_color;
|
||||
settings->uints.menu_bg_dark_color = menu_bg_dark_color;
|
||||
settings->uints.menu_bg_light_color = menu_bg_light_color;
|
||||
settings->uints.menu_border_dark_color = menu_border_dark_color;
|
||||
settings->uints.menu_border_light_color = menu_border_light_color;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
@ -2048,6 +2074,7 @@ void config_set_defaults(void)
|
||||
#endif
|
||||
*settings->paths.path_cheat_database = '\0';
|
||||
*settings->paths.path_menu_wallpaper = '\0';
|
||||
*settings->paths.path_rgui_theme_preset = '\0';
|
||||
*settings->paths.path_content_database = '\0';
|
||||
*settings->paths.path_overlay = '\0';
|
||||
*settings->paths.path_record_config = '\0';
|
||||
@ -2463,7 +2490,7 @@ static bool check_menu_driver_compatibility(void)
|
||||
string_is_equal(video_driver, "metal") ||
|
||||
string_is_equal(video_driver, "ctr") ||
|
||||
string_is_equal(video_driver, "vita2d"))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2632,6 +2659,8 @@ static void config_file_dump_all(config_file_t *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is no longer used, so comment out to silence warnings...
|
||||
#ifdef HAVE_MENU
|
||||
static void config_get_hex_base(config_file_t *conf,
|
||||
const char *key, unsigned *base)
|
||||
@ -2643,6 +2672,7 @@ static void config_get_hex_base(config_file_t *conf,
|
||||
*base = tmp;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
/**
|
||||
* config_load:
|
||||
@ -2718,11 +2748,11 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
|
||||
while (extra_path)
|
||||
{
|
||||
bool ret = config_append_file(conf, extra_path);
|
||||
bool result = config_append_file(conf, extra_path);
|
||||
|
||||
RARCH_LOG("Config: appending config \"%s\"\n", extra_path);
|
||||
|
||||
if (!ret)
|
||||
if (!result)
|
||||
RARCH_ERR("Config: failed to append config \"%s\"\n", extra_path);
|
||||
extra_path = strtok_r(NULL, "|", &save);
|
||||
}
|
||||
@ -2858,22 +2888,6 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
settings->floats.video_msg_color_g = ((msg_color >> 8) & 0xff) / 255.0f;
|
||||
settings->floats.video_msg_color_b = ((msg_color >> 0) & 0xff) / 255.0f;
|
||||
}
|
||||
#ifdef HAVE_MENU
|
||||
config_get_hex_base(conf, "menu_entry_normal_color",
|
||||
&settings->uints.menu_entry_normal_color);
|
||||
config_get_hex_base(conf, "menu_entry_hover_color",
|
||||
&settings->uints.menu_entry_hover_color);
|
||||
config_get_hex_base(conf, "menu_title_color",
|
||||
&settings->uints.menu_title_color);
|
||||
config_get_hex_base(conf, "menu_bg_dark_color",
|
||||
&settings->uints.menu_bg_dark_color);
|
||||
config_get_hex_base(conf, "menu_bg_light_color",
|
||||
&settings->uints.menu_bg_light_color);
|
||||
config_get_hex_base(conf, "menu_border_dark_color",
|
||||
&settings->uints.menu_border_dark_color);
|
||||
config_get_hex_base(conf, "menu_border_light_color",
|
||||
&settings->uints.menu_border_light_color);
|
||||
#endif
|
||||
|
||||
/* Float settings */
|
||||
for (i = 0; i < (unsigned)float_settings_size; i++)
|
||||
@ -3062,6 +3076,8 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
|
||||
if (string_is_equal(settings->paths.path_menu_wallpaper, "default"))
|
||||
*settings->paths.path_menu_wallpaper = '\0';
|
||||
if (string_is_equal(settings->paths.path_rgui_theme_preset, "default"))
|
||||
*settings->paths.path_rgui_theme_preset = '\0';
|
||||
if (string_is_equal(settings->paths.directory_video_shader, "default"))
|
||||
*settings->paths.directory_video_shader = '\0';
|
||||
if (string_is_equal(settings->paths.directory_video_filter, "default"))
|
||||
@ -4361,22 +4377,6 @@ bool config_save_file(const char *path)
|
||||
|
||||
/* Hexadecimal settings */
|
||||
config_set_hex(conf, "video_message_color", msg_color);
|
||||
#ifdef HAVE_MENU
|
||||
config_set_hex(conf, "menu_entry_normal_color",
|
||||
settings->uints.menu_entry_normal_color);
|
||||
config_set_hex(conf, "menu_entry_hover_color",
|
||||
settings->uints.menu_entry_hover_color);
|
||||
config_set_hex(conf, "menu_title_color",
|
||||
settings->uints.menu_title_color);
|
||||
config_set_hex(conf, "menu_bg_dark_color",
|
||||
settings->uints.menu_bg_dark_color);
|
||||
config_set_hex(conf, "menu_bg_light_color",
|
||||
settings->uints.menu_bg_light_color);
|
||||
config_set_hex(conf, "menu_border_dark_color",
|
||||
settings->uints.menu_border_dark_color);
|
||||
config_set_hex(conf, "menu_border_light_color",
|
||||
settings->uints.menu_border_light_color);
|
||||
#endif
|
||||
|
||||
video_driver_save_settings(conf);
|
||||
|
||||
@ -4734,7 +4734,7 @@ bool config_save_overrides(int override_type)
|
||||
/* Replaces currently loaded configuration file with
|
||||
* another one. Will load a dummy core to flush state
|
||||
* properly. */
|
||||
bool config_replace(bool config_save_on_exit, char *path)
|
||||
bool config_replace(bool config_replace_save_on_exit, char *path)
|
||||
{
|
||||
content_ctx_info_t content_info = {0};
|
||||
|
||||
@ -4746,7 +4746,7 @@ bool config_replace(bool config_save_on_exit, char *path)
|
||||
if (string_is_equal(path, path_get(RARCH_PATH_CONFIG)))
|
||||
return false;
|
||||
|
||||
if (config_save_on_exit && !path_is_empty(RARCH_PATH_CONFIG))
|
||||
if (config_replace_save_on_exit && !path_is_empty(RARCH_PATH_CONFIG))
|
||||
config_save_file(path_get(RARCH_PATH_CONFIG));
|
||||
|
||||
path_set(RARCH_PATH_CONFIG, path);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
* Copyright (C) 2014-2016 - Jean-André Santoni
|
||||
* Copyright (C) 2016 - Brad Parker
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
*
|
||||
* 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-
|
||||
@ -25,7 +25,7 @@
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "gfx/video_driver.h"
|
||||
#include "gfx/video_defines.h"
|
||||
#include "input/input_defines.h"
|
||||
#include "led/led_defines.h"
|
||||
|
||||
@ -110,6 +110,10 @@ typedef struct settings
|
||||
/* Audio */
|
||||
bool audio_enable;
|
||||
bool audio_enable_menu;
|
||||
bool audio_enable_menu_ok;
|
||||
bool audio_enable_menu_cancel;
|
||||
bool audio_enable_menu_notice;
|
||||
bool audio_enable_menu_bgm;
|
||||
bool audio_sync;
|
||||
bool audio_rate_control;
|
||||
bool audio_wasapi_exclusive_mode;
|
||||
@ -300,6 +304,7 @@ typedef struct settings
|
||||
bool video_window_save_positions;
|
||||
|
||||
bool sustained_performance_mode;
|
||||
bool playlist_use_old_format;
|
||||
} bools;
|
||||
|
||||
struct
|
||||
@ -402,14 +407,8 @@ typedef struct settings
|
||||
unsigned menu_timedate_style;
|
||||
unsigned menu_thumbnails;
|
||||
unsigned menu_left_thumbnails;
|
||||
unsigned menu_rgui_thumbnail_downscaler;
|
||||
unsigned menu_dpi_override_value;
|
||||
unsigned menu_entry_normal_color;
|
||||
unsigned menu_entry_hover_color;
|
||||
unsigned menu_title_color;
|
||||
unsigned menu_bg_dark_color;
|
||||
unsigned menu_bg_light_color;
|
||||
unsigned menu_border_dark_color;
|
||||
unsigned menu_border_light_color;
|
||||
unsigned menu_rgui_color_theme;
|
||||
unsigned menu_xmb_layout;
|
||||
unsigned menu_xmb_shader_pipeline;
|
||||
@ -541,6 +540,7 @@ typedef struct settings
|
||||
char path_cheat_settings[PATH_MAX_LENGTH];
|
||||
char path_shader[PATH_MAX_LENGTH];
|
||||
char path_font[PATH_MAX_LENGTH];
|
||||
char path_rgui_theme_preset[PATH_MAX_LENGTH];
|
||||
|
||||
char directory_audio_filter[PATH_MAX_LENGTH];
|
||||
char directory_autoconfig[PATH_MAX_LENGTH];
|
||||
|
6
configure
vendored
6
configure
vendored
@ -4,6 +4,8 @@ PACKAGE_NAME=retroarch
|
||||
|
||||
cat /dev/null > config.log
|
||||
|
||||
. qb/qb.init.sh
|
||||
|
||||
. qb/qb.system.sh
|
||||
|
||||
. qb/qb.params.sh
|
||||
@ -11,3 +13,7 @@ cat /dev/null > config.log
|
||||
. qb/qb.comp.sh
|
||||
|
||||
. qb/qb.libs.sh
|
||||
|
||||
. qb/qb.moc.sh
|
||||
|
||||
. qb/qb.make.sh
|
||||
|
@ -109,6 +109,9 @@ void content_set_subsystem_info(void);
|
||||
/* Get the path to the last selected subsystem rom */
|
||||
char* content_get_subsystem_rom(unsigned index);
|
||||
|
||||
/* Sets the subsystem by name */
|
||||
bool content_set_subsystem_by_name(const char* subsystem_name);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
2
core.h
2
core.h
@ -65,6 +65,8 @@ typedef struct rarch_system_info
|
||||
const char *input_desc_btn[MAX_USERS][RARCH_FIRST_META_KEY];
|
||||
char valid_extensions[255];
|
||||
|
||||
bool supports_vfs;
|
||||
|
||||
struct retro_disk_control_callback disk_control_cb;
|
||||
struct retro_location_callback location_cb;
|
||||
|
||||
|
26
core_info.c
26
core_info.c
@ -201,7 +201,7 @@ static bool core_info_list_iterate(
|
||||
if (!current_path)
|
||||
return false;
|
||||
|
||||
info_path_base = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
info_path_base = (char*)malloc(info_path_base_size);
|
||||
|
||||
info_path_base[0] = '\0';
|
||||
|
||||
@ -230,17 +230,15 @@ static bool core_info_list_iterate(
|
||||
static core_info_list_t *core_info_list_new(const char *path,
|
||||
const char *libretro_info_dir,
|
||||
const char *exts,
|
||||
bool show_hidden_files)
|
||||
bool dir_show_hidden_files)
|
||||
{
|
||||
size_t i;
|
||||
core_info_t *core_info = NULL;
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
const char *path_basedir = libretro_info_dir;
|
||||
struct string_list *contents = string_list_new();
|
||||
bool ok;
|
||||
|
||||
ok = dir_list_append(contents, path, exts,
|
||||
false, show_hidden_files, false, false);
|
||||
bool ok = dir_list_append(contents, path, exts,
|
||||
false, dir_show_hidden_files, false, false);
|
||||
|
||||
#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
/* UWP: browse the optional packages for additional cores */
|
||||
@ -249,7 +247,7 @@ static core_info_list_t *core_info_list_new(const char *path,
|
||||
for (i = 0; i < core_packages->size; i++)
|
||||
{
|
||||
dir_list_append(contents, core_packages->elems[i].data, exts,
|
||||
false, show_hidden_files, false, false);
|
||||
false, dir_show_hidden_files, false, false);
|
||||
}
|
||||
string_list_free(core_packages);
|
||||
#else
|
||||
@ -574,7 +572,11 @@ static bool core_info_list_update_missing_firmware_internal(
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
path = (char*)malloc(path_size);
|
||||
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
path[0] = '\0';
|
||||
|
||||
for (i = 0; i < info->firmware_count; i++)
|
||||
@ -676,12 +678,12 @@ void core_info_deinit_list(void)
|
||||
}
|
||||
|
||||
bool core_info_init_list(const char *path_info, const char *dir_cores,
|
||||
const char *exts, bool show_hidden_files)
|
||||
const char *exts, bool dir_show_hidden_files)
|
||||
{
|
||||
if (!(core_info_curr_list = core_info_list_new(dir_cores,
|
||||
!string_is_empty(path_info) ? path_info : dir_cores,
|
||||
exts,
|
||||
show_hidden_files)))
|
||||
dir_show_hidden_files)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -797,13 +799,13 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list,
|
||||
|
||||
void core_info_get_name(const char *path, char *s, size_t len,
|
||||
const char *path_info, const char *dir_cores,
|
||||
const char *exts, bool show_hidden_files)
|
||||
const char *exts, bool dir_show_hidden_files)
|
||||
{
|
||||
size_t i;
|
||||
const char *path_basedir = !string_is_empty(path_info) ?
|
||||
path_info : dir_cores;
|
||||
struct string_list *contents = dir_list_new(
|
||||
dir_cores, exts, false, show_hidden_files, false, false);
|
||||
dir_cores, exts, false, dir_show_hidden_files, false, false);
|
||||
if (!contents)
|
||||
return;
|
||||
|
||||
|
@ -223,4 +223,3 @@ void libretro_dummy_retro_cheat_set(unsigned idx,
|
||||
(void)enabled;
|
||||
(void)code;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ INTERNAL_LIBLAME = 0
|
||||
INTERNAL_LIBFAAC = 0
|
||||
INTERNAL_LIBSPEEX = 0
|
||||
INTERNAL_LIBTHEORA = 0
|
||||
INTERNAL_LIBOPUS = 0
|
||||
INTERNAL_LIBOPUS = 0
|
||||
INTERNAL_LIBVORBIS = 0
|
||||
INTERNAL_WEBP = 0
|
||||
INTERNAL_ZLIB = 0
|
||||
@ -226,4 +226,3 @@ clean:
|
||||
rm -f $(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -3,7 +3,7 @@ LIBAVFORMAT_SOURCE :=
|
||||
LIBAVUTIL_SOURCE :=
|
||||
DEPS_SOURCE :=
|
||||
DEFINES := -DHAVE_SWRESAMPLE
|
||||
LIBRETRO_SOURCE :=
|
||||
LIBRETRO_SOURCE :=
|
||||
GL_SOURCE :=
|
||||
|
||||
CPUOPTS :=
|
||||
|
@ -368,7 +368,7 @@ endif
|
||||
ifeq ($(HAVE_NVENC),1)
|
||||
DEFINES += -DCONFIG_NVENC_ENCODER=1 \
|
||||
-DCONFIG_NVENC_H264_ENCODER=1 \
|
||||
-DCONFIG_NVENC_HEVC_ENCODER=1
|
||||
-DCONFIG_NVENC_HEVC_ENCODER=1
|
||||
else
|
||||
DEFINES += -DCONFIG_NVENC_ENCODER=0 \
|
||||
-DCONFIG_NVENC_H264_ENCODER=0 \
|
||||
@ -424,7 +424,7 @@ endif
|
||||
ifeq ($(HAVE_ZLIB),1)
|
||||
DEFINES += -DCONFIG_ZLIB=1
|
||||
else
|
||||
DEFINES += -DCONFIG_ZLIB=0
|
||||
DEFINES += -DCONFIG_ZLIB=0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_LIBDCADEC),1)
|
||||
@ -1205,7 +1205,7 @@ DEFINES += \
|
||||
-DCONFIG_LIBZVBI_TELETEXT_DECODER=0 \
|
||||
-DCONFIG_BINTEXT_DECODER=1 \
|
||||
-DCONFIG_XBIN_DECODER=1 \
|
||||
-DCONFIG_IDF_DECODER=1
|
||||
-DCONFIG_IDF_DECODER=1
|
||||
|
||||
ifeq ($(HAVE_ZLIB),1)
|
||||
DEFINES += -DCONFIG_ZLIB_DECODER=1
|
||||
@ -1644,7 +1644,7 @@ ifeq ($(INTERNAL_LIBAVUTIL),1)
|
||||
AVCODEC_BLACKLIST += $(AVCODEC_DIR)/file_open.c
|
||||
endif
|
||||
|
||||
#Codec HW Acceleration flags - all disabled for now - not sure if
|
||||
#Codec HW Acceleration flags - all disabled for now - not sure if
|
||||
# libretro will ever support this
|
||||
|
||||
ifeq ($(HAVE_MMAL),1)
|
||||
|
@ -10,4 +10,3 @@ static const char *fragment_source = GLSL(
|
||||
gl_FragColor = vec4(pow(mix(pow(texture2D(sTex0, vTex).rgb, vec3(2.2)), pow(texture2D(sTex1, vTex).rgb, vec3(2.2)), uMix), vec3(1.0 / 2.2)), 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -9,4 +9,3 @@ static const char *vertex_source = GLSL(
|
||||
gl_Position = vec4(aVertex, 0.0, 1.0); vTex = aTexCoord;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -10,4 +10,3 @@ static const char *fragment_source = GLSL(
|
||||
gl_FragColor = vec4(pow(mix(pow(texture2D(sTex0, vTex).bgr, vec3(2.2)), pow(texture2D(sTex1, vTex).bgr, vec3(2.2)), uMix), vec3(1.0 / 2.2)), 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -2,4 +2,3 @@
|
||||
global: retro_*;
|
||||
local: *;
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
|
||||
#define WIDTH 356
|
||||
#define HEIGHT 200
|
||||
#define FPS (60000.0f / 1000.0f)
|
||||
|
||||
static retro_log_printf_t GONG_CORE_PREFIX(log_cb);
|
||||
static retro_video_refresh_t GONG_CORE_PREFIX(video_cb);
|
||||
@ -61,6 +60,7 @@ static bool is_initialized = 0;
|
||||
static unsigned player1_score = 0;
|
||||
static unsigned player2_score = 0;
|
||||
static float current_play_points = 0.0f;
|
||||
static float refresh = 60.0f;
|
||||
|
||||
static unsigned char *video_buf = NULL;
|
||||
|
||||
@ -84,7 +84,7 @@ typedef struct
|
||||
float last_dt;
|
||||
} Game_Input;
|
||||
|
||||
static Game_Input g_input = {0};
|
||||
static Game_Input g_input = {{{0}}};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -145,7 +145,7 @@ void GONG_CORE_PREFIX(retro_get_system_av_info)(struct retro_system_av_info *inf
|
||||
info->geometry.max_width = WIDTH;
|
||||
info->geometry.max_height = HEIGHT;
|
||||
info->geometry.aspect_ratio = 16.0f / 9.0f;
|
||||
info->timing.fps = FPS;
|
||||
info->timing.fps = refresh;
|
||||
info->timing.sample_rate = 44100.0;
|
||||
}
|
||||
|
||||
@ -164,8 +164,6 @@ void GONG_CORE_PREFIX(retro_init)(void)
|
||||
game_buffer.height = HEIGHT;
|
||||
game_buffer.pitch = WIDTH * sizeof(unsigned);
|
||||
game_buffer.memory = video_buf;
|
||||
|
||||
g_input.last_dt = 1.0f / FPS;
|
||||
}
|
||||
|
||||
void GONG_CORE_PREFIX(retro_deinit)(void)
|
||||
@ -182,6 +180,7 @@ void GONG_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
|
||||
bool no_content = true;
|
||||
|
||||
static const struct retro_variable vars[] = {
|
||||
{ "gong_refresh", "Video Refresh Rate (restart); 60|75|100|120" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
@ -192,6 +191,19 @@ void GONG_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
|
||||
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
|
||||
}
|
||||
|
||||
static void check_variables(void)
|
||||
{
|
||||
struct retro_variable var = {0};
|
||||
|
||||
var.key = "gong_refresh";
|
||||
|
||||
if (GONG_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
refresh = atoi(var.value);
|
||||
g_input.last_dt = 1.0f / refresh;
|
||||
}
|
||||
}
|
||||
|
||||
void GONG_CORE_PREFIX(retro_set_video_refresh)(retro_video_refresh_t cb)
|
||||
{
|
||||
GONG_CORE_PREFIX(video_cb) = cb;
|
||||
@ -264,6 +276,8 @@ bool GONG_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
|
||||
{
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
|
||||
check_variables();
|
||||
|
||||
if (!GONG_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
if (GONG_CORE_PREFIX(log_cb))
|
||||
@ -324,6 +338,10 @@ void GONG_CORE_PREFIX(retro_run)(void)
|
||||
int i = 0;
|
||||
int16_t analogYLeft1 = 0;
|
||||
int16_t analogYRight1 = 0;
|
||||
bool updated = false;
|
||||
|
||||
if (GONG_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
check_variables();
|
||||
|
||||
GONG_CORE_PREFIX(input_poll_cb)();
|
||||
|
||||
@ -460,7 +478,7 @@ static void draw_number(Game_Offscreen_Buffer *buffer, unsigned number, unsigned
|
||||
draw_rect(buffer, color, at_x + 2.f, y, .5f, 4.5f);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
{
|
||||
draw_rect(buffer, color, at_x - 2.f, y - 2.f, .5f, 2.f);
|
||||
@ -470,7 +488,7 @@ static void draw_number(Game_Offscreen_Buffer *buffer, unsigned number, unsigned
|
||||
draw_rect(buffer, color, at_x, y - 4.f, 2.5f, .5f);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 3:
|
||||
{
|
||||
draw_rect(buffer, color, at_x + 2.f, y, .5f, 4.f);
|
||||
@ -565,7 +583,7 @@ static void game_update_and_render(Game_Input *input, Game_Offscreen_Buffer *dra
|
||||
{
|
||||
float speed = 80.f;
|
||||
player1_dpy = 0.f;
|
||||
|
||||
|
||||
if (is_down(input->buttons[B_SPEED_UP]))
|
||||
speed = 150.f;
|
||||
|
||||
|
@ -2,4 +2,3 @@
|
||||
global: retro_*;
|
||||
local: *;
|
||||
};
|
||||
|
||||
|
@ -166,7 +166,7 @@ void IMAGE_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
|
||||
IMAGE_CORE_PREFIX(environ_cb) = cb;
|
||||
|
||||
cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
|
||||
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
/* I don't trust filestream_vfs_init to work inside rarch */
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VFS_INTERFACE, &vfs_iface_info))
|
||||
@ -254,7 +254,7 @@ static bool imageviewer_load(const char *path, int image_index)
|
||||
buf = malloc(len);
|
||||
filestream_read(f, buf, len);
|
||||
filestream_close(f);
|
||||
|
||||
|
||||
image_buffer = (uint32_t*)stbi_load_from_memory(
|
||||
buf, len,
|
||||
&image_width, &image_height,
|
||||
|
@ -145,4 +145,3 @@ clean:
|
||||
rm -f $(OBJECTS) $(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -21,5 +21,4 @@ endif
|
||||
LOCAL_SRC_FILES += ../libretro-test.c
|
||||
LOCAL_CFLAGS += -O3 -std=gnu99 -ffast-math -funroll-loops
|
||||
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
@ -2,4 +2,3 @@
|
||||
global: retro_*;
|
||||
local: *;
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ TARGET_NAME := video_processor
|
||||
LIBV4L2 = -lv4l2
|
||||
|
||||
ifneq ($(findstring Linux,$(shell uname -a)),)
|
||||
CFLAGS += -DHAVE_UDEV
|
||||
CFLAGS += -DHAVE_UDEV
|
||||
LIBUDEV = -ludev
|
||||
CFLAGS += -DHAVE_ALSA
|
||||
LIBASOUND = -lasound
|
||||
@ -144,4 +144,3 @@ clean:
|
||||
rm -f $(OBJECTS) $(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
@ -3,7 +3,6 @@ Libretro core for V4L2 capture devices
|
||||
|
||||
The basic idea is this -- plug your legacy console into a capture device and use RetroArch to upscale it and apply shaders to taste.
|
||||
|
||||
|
||||
## Raspberry Pi specific config
|
||||
|
||||
Add to /boot/config.txt:
|
||||
|
@ -2,4 +2,3 @@
|
||||
global: retro_*;
|
||||
local: *;
|
||||
};
|
||||
|
||||
|
@ -86,7 +86,7 @@ static struct v4l2_capbuf v4l2_capbuf[VIDEO_BUFFERS_MAX];
|
||||
|
||||
static float dummy_pos=0;
|
||||
|
||||
static int video_half_feed_rate=0; // for interlaced captures
|
||||
static int video_half_feed_rate=0; /* for interlaced captures */
|
||||
static uint32_t video_cap_width;
|
||||
static uint32_t video_cap_height;
|
||||
static uint32_t video_out_height;
|
||||
@ -102,7 +102,7 @@ static uint32_t *frame_prev2;
|
||||
static uint32_t *frame_prev3;
|
||||
static uint32_t *frame_curr;
|
||||
|
||||
// Frametime debug messages
|
||||
/* Frametime debug messages */
|
||||
struct timeval ft_prevtime = { 0 }, ft_prevtime2 = { 0 };
|
||||
char *ft_info = NULL, *ft_info2 = NULL;
|
||||
double ft_favg, ft_ftime;
|
||||
@ -282,17 +282,17 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_set_environment)(retro_environment_t
|
||||
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb) = cb;
|
||||
|
||||
// Allows retroarch to seed the previous values
|
||||
/* Allows retroarch to seed the previous values */
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_SET_VARIABLES, envvars);
|
||||
|
||||
// Enumerate all real devices
|
||||
/* Enumerate all real devices */
|
||||
enumerate_video_devices(video_devices, sizeof(video_devices));
|
||||
enumerate_audio_devices(audio_devices, sizeof(audio_devices));
|
||||
|
||||
// Add the dummy device
|
||||
/* Add the dummy device */
|
||||
appendstr(video_devices, "|dummy", ENVVAR_BUFLEN);
|
||||
|
||||
// Registers available devices list (still respects saved device if it exists)
|
||||
/* Registers available devices list (still respects saved device if it exists) */
|
||||
envvars[0].key = "videoproc_videodev";
|
||||
envvars[0].value = video_devices;
|
||||
envvars[1].key = "videoproc_audiodev";
|
||||
@ -503,7 +503,7 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_av_info)(struct retro_syst
|
||||
if (strcmp(videodev.value, "dummy") == 0) {
|
||||
info->geometry.aspect_ratio = 4.0/3.0;
|
||||
info->geometry.base_width = info->geometry.max_width = video_cap_width;
|
||||
info->geometry.base_height = video_cap_height; //out?
|
||||
info->geometry.base_height = video_cap_height; /* out? */
|
||||
info->geometry.max_height = video_out_height;
|
||||
info->timing.fps = 60;
|
||||
info->timing.sample_rate = AUDIO_SAMPLE_RATE;
|
||||
@ -517,16 +517,17 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_av_info)(struct retro_syst
|
||||
|
||||
info->geometry.base_width = info->geometry.max_width = video_format.fmt.pix.width;
|
||||
info->geometry.base_height = video_format.fmt.pix.height;
|
||||
//TODO Only double if frames are NOT fields (interlaced, full resolution)
|
||||
/* TODO Only double if frames are NOT fields (interlaced, full resolution) */
|
||||
info->geometry.max_height = video_format.fmt.pix.height * 2;
|
||||
//TODO Only double if frames ARE fields (progressive or deinterlaced, full framerate)
|
||||
// *2 for fields
|
||||
/* TODO Only double if frames ARE fields (progressive or deinterlaced, full framerate)
|
||||
* *2 for fields
|
||||
*/
|
||||
info->timing.fps = ((double)(video_standard.frameperiod.denominator*2)) /
|
||||
(double)video_standard.frameperiod.numerator;
|
||||
info->timing.sample_rate = AUDIO_SAMPLE_RATE;
|
||||
|
||||
if (error == 0) {
|
||||
//TODO Allow for fixed 4:3 and 16:9 modes
|
||||
/* TODO Allow for fixed 4:3 and 16:9 modes */
|
||||
info->geometry.aspect_ratio = (double)info->geometry.base_width / (double)info->geometry.max_height /\
|
||||
((double)cc.pixelaspect.numerator / (double)cc.pixelaspect.denominator);
|
||||
}
|
||||
@ -535,7 +536,7 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_av_info)(struct retro_syst
|
||||
printf("Aspect ratio: %f\n",info->geometry.aspect_ratio);
|
||||
printf("Buffer Resolution %ux%u %f fps\n", info->geometry.base_width,
|
||||
info->geometry.base_height, info->timing.fps);
|
||||
printf("Buffer Max Resolution %ux%u\n", info->geometry.max_width,
|
||||
printf("Buffer Max Resolution %ux%u\n", info->geometry.max_width,
|
||||
info->geometry.max_height);
|
||||
}
|
||||
|
||||
@ -549,10 +550,10 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_reset)(void)
|
||||
open_devices();
|
||||
}
|
||||
|
||||
//TODO improve this mess and make it generic enough for use with dummy mode
|
||||
/* TODO improve this mess and make it generic enough for use with dummy mode */
|
||||
void v4l2_frame_times(struct v4l2_buffer buf) {
|
||||
if (strcmp("Off", video_frame_times) == 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ft_info == NULL)
|
||||
ft_info = calloc(5000, sizeof(char));
|
||||
@ -593,7 +594,8 @@ void source_dummy(int width, int height) {
|
||||
}
|
||||
|
||||
dummy_pos += step;
|
||||
//dummy_pos = M_PI/4; step = 0; // no animation
|
||||
/* no animation */
|
||||
/* dummy_pos = M_PI/4; step = 0; */
|
||||
triangpos = (sinf(dummy_pos)+1)/2*width;
|
||||
if (video_buf.field == V4L2_FIELD_INTERLACED) {
|
||||
if (video_half_feed_rate == 0)
|
||||
@ -609,9 +611,9 @@ void source_dummy(int width, int height) {
|
||||
src[1] = 0x10 + color*0xE0;
|
||||
src[2] = 0x10 + color*0xE0;
|
||||
|
||||
// End of a line
|
||||
/* End of a line */
|
||||
if ( ((i+1) % width) == 0 ) {
|
||||
triangpos -= 2; //offset should be half of this?
|
||||
triangpos -= 2; /* offset should be half of this? */
|
||||
triangpos_t -= 1;
|
||||
triangpos_b -= 1;
|
||||
if (video_buf.field == V4L2_FIELD_INTERLACED) {
|
||||
@ -626,18 +628,18 @@ void source_dummy(int width, int height) {
|
||||
}
|
||||
}
|
||||
|
||||
if(video_buf.field == V4L2_FIELD_TOP)
|
||||
if(video_buf.field == V4L2_FIELD_TOP)
|
||||
video_buf.field = V4L2_FIELD_BOTTOM;
|
||||
else if (video_buf.field == V4L2_FIELD_BOTTOM)
|
||||
else if (video_buf.field == V4L2_FIELD_BOTTOM)
|
||||
video_buf.field = V4L2_FIELD_TOP;
|
||||
}
|
||||
|
||||
void source_v4l2_normal(int width, int height) {
|
||||
struct v4l2_buffer bufcp;
|
||||
|
||||
|
||||
int error;
|
||||
|
||||
// Wait until v4l2 dequees a buffer
|
||||
/* Wait until v4l2 dequees a buffer */
|
||||
memset(&video_buf, 0, sizeof(struct v4l2_buffer));
|
||||
video_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
video_buf.memory = V4L2_MEMORY_MMAP;
|
||||
@ -651,7 +653,7 @@ void source_v4l2_normal(int width, int height) {
|
||||
|
||||
bufcp = video_buf;
|
||||
memcpy( (uint32_t*) frame_cap, (uint8_t*) v4l2_capbuf[video_buf.index].start, video_format.fmt.pix.width * video_format.fmt.pix.height * 3);
|
||||
|
||||
|
||||
error = v4l2_ioctl(video_device_fd, VIDIOC_QBUF, &video_buf);
|
||||
if (error != 0)
|
||||
printf("VIDIOC_QBUF failed: %s\n", strerror(errno));
|
||||
@ -664,11 +666,11 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
struct v4l2_format fmt;
|
||||
struct v4l2_requestbuffers reqbufs;
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
|
||||
int error;
|
||||
uint32_t index;
|
||||
|
||||
// For later, saving time
|
||||
/* For later, saving time */
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
error = v4l2_ioctl(video_device_fd, VIDIOC_G_FMT, &fmt);
|
||||
@ -677,7 +679,7 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
printf("VIDIOC_G_FMT failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
// Wait until v4l2 dequees a buffer
|
||||
/* Wait until v4l2 dequees a buffer */
|
||||
memset(&video_buf, 0, sizeof(struct v4l2_buffer));
|
||||
video_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
video_buf.memory = V4L2_MEMORY_MMAP;
|
||||
@ -692,7 +694,7 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
v4l2_ioctl(video_device_fd, VIDIOC_STREAMOFF, &type);
|
||||
|
||||
//Let's get the data as fast as possible!
|
||||
/* Let's get the data as fast as possible! */
|
||||
bufcp = video_buf;
|
||||
memcpy( (uint32_t*) frame_cap, (uint8_t*) v4l2_capbuf[video_buf.index].start, video_format.fmt.pix.width * video_format.fmt.pix.height * 3);
|
||||
|
||||
@ -722,7 +724,7 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
printf("VIDIOC_REQBUFS failed: %s\n", strerror(errno));
|
||||
}
|
||||
v4l2_ncapbuf = reqbufs.count;
|
||||
//printf("GOT v4l2_ncapbuf=%ld\n", v4l2_ncapbuf);
|
||||
/* printf("GOT v4l2_ncapbuf=%ld\n", v4l2_ncapbuf); */
|
||||
|
||||
index = 0;
|
||||
memset(&video_buf, 0, sizeof(struct v4l2_buffer));
|
||||
@ -742,9 +744,11 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
|
||||
v4l2_ioctl(video_device_fd, VIDIOC_QBUF,& video_buf);
|
||||
|
||||
//error = v4l2_ioctl(video_device_fd, VIDIOC_QBUF, &video_buf);
|
||||
//if (error != 0)
|
||||
// printf("VIDIOC_QBUF failed: %s\n", strerror(errno));
|
||||
#if 0
|
||||
error = v4l2_ioctl(video_device_fd, VIDIOC_QBUF, &video_buf);
|
||||
if (error != 0)
|
||||
printf("VIDIOC_QBUF failed: %s\n", strerror(errno));
|
||||
#endif
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
error = v4l2_ioctl(video_device_fd, VIDIOC_STREAMON, &type);
|
||||
@ -758,10 +762,12 @@ void source_v4l2_alternate_hack(int width, int height) {
|
||||
|
||||
void processing_heal(uint8_t *src, int width, int height) {
|
||||
uint32_t *fp1 = frame_prev1;
|
||||
for (int i = 0; i < width * height; i+=1, src += 3, ++fp1) {
|
||||
// Tries to filter a bunch of blanked out scanline sections my capture cards spits out with this crazy hack
|
||||
// Since the blanked out scanlines are set to a black value bellow anything that can be captued, it's quite
|
||||
//easy to select the scanlines...
|
||||
int i;
|
||||
for (i = 0; i < width * height; i+=1, src += 3, ++fp1) {
|
||||
/* Tries to filter a bunch of blanked out scanline sections my capture cards spits out with this crazy hack
|
||||
* Since the blanked out scanlines are set to a black value bellow anything that can be captued, it's quite
|
||||
* easy to select the scanlines...
|
||||
*/
|
||||
if (src[0] <= 0 && src[1] <= 0 && src[2] <= 0 && i >= width && i <= width * height - width) {
|
||||
if (*(src + 0 - width*3) >= ((*fp1>> 0&0xFF)-6) && \
|
||||
*(src + 1 - width*3) >= ((*fp1>> 8&0xFF)-6) && \
|
||||
@ -786,15 +792,16 @@ void processing_deinterlacing_crap(uint32_t *src, uint32_t *dst, int width, int
|
||||
uint32_t pixacul=0;
|
||||
uint32_t *fp1 = frame_prev1, *fp2 = frame_prev2, *fp3 = frame_prev3;
|
||||
|
||||
// Helps pointing to the pixel in the adjacent row
|
||||
/* Helps pointing to the pixel in the adjacent row */
|
||||
if (field == V4L2_FIELD_TOP)
|
||||
targetrow = width;
|
||||
else
|
||||
targetrow = width*-1;
|
||||
|
||||
// Starts from the even scanline if frame contains bottom fields
|
||||
//On progressive sources, should only skip the destination lines, since all lines the source are the same fields
|
||||
//On interlaced sources, should skip both the source and the destination lines, since only half the lines in the source are the same fields (must also skip fields later)
|
||||
/* Starts from the even scanline if frame contains bottom fields
|
||||
* On progressive sources, should only skip the destination lines, since all lines the source are the same fields
|
||||
* On interlaced sources, should skip both the source and the destination lines, since only half the lines in the source are the same fields (must also skip fields later)
|
||||
*/
|
||||
if (field == V4L2_FIELD_BOTTOM) {
|
||||
dst += width;
|
||||
if (skip_lines_src == 1) {
|
||||
@ -806,13 +813,14 @@ void processing_deinterlacing_crap(uint32_t *src, uint32_t *dst, int width, int
|
||||
}
|
||||
|
||||
for (i = 0; i < width * height; i+=1, src += 1, dst += 1, ++fp1, ++fp2, ++fp3) {
|
||||
// Will fill the current destination line with current field
|
||||
//The masking is used to prserve some information set by the
|
||||
//deinterlacing process, uses the alpha channel to tell if a
|
||||
//pixel needs further processing...
|
||||
/* Will fill the current destination line with current field
|
||||
* The masking is used to prserve some information set by the
|
||||
* deinterlacing process, uses the alpha channel to tell if a
|
||||
* pixel needs further processing...
|
||||
*/
|
||||
*(dst) = (*(src) & 0x00FFFFFF) | (*dst & 0xFF000000);
|
||||
|
||||
// Crappy deinterlacing
|
||||
/* Crappy deinterlacing */
|
||||
if (i >= width && i <= (width*height-width)) {
|
||||
pixacul=((((*(dst)>> 0&0xFF) + (pixacul>> 0&0xFF))>>1<<0 |\
|
||||
((*(dst)>> 8&0xFF) + (pixacul>> 8&0xFF))>>1<<8 |\
|
||||
@ -842,9 +850,10 @@ void processing_deinterlacing_crap(uint32_t *src, uint32_t *dst, int width, int
|
||||
}
|
||||
}
|
||||
|
||||
// Skips a scanline if we reach the end of the current one
|
||||
//On progressive sources, should only skip the destination lines,
|
||||
//On interlaced sources, should skip both the source and the destination lines
|
||||
/* Skips a scanline if we reach the end of the current one
|
||||
* On progressive sources, should only skip the destination lines,
|
||||
* On interlaced sources, should skip both the source and the destination lines
|
||||
*/
|
||||
if ( ((i+1) % width) == 0 ) {
|
||||
dst += width;
|
||||
if (skip_lines_src == 1) {
|
||||
@ -859,7 +868,8 @@ void processing_deinterlacing_crap(uint32_t *src, uint32_t *dst, int width, int
|
||||
|
||||
void processing_bgr_xrgb(uint8_t *src, uint32_t *dst, int width, int height) {
|
||||
/* BGR24 to XRGB8888 conversion */
|
||||
for (int i = 0; i < width * height; i+=1, src += 3, dst += 1) {
|
||||
int i;
|
||||
for (i = 0; i < width * height; i+=1, src += 3, dst += 1) {
|
||||
*dst = 0xFF << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
|
||||
}
|
||||
}
|
||||
@ -880,15 +890,16 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_run)(void)
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &capturemode);
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &outputmode);
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &frametimes);
|
||||
// Video or Audio device(s) has(ve) been changed
|
||||
//TODO We may get away without reseting devices when changing output mode...
|
||||
/* Video or Audio device(s) has(ve) been changed
|
||||
* TODO We may get away without reseting devices when changing output mode...
|
||||
*/
|
||||
if ((videodev.value && (strcmp(video_device, videodev.value) != 0)) ||\
|
||||
(audiodev.value && (strcmp(audio_device, audiodev.value) != 0)) ||\
|
||||
(capturemode.value && (strcmp(video_capture_mode, capturemode.value) != 0)) ||\
|
||||
(outputmode.value && (strcmp(video_output_mode, outputmode.value) != 0))) {
|
||||
VIDEOPROC_CORE_PREFIX(retro_unload_game)();
|
||||
// This core does not cares for the retro_game_info * argument?
|
||||
VIDEOPROC_CORE_PREFIX(retro_load_game)(NULL);
|
||||
/* This core does not cares for the retro_game_info * argument? */
|
||||
VIDEOPROC_CORE_PREFIX(retro_load_game)(NULL);
|
||||
}
|
||||
|
||||
if (frametimes.value != NULL) {
|
||||
@ -898,12 +909,13 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_run)(void)
|
||||
|
||||
VIDEOPROC_CORE_PREFIX(input_poll_cb)();
|
||||
|
||||
//printf("%d %d %d %s\n", video_cap_width, video_cap_height, video_buf.field, video_output_mode);
|
||||
//TODO pass frame_curr to source_* functions
|
||||
//half_feed_rate allows interlaced intput to be fed at half the calls to this function
|
||||
//where the same frame is then read by the deinterlacer twice, for each field
|
||||
/* printf("%d %d %d %s\n", video_cap_width, video_cap_height, video_buf.field, video_output_mode);
|
||||
* TODO pass frame_curr to source_* functions
|
||||
* half_feed_rate allows interlaced intput to be fed at half the calls to this function
|
||||
* where the same frame is then read by the deinterlacer twice, for each field
|
||||
*/
|
||||
if (video_half_feed_rate == 0) {
|
||||
// Capture
|
||||
/* Capture */
|
||||
if (strcmp(video_device, "dummy") == 0) {
|
||||
source_dummy(video_cap_width, video_cap_height);
|
||||
} else {
|
||||
@ -915,28 +927,31 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_run)(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (video_buf.field == V4L2_FIELD_INTERLACED)
|
||||
if (video_buf.field == V4L2_FIELD_INTERLACED)
|
||||
video_half_feed_rate = 1;
|
||||
} else {
|
||||
video_half_feed_rate = 0;
|
||||
}
|
||||
|
||||
// Converts from bgr to xrgb, deinterlacing, final copy to the outpuit buffer (frame_out)
|
||||
//Every frame except frame_cap shall be encoded in xrgb
|
||||
//Every frame except frame_out shall have the same height
|
||||
/* Converts from bgr to xrgb, deinterlacing, final copy to the outpuit buffer (frame_out)
|
||||
* Every frame except frame_cap shall be encoded in xrgb
|
||||
* Every frame except frame_out shall have the same height
|
||||
*/
|
||||
if (strcmp(video_output_mode, "deinterlaced") == 0) {
|
||||
processing_bgr_xrgb(frame_cap, frame_curr, video_cap_width, video_cap_height);
|
||||
// When deinterlacing a interlaced intput, we need to process both fields of a frame,
|
||||
//one at a time (retro_run needs to be called twice, vide_half_feed_rate prevents the
|
||||
//source from being read twice...
|
||||
/* When deinterlacing a interlaced intput, we need to process both fields of a frame,
|
||||
* one at a time (retro_run needs to be called twice, vide_half_feed_rate prevents the
|
||||
* source from being read twice...
|
||||
*/
|
||||
if (strcmp(video_capture_mode, "interlaced") == 0) {
|
||||
enum v4l2_field field_read;
|
||||
if (video_half_feed_rate == 0)
|
||||
field_read = V4L2_FIELD_TOP;
|
||||
else
|
||||
field_read = V4L2_FIELD_BOTTOM;
|
||||
//video_half_feed_rate will allow us to capture the interlaced frame once and run the
|
||||
//deinterlacing algo twice, extracting a given field for each run.
|
||||
/* video_half_feed_rate will allow us to capture the interlaced frame once and run the
|
||||
* deinterlacing algo twice, extracting a given field for each run.
|
||||
*/
|
||||
processing_deinterlacing_crap(frame_curr, frame_out, video_cap_width, video_cap_height/2, field_read, 1);
|
||||
} else {
|
||||
processing_deinterlacing_crap(frame_curr, frame_out, video_cap_width, video_cap_height, video_buf.field, 0);
|
||||
@ -950,7 +965,7 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_run)(void)
|
||||
VIDEOPROC_CORE_PREFIX(video_refresh_cb)(frame_out, video_cap_width,
|
||||
video_out_height, video_cap_width * sizeof(uint32_t));
|
||||
} else if (strcmp(video_capture_mode, "alternate_hack") == 0) {
|
||||
// Case where alternate_hack without deinterlacing would not generate previous frame for processing_heal
|
||||
/* Case where alternate_hack without deinterlacing would not generate previous frame for processing_heal */
|
||||
processing_bgr_xrgb(frame_cap, frame_curr, video_cap_width, video_cap_height);
|
||||
aux = frame_prev3;
|
||||
frame_prev3 = frame_prev2;
|
||||
@ -998,15 +1013,17 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_cheat_set)(unsigned index, bool enabl
|
||||
|
||||
static void videoinput_set_control_v4l2( uint32_t id, double val )
|
||||
{
|
||||
//struct v4l2_queryctrl query;
|
||||
#if 0
|
||||
struct v4l2_queryctrl query;
|
||||
|
||||
//query.id = id;
|
||||
//if( ioctl( video_device_fd, VIDIOC_QUERYCTRL, &query ) >= 0 && !(query.flags & V4L2_CTRL_FLAG_DISABLED) ) {
|
||||
// struct v4l2_control control;
|
||||
// control.id = id;
|
||||
// control.value = query.minimum + ((int) ((val * ((double) (query.maximum - query.minimum))) + 0.5));
|
||||
// ioctl( video_device_fd, VIDIOC_S_CTRL, &control );
|
||||
//}
|
||||
query.id = id;
|
||||
if( ioctl( video_device_fd, VIDIOC_QUERYCTRL, &query ) >= 0 && !(query.flags & V4L2_CTRL_FLAG_DISABLED) ) {
|
||||
struct v4l2_control control;
|
||||
control.id = id;
|
||||
control.value = query.minimum + ((int) ((val * ((double) (query.maximum - query.minimum))) + 0.5));
|
||||
ioctl( video_device_fd, VIDIOC_S_CTRL, &control );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_info *game)
|
||||
@ -1050,7 +1067,7 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
}
|
||||
strncpy(video_device, videodev.value, ENVVAR_BUFLEN-1);
|
||||
|
||||
// Audio device is optional...
|
||||
/* Audio device is optional... */
|
||||
VIDEOPROC_CORE_PREFIX(environment_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &audiodev);
|
||||
if (audiodev.value != NULL) {
|
||||
strncpy(audio_device, audiodev.value, ENVVAR_BUFLEN-1);
|
||||
@ -1106,8 +1123,8 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
|
||||
fmt.fmt.pix.height = 240;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_TOP;
|
||||
|
||||
//TODO Query the size and FPS
|
||||
|
||||
/* TODO Query the size and FPS */
|
||||
if (strcmp(video_capture_mode, "interlaced") == 0) {
|
||||
v4l2_ncapbuf_target = 2;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
@ -1166,7 +1183,7 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
}
|
||||
|
||||
video_format = fmt;
|
||||
//TODO Check if what we got is indeed what we asked for
|
||||
/* TODO Check if what we got is indeed what we asked for */
|
||||
|
||||
memset(&reqbufs, 0, sizeof(reqbufs));
|
||||
reqbufs.count = v4l2_ncapbuf_target;
|
||||
@ -1229,11 +1246,12 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
return false;
|
||||
}
|
||||
|
||||
//videoinput_set_control_v4l2(V4L2_CID_HUE, (double) 0.4f);
|
||||
/* videoinput_set_control_v4l2(V4L2_CID_HUE, (double) 0.4f); */
|
||||
}
|
||||
|
||||
//TODO Framerates?
|
||||
// Each frame should combine both fields into a full frame (if not already captured interlaced), half frame-rate
|
||||
/* TODO Framerates?
|
||||
* Each frame should combine both fields into a full frame (if not already captured interlaced), half frame-rate
|
||||
*/
|
||||
if (strcmp(video_output_mode, "interlaced") == 0) {
|
||||
if (strcmp(video_capture_mode, "interlaced") == 0) {
|
||||
video_out_height = video_cap_height;
|
||||
@ -1242,24 +1260,24 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
video_capture_mode, video_output_mode);
|
||||
video_out_height = video_cap_height*2;
|
||||
}
|
||||
// Each frame has one field, full frame-rate
|
||||
/* Each frame has one field, full frame-rate */
|
||||
} else if (strcmp(video_output_mode, "progressive") == 0) {
|
||||
video_out_height = video_cap_height;
|
||||
// Each frame has one or both field to be deinterlaced into a full frame (double the lines if one field), full frame-rate
|
||||
video_out_height = video_cap_height;
|
||||
/* Each frame has one or both field to be deinterlaced into a full frame (double the lines if one field), full frame-rate */
|
||||
} else if (strcmp(video_output_mode, "deinterlaced") == 0) {
|
||||
if (strcmp(video_capture_mode, "interlaced") == 0)
|
||||
video_out_height = video_cap_height;
|
||||
else
|
||||
video_out_height = video_cap_height*2;
|
||||
} else
|
||||
video_out_height = video_cap_height;
|
||||
video_out_height = video_cap_height;
|
||||
|
||||
printf("Capture Resolution %ux%u\n", video_cap_width, video_cap_height);
|
||||
printf("Output Resolution %ux%u\n", video_cap_width, video_out_height);
|
||||
|
||||
frame_cap = calloc(1, video_cap_width * video_cap_height * sizeof(uint8_t) * 3);
|
||||
frame_out = calloc(1, video_cap_width * video_out_height * sizeof(uint32_t));
|
||||
//TODO: Only allocate frames if we are going to use it (for deinterlacing or other filters?)
|
||||
/* TODO: Only allocate frames if we are going to use it (for deinterlacing or other filters?) */
|
||||
frames[0] = calloc(1, video_cap_width * video_out_height * sizeof(uint32_t));
|
||||
frames[1] = calloc(1, video_cap_width * video_out_height * sizeof(uint32_t));
|
||||
frames[2] = calloc(1, video_cap_width * video_out_height * sizeof(uint32_t));
|
||||
@ -1270,7 +1288,7 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
frame_prev2 = frames[2];
|
||||
frame_prev3 = frames[3];
|
||||
|
||||
//TODO: Check frames[] allocation
|
||||
/* TODO: Check frames[] allocation */
|
||||
if (!frame_out || !frame_cap)
|
||||
{
|
||||
printf("Cannot allocate buffers\n");
|
||||
@ -1293,6 +1311,7 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in
|
||||
RETRO_API void VIDEOPROC_CORE_PREFIX(retro_unload_game)(void)
|
||||
{
|
||||
struct v4l2_requestbuffers reqbufs;
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
if (audio_handle != NULL) {
|
||||
@ -1328,7 +1347,7 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_unload_game)(void)
|
||||
free(frame_cap);
|
||||
frame_cap = NULL;
|
||||
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (i = 0; i<4; ++i) {
|
||||
if (frames[i])
|
||||
free(frames[i]);
|
||||
frames[i] = NULL;
|
||||
|
@ -5,4 +5,3 @@
|
||||
|
||||
*startfile:
|
||||
ctr/3dsx_custom_crt0%O%s crti%O%s crtbegin%O%s
|
||||
|
||||
|
@ -72,4 +72,3 @@ ClrLoop:
|
||||
bne ClrLoop
|
||||
|
||||
bx lr
|
||||
|
||||
|
@ -308,4 +308,3 @@ long sysconf(int name)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -12,18 +12,18 @@ extern const loaderFuncs_s loader_Rosalina;
|
||||
static void (*launch_3dsx)(const char* path, argData_s* args, executableMetadata_s* em);
|
||||
|
||||
static int exec_3dsx_actual(const char* path, const char** args, bool appendPath){
|
||||
struct stat sBuff;
|
||||
struct stat sBuff;
|
||||
argData_s newProgramArgs;
|
||||
unsigned int argChars = 0;
|
||||
unsigned int argNum = 0;
|
||||
bool fileExists;
|
||||
bool inited;
|
||||
|
||||
|
||||
if(path == NULL || path[0] == '\0'){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fileExists = stat(path, &sBuff) == 0;
|
||||
if(!fileExists){
|
||||
errno = ENOENT;
|
||||
@ -41,7 +41,7 @@ static int exec_3dsx_actual(const char* path, const char** args, bool appendPath
|
||||
strcpy(newProgramArgs.dst, path);
|
||||
newProgramArgs.dst += strlen(path) + 1;
|
||||
newProgramArgs.buf[0]++;
|
||||
|
||||
|
||||
}
|
||||
while(args[argNum] != NULL){
|
||||
strcpy(newProgramArgs.dst, args[argNum]);
|
||||
@ -49,10 +49,10 @@ static int exec_3dsx_actual(const char* path, const char** args, bool appendPath
|
||||
newProgramArgs.buf[0]++;
|
||||
argNum++;
|
||||
}
|
||||
|
||||
|
||||
inited = loader_Rosalina.init();
|
||||
launch_3dsx = loader_Rosalina.launchFile;
|
||||
|
||||
|
||||
if(!inited){
|
||||
inited = loader_Ninjhax2.init();
|
||||
launch_3dsx = loader_Ninjhax2.launchFile;
|
||||
@ -62,13 +62,13 @@ static int exec_3dsx_actual(const char* path, const char** args, bool appendPath
|
||||
inited = loader_Ninjhax1.init();
|
||||
launch_3dsx = loader_Ninjhax1.launchFile;
|
||||
}
|
||||
|
||||
|
||||
if(inited){
|
||||
osSetSpeedupEnable(false);
|
||||
launch_3dsx(path, &newProgramArgs, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//should never be reached
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef EXEC_3DSX_H
|
||||
#define EXEC_3DSX_H
|
||||
|
||||
//since 3dsx programs are not guaranteed access to the OS, the 3dsx bootloader run by the exploit must run the next program
|
||||
//your program must have no extra threads running when this is called, these limits do not apply to exec_cia
|
||||
int exec_3dsx_no_path_in_args(const char* path, const char** args);
|
||||
int exec_3dsx(const char* path, const char** args);
|
||||
|
||||
#ifndef EXEC_3DSX_H
|
||||
#define EXEC_3DSX_H
|
||||
|
||||
//since 3dsx programs are not guaranteed access to the OS, the 3dsx bootloader run by the exploit must run the next program
|
||||
//your program must have no extra threads running when this is called, these limits do not apply to exec_cia
|
||||
int exec_3dsx_no_path_in_args(const char* path, const char** args);
|
||||
int exec_3dsx(const char* path, const char** args);
|
||||
|
||||
#endif
|
@ -13,7 +13,6 @@ typedef struct{
|
||||
|
||||
char argvHmac[0x20] = {0x1d, 0x78, 0xff, 0xb9, 0xc5, 0xbc, 0x78, 0xb7, 0xac, 0x29, 0x1d, 0x3e, 0x16, 0xd0, 0xcf, 0x53, 0xef, 0x12, 0x58, 0x83, 0xb6, 0x9e, 0x2f, 0x79, 0x47, 0xf9, 0x35, 0x61, 0xeb, 0x50, 0xd7, 0x67};
|
||||
|
||||
|
||||
static void errorAndQuit(const char* errorStr){
|
||||
errorConf error;
|
||||
|
||||
@ -30,37 +29,37 @@ static int isCiaInstalled(u64 titleId, u16 version){
|
||||
bool titleExists = false;
|
||||
AM_TitleEntry titleInfo;
|
||||
Result failed;
|
||||
|
||||
|
||||
failed = AM_GetTitleCount(MEDIATYPE_SD, &titlesToRetrieve);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
titleIds = malloc(titlesToRetrieve * sizeof(uint64_t));
|
||||
if(titleIds == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
failed = AM_GetTitleList(&titlesRetrieved, MEDIATYPE_SD, titlesToRetrieve, titleIds);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
for(u32 titlesToCheck = 0; titlesToCheck < titlesRetrieved; titlesToCheck++){
|
||||
if(titleIds[titlesToCheck] == titleId){
|
||||
titleExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(titleIds);
|
||||
|
||||
|
||||
if(titleExists){
|
||||
failed = AM_GetTitleInfo(MEDIATYPE_SD, 1 /*titleCount*/, &titleId, &titleInfo);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
if(titleInfo.version == version)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -72,15 +71,15 @@ static int installCia(Handle ciaFile){
|
||||
u32 bytesRead;
|
||||
u32 bytesWritten;
|
||||
u8 transferBuffer[FILE_CHUNK_SIZE];
|
||||
|
||||
|
||||
failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
failed = FSFILE_GetSize(ciaFile, &fileSize);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
while(fileOffset < fileSize){
|
||||
u64 bytesRemaining = fileSize - fileOffset;
|
||||
failed = FSFILE_Read(ciaFile, &bytesRead, fileOffset, transferBuffer, bytesRemaining < FILE_CHUNK_SIZE ? bytesRemaining : FILE_CHUNK_SIZE);
|
||||
@ -88,7 +87,7 @@ static int installCia(Handle ciaFile){
|
||||
AM_CancelCIAInstall(outputHandle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
failed = FSFILE_Write(outputHandle, &bytesWritten, fileOffset, transferBuffer, bytesRead, 0);
|
||||
if(R_FAILED(failed)){
|
||||
AM_CancelCIAInstall(outputHandle);
|
||||
@ -96,32 +95,32 @@ static int installCia(Handle ciaFile){
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(bytesWritten != bytesRead){
|
||||
AM_CancelCIAInstall(outputHandle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fileOffset += bytesWritten;
|
||||
}
|
||||
|
||||
|
||||
failed = AM_FinishCiaInstall(outputHandle);
|
||||
if(R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int exec_cia(const char* path, const char** args){
|
||||
struct stat sBuff;
|
||||
struct stat sBuff;
|
||||
bool fileExists;
|
||||
bool inited;
|
||||
|
||||
|
||||
if(path == NULL || path[0] == '\0'){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fileExists = stat(path, &sBuff) == 0;
|
||||
if(!fileExists){
|
||||
errno = ENOENT;
|
||||
@ -131,7 +130,7 @@ int exec_cia(const char* path, const char** args){
|
||||
errno = EINVAL;;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
inited = R_SUCCEEDED(amInit()) && R_SUCCEEDED(fsInit());
|
||||
if(inited){
|
||||
Result res;
|
||||
@ -141,20 +140,20 @@ int exec_cia(const char* path, const char** args){
|
||||
int ciaInstalled;
|
||||
ciaParam param;
|
||||
int argsLength;
|
||||
|
||||
|
||||
//open cia file
|
||||
res = FSUSER_OpenArchive(&ciaArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
|
||||
if(R_FAILED(res))
|
||||
errorAndQuit("Cant open SD FS archive.");
|
||||
|
||||
|
||||
res = FSUSER_OpenFile(&ciaFile, ciaArchive, fsMakePath(PATH_ASCII, path + 5/*skip "sdmc:"*/), FS_OPEN_READ, 0);
|
||||
if(R_FAILED(res))
|
||||
errorAndQuit("Cant open CIA file.");
|
||||
|
||||
|
||||
res = AM_GetCiaFileInfo(MEDIATYPE_SD, &ciaInfo, ciaFile);
|
||||
if(R_FAILED(res))
|
||||
errorAndQuit("Cant get CIA file info.");
|
||||
|
||||
|
||||
ciaInstalled = isCiaInstalled(ciaInfo.titleID, ciaInfo.version);
|
||||
if(ciaInstalled == -1){
|
||||
//error
|
||||
@ -166,10 +165,10 @@ int exec_cia(const char* path, const char** args){
|
||||
if(error == -1)
|
||||
errorAndQuit("Cant install CIA.");
|
||||
}
|
||||
|
||||
|
||||
FSFILE_Close(ciaFile);
|
||||
FSUSER_CloseArchive(ciaArchive);
|
||||
|
||||
|
||||
param.argc = 0;
|
||||
argsLength = 0;
|
||||
char* argLocation = param.args;
|
||||
@ -179,19 +178,19 @@ int exec_cia(const char* path, const char** args){
|
||||
argsLength += strlen(args[param.argc]) + 1;
|
||||
param.argc++;
|
||||
}
|
||||
|
||||
|
||||
res = APT_PrepareToDoApplicationJump(0, ciaInfo.titleID, 0x1);
|
||||
if(R_FAILED(res))
|
||||
errorAndQuit("CIA cant run, cant prepare.");
|
||||
|
||||
|
||||
res = APT_DoApplicationJump(¶m, sizeof(param.argc) + argsLength, argvHmac);
|
||||
if(R_FAILED(res))
|
||||
errorAndQuit("CIA cant run, cant jump.");
|
||||
|
||||
|
||||
//wait for application jump, for some reason its not instant
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
//should never be reached
|
||||
amExit();
|
||||
fsExit();
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef EXEC_CIA_H
|
||||
#define EXEC_CIA_H
|
||||
|
||||
int exec_cia(const char* path, const char** args);
|
||||
|
||||
#ifndef EXEC_CIA_H
|
||||
#define EXEC_CIA_H
|
||||
|
||||
int exec_cia(const char* path, const char** args);
|
||||
|
||||
#endif
|
@ -1,95 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
// C stdlib includes
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// 3DS includes
|
||||
#include <3ds.h>
|
||||
|
||||
|
||||
#define ENTRY_ARGBUFSIZE 0x400
|
||||
#define NUM_SERVICESTHATMATTER 5
|
||||
|
||||
typedef enum
|
||||
{
|
||||
StrId_Loading = 0,
|
||||
StrId_Directory,
|
||||
StrId_DefaultLongTitle,
|
||||
StrId_DefaultPublisher,
|
||||
StrId_IOError,
|
||||
StrId_CouldNotOpenFile,
|
||||
|
||||
StrId_NoAppsFound_Title,
|
||||
StrId_NoAppsFound_Msg,
|
||||
|
||||
StrId_Reboot,
|
||||
StrId_ReturnToHome,
|
||||
|
||||
StrId_TitleSelector,
|
||||
StrId_ErrorReadingTitleMetadata,
|
||||
StrId_NoTitlesFound,
|
||||
StrId_SelectTitle,
|
||||
|
||||
StrId_NoTargetTitleSupport,
|
||||
StrId_MissingTargetTitle,
|
||||
|
||||
StrId_NetLoader,
|
||||
StrId_NetLoaderUnavailable,
|
||||
StrId_NetLoaderOffline,
|
||||
StrId_NetLoaderError,
|
||||
StrId_NetLoaderActive,
|
||||
StrId_NetLoaderTransferring,
|
||||
|
||||
StrId_Max,
|
||||
} StrId;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* dst;
|
||||
u32 buf[ENTRY_ARGBUFSIZE/sizeof(u32)];
|
||||
} argData_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool scanned;
|
||||
u32 sectionSizes[3];
|
||||
bool servicesThatMatter[NUM_SERVICESTHATMATTER];
|
||||
} executableMetadata_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 num;
|
||||
u32 text_end;
|
||||
u32 data_address;
|
||||
u32 data_size;
|
||||
u32 processLinearOffset;
|
||||
u32 processHookAddress;
|
||||
u32 processAppCodeAddress;
|
||||
u32 processHookTidLow, processHookTidHigh;
|
||||
u32 mediatype;
|
||||
bool capabilities[0x10]; // {socuAccess, csndAccess, qtmAccess, nfcAccess, httpcAccess, reserved...}
|
||||
} memmap_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 src, dst, size;
|
||||
} memmap_entry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
memmap_header_t header;
|
||||
memmap_entry_t map[];
|
||||
} memmap_t;
|
||||
|
||||
#define memmapSize(m) (sizeof(memmap_header_t) + sizeof(memmap_entry_t)*(m)->header.num)
|
||||
|
||||
|
||||
#include "launch.h"
|
||||
#pragma once
|
||||
|
||||
// C stdlib includes
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// 3DS includes
|
||||
#include <3ds.h>
|
||||
|
||||
#define ENTRY_ARGBUFSIZE 0x400
|
||||
#define NUM_SERVICESTHATMATTER 5
|
||||
|
||||
typedef enum
|
||||
{
|
||||
StrId_Loading = 0,
|
||||
StrId_Directory,
|
||||
StrId_DefaultLongTitle,
|
||||
StrId_DefaultPublisher,
|
||||
StrId_IOError,
|
||||
StrId_CouldNotOpenFile,
|
||||
|
||||
StrId_NoAppsFound_Title,
|
||||
StrId_NoAppsFound_Msg,
|
||||
|
||||
StrId_Reboot,
|
||||
StrId_ReturnToHome,
|
||||
|
||||
StrId_TitleSelector,
|
||||
StrId_ErrorReadingTitleMetadata,
|
||||
StrId_NoTitlesFound,
|
||||
StrId_SelectTitle,
|
||||
|
||||
StrId_NoTargetTitleSupport,
|
||||
StrId_MissingTargetTitle,
|
||||
|
||||
StrId_NetLoader,
|
||||
StrId_NetLoaderUnavailable,
|
||||
StrId_NetLoaderOffline,
|
||||
StrId_NetLoaderError,
|
||||
StrId_NetLoaderActive,
|
||||
StrId_NetLoaderTransferring,
|
||||
|
||||
StrId_Max,
|
||||
} StrId;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* dst;
|
||||
u32 buf[ENTRY_ARGBUFSIZE/sizeof(u32)];
|
||||
} argData_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool scanned;
|
||||
u32 sectionSizes[3];
|
||||
bool servicesThatMatter[NUM_SERVICESTHATMATTER];
|
||||
} executableMetadata_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 num;
|
||||
u32 text_end;
|
||||
u32 data_address;
|
||||
u32 data_size;
|
||||
u32 processLinearOffset;
|
||||
u32 processHookAddress;
|
||||
u32 processAppCodeAddress;
|
||||
u32 processHookTidLow, processHookTidHigh;
|
||||
u32 mediatype;
|
||||
bool capabilities[0x10]; // {socuAccess, csndAccess, qtmAccess, nfcAccess, httpcAccess, reserved...}
|
||||
} memmap_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 src, dst, size;
|
||||
} memmap_entry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
memmap_header_t header;
|
||||
memmap_entry_t map[];
|
||||
} memmap_t;
|
||||
|
||||
#define memmapSize(m) (sizeof(memmap_header_t) + sizeof(memmap_entry_t)*(m)->header.num)
|
||||
|
||||
#include "launch.h"
|
||||
|
2
deps/mbedtls/dhm.c
vendored
2
deps/mbedtls/dhm.c
vendored
@ -530,7 +530,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
|
||||
*n = (size_t) size;
|
||||
|
||||
if( *n + 1 == 0 ||
|
||||
( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
|
||||
( *buf = (unsigned char*)mbedtls_calloc( 1, *n + 1 ) ) == NULL )
|
||||
{
|
||||
fclose( f );
|
||||
return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
|
||||
|
4
deps/mbedtls/ecp.c
vendored
4
deps/mbedtls/ecp.c
vendored
@ -811,7 +811,7 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL )
|
||||
if( ( c = (mbedtls_mpi*)mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL )
|
||||
return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
|
||||
|
||||
mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
|
||||
@ -1406,7 +1406,7 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
|
||||
if( T == NULL )
|
||||
{
|
||||
T = mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) );
|
||||
T = (mbedtls_ecp_point*)mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) );
|
||||
if( T == NULL )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
|
2
deps/mbedtls/net_sockets.c
vendored
2
deps/mbedtls/net_sockets.c
vendored
@ -578,7 +578,7 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_would_block( ctx ) != 0 )
|
||||
if( net_would_block((const mbedtls_net_context*)ctx) != 0 )
|
||||
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
|
||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user