mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 17:29:21 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e25601a56 | ||
|
|
fca5af7ac3 | ||
|
|
1af0ede1a6 | ||
|
|
e7733abc40 | ||
|
|
4171c93bff | ||
|
|
dd2c9c911b | ||
|
|
de052537ec | ||
|
|
68bc6b37ae | ||
|
|
548d1bae9e | ||
|
|
c89e557158 | ||
|
|
62dda5fdbf | ||
|
|
22f24bd48f | ||
|
|
eeb0c65b6e | ||
|
|
b23fcf238b | ||
|
|
79698981ad | ||
|
|
ab4e3e8c75 | ||
|
|
4bee4429aa | ||
|
|
269ee7e672 | ||
|
|
8d6b70c22c | ||
|
|
e786059506 | ||
|
|
d48d4385d9 | ||
|
|
1521be8acb | ||
|
|
76c97bbfad | ||
|
|
1b931dd410 | ||
|
|
77baa1c930 | ||
|
|
d41b7770c4 | ||
|
|
4f145a4f4f | ||
|
|
fc7dc3cef7 | ||
|
|
0dbfd721b3 | ||
|
|
243505b7cb | ||
|
|
04af898fe5 | ||
|
|
9e1c5747f6 | ||
|
|
ab49806a5f | ||
|
|
e24934d5ea | ||
|
|
8ab162ffb1 | ||
|
|
614e5bc44f | ||
|
|
c1137ee3fa | ||
|
|
6cfe0ea77c | ||
|
|
d89b7f93b2 | ||
|
|
a6b114e423 | ||
|
|
90f2ebeac1 | ||
|
|
60cca4d9d2 | ||
|
|
9b2752ff07 | ||
|
|
16c4035e1c | ||
|
|
b5eba22aaf | ||
|
|
98b572d17a | ||
|
|
76c6e01534 | ||
|
|
15b1281075 | ||
|
|
e4ef930b47 | ||
|
|
19e86a2b19 | ||
|
|
46b62b4a63 | ||
|
|
7874d179da | ||
|
|
341a4d50ea | ||
|
|
b8328a9fdf | ||
|
|
5b8411fe77 | ||
|
|
682d8f23e9 | ||
|
|
34a9224334 | ||
|
|
88ee7cbfa8 | ||
|
|
70e472e9e2 | ||
|
|
e9adb44c4a | ||
|
|
81f8cae52a | ||
|
|
36e67108fb | ||
|
|
f0bad7b091 | ||
|
|
354c50039b | ||
|
|
b9c69e24a9 | ||
|
|
6319262b9c | ||
|
|
78e02bf3dd | ||
|
|
3492ba5fd6 | ||
|
|
f9ed6cbbfe | ||
|
|
98a573033d | ||
|
|
066089873b | ||
|
|
8032ff6e19 | ||
|
|
99d5dba6ae | ||
|
|
0b0455975b | ||
|
|
4b34894b59 | ||
|
|
311ee2db62 | ||
|
|
dfafcb0513 | ||
|
|
28520af599 | ||
|
|
207795abfd | ||
|
|
495ad41741 | ||
|
|
d591529e7a | ||
|
|
3a5dace583 | ||
|
|
e2952586d1 | ||
|
|
16f25c2e06 | ||
|
|
8fea733a1f | ||
|
|
bbb09f7557 | ||
|
|
1fc1acd3d0 | ||
|
|
0923985516 | ||
|
|
2b1d1bc8cb | ||
|
|
38e3cc2087 | ||
|
|
be3acb902b | ||
|
|
617940fb8d | ||
|
|
a96ae6e987 | ||
|
|
a65396ba56 | ||
|
|
61c4e3a5e4 | ||
|
|
df8f93e9d5 | ||
|
|
577e1bd693 | ||
|
|
1012d07e7f | ||
|
|
edec9448c4 | ||
|
|
19ea50843c | ||
|
|
e9db190baa | ||
|
|
fd5d9a0710 | ||
|
|
1f673be3c8 | ||
|
|
a82582e859 | ||
|
|
40ecfbcdfa | ||
|
|
1e54379141 | ||
|
|
291012d2a9 | ||
|
|
5296f4aebd | ||
|
|
c86de916cb | ||
|
|
c014fc20a1 | ||
|
|
39f089f374 | ||
|
|
1fe7898add | ||
|
|
3b2ec53100 | ||
|
|
3a8f12dff3 | ||
|
|
02d1eeb400 | ||
|
|
261f1b72d4 | ||
|
|
15f7ba4d99 | ||
|
|
ea49348db2 | ||
|
|
af6208be29 | ||
|
|
5f81200067 | ||
|
|
3901c2d63a | ||
|
|
b1ad6014f0 | ||
|
|
572611f1ca | ||
|
|
6d4b1b69e5 | ||
|
|
dcb6bae868 | ||
|
|
69208d0fca | ||
|
|
60c8edd39c | ||
|
|
d2e2c289a6 | ||
|
|
562bf11946 | ||
|
|
3d80838754 | ||
|
|
85f25574fb | ||
|
|
2986e9ff37 | ||
|
|
9b87456d3e | ||
|
|
8a64df5763 | ||
|
|
376547044c | ||
|
|
2b22eaa7e6 | ||
|
|
da4c95531e | ||
|
|
707aafa1e6 | ||
|
|
e5169eee71 | ||
|
|
665b98bd28 | ||
|
|
0817fb3d18 | ||
|
|
29e9546b7d | ||
|
|
2653a9bed3 | ||
|
|
72a44078ce | ||
|
|
501954c6f6 | ||
|
|
fa7859ad13 | ||
|
|
600776012d | ||
|
|
37044dd387 | ||
|
|
a11d955dd8 | ||
|
|
c0daf56963 | ||
|
|
bbdf586f18 | ||
|
|
4a93cb2007 | ||
|
|
203bea3fe6 | ||
|
|
641662d77c | ||
|
|
2ad394148a | ||
|
|
bbd1e6a6a5 | ||
|
|
bef72a19d0 | ||
|
|
3efa83a646 | ||
|
|
1d2150cb45 | ||
|
|
56236f7372 | ||
|
|
246863279a | ||
|
|
a986b71947 | ||
|
|
3eba8da4e9 | ||
|
|
94261da70a | ||
|
|
5dcdee5faa | ||
|
|
8386c06e07 | ||
|
|
85d11eac30 | ||
|
|
755cc94489 | ||
|
|
ef2ddf6912 | ||
|
|
f97e557194 | ||
|
|
0029598822 | ||
|
|
e23cd0e7e7 | ||
|
|
4c9ae245a4 | ||
|
|
4380b73ca6 | ||
|
|
fa2a748631 | ||
|
|
bdc866d6d5 | ||
|
|
554bbb5fd0 | ||
|
|
6e0971fc61 | ||
|
|
d5cdfbb7ba | ||
|
|
063986a4b3 | ||
|
|
fdb859276b | ||
|
|
9a14c28056 | ||
|
|
210833006f | ||
|
|
4ca5af4ac9 | ||
|
|
decd374c15 | ||
|
|
1216c3ef6d | ||
|
|
0f72a07b9e | ||
|
|
c4fafaebec | ||
|
|
c0160095fa | ||
|
|
f559e931cf | ||
|
|
f92a507a9b | ||
|
|
be7e074856 | ||
|
|
3e1f56d57f | ||
|
|
aae2e6fd7d | ||
|
|
91baea201a | ||
|
|
cf58c09d6e | ||
|
|
53dbd69751 | ||
|
|
3d950b2324 | ||
|
|
96395f7d39 | ||
|
|
e4eb5a9bb9 | ||
|
|
27c45b1b7a | ||
|
|
278dc75285 | ||
|
|
9c6c10da22 | ||
|
|
1d6f547e7f | ||
|
|
ee7051891b | ||
|
|
22b789cca6 | ||
|
|
40a6c978ce | ||
|
|
688629d108 | ||
|
|
65e8b28d02 | ||
|
|
1561ed8022 | ||
|
|
1630affbdd | ||
|
|
d88e37a2f1 | ||
|
|
fa00cdba20 | ||
|
|
6c97a7514c | ||
|
|
83057301c2 | ||
|
|
6e6fbc5ad3 | ||
|
|
d567b0ca25 | ||
|
|
3667690027 | ||
|
|
2936b1940a | ||
|
|
07700d77bd | ||
|
|
776568a429 | ||
|
|
8f39fb2adf | ||
|
|
91ee8c8ee6 | ||
|
|
a4e810795c | ||
|
|
0418e49757 | ||
|
|
0096b9e6f0 | ||
|
|
47e1f0f2b1 | ||
|
|
f2a64aa8e7 | ||
|
|
c25e3ab3f9 | ||
|
|
b6d01ce448 | ||
|
|
090919490a | ||
|
|
2ba1f3547c | ||
|
|
556fa9a499 | ||
|
|
ec3ab80da8 | ||
|
|
41e32ea949 | ||
|
|
42c3072ff9 | ||
|
|
0b0ac03bed | ||
|
|
ef8427cc23 | ||
|
|
c73daa6a1c | ||
|
|
6b6233944b | ||
|
|
a6245185b9 | ||
|
|
bfd283e2a6 | ||
|
|
54675938ce | ||
|
|
758a6c76ae | ||
|
|
05d71ebb67 | ||
|
|
19406af87f | ||
|
|
fa328c1590 | ||
|
|
c4e04a6d09 | ||
|
|
b1579dd8d9 | ||
|
|
6ca24c412d | ||
|
|
fc4a5ad691 | ||
|
|
4b183f84b2 | ||
|
|
bf01a2d6e5 | ||
|
|
4c38228359 | ||
|
|
ef9501a40d | ||
|
|
195c9f6ab6 | ||
|
|
cc0b7c42d1 | ||
|
|
4ec9fe5a57 | ||
|
|
643b3a73a4 | ||
|
|
dcd5dd6492 | ||
|
|
39db52b4f4 | ||
|
|
3955009b08 | ||
|
|
f1dc0b6d8e | ||
|
|
a30e53d911 | ||
|
|
568c55aca2 | ||
|
|
62af393cd8 | ||
|
|
7ed61ca766 | ||
|
|
f9580c245d | ||
|
|
88b28b6458 | ||
|
|
7c63889b26 | ||
|
|
55de2803a4 | ||
|
|
4de34a53e7 | ||
|
|
0e22651c48 | ||
|
|
fa6ce5bc68 | ||
|
|
db7431f3fa | ||
|
|
7747e3a6b4 | ||
|
|
0d2d8f4d41 | ||
|
|
f4f339c4d5 | ||
|
|
48fddcb7bd | ||
|
|
0a6f6cb281 | ||
|
|
eb51b0c383 | ||
|
|
5f1fcf51a6 | ||
|
|
569014c5d2 | ||
|
|
1d6ebacfaa | ||
|
|
80f494b961 | ||
|
|
f4d1732137 | ||
|
|
2fc3a6fc1a | ||
|
|
dc8f8cd401 | ||
|
|
88c331ea99 | ||
|
|
9d16264ba1 | ||
|
|
d809cc6a31 | ||
|
|
5c0cca9783 | ||
|
|
a0e7fe19af | ||
|
|
960ff23843 | ||
|
|
0996e13352 | ||
|
|
81972149fc | ||
|
|
48af253a06 | ||
|
|
1e45692f0b | ||
|
|
096a420e7b | ||
|
|
ecb3301b19 | ||
|
|
ad397671a7 | ||
|
|
8b5db9fdaf | ||
|
|
4137273002 | ||
|
|
f6db9ce04d | ||
|
|
106c912eb5 | ||
|
|
3fe8806018 | ||
|
|
f3742a101c | ||
|
|
b09a22360c | ||
|
|
f01afe72c6 | ||
|
|
a2fd581dad | ||
|
|
2169a25b0a | ||
|
|
fdd4915718 | ||
|
|
9e9fa1f7df | ||
|
|
5e8ab7b287 | ||
|
|
0e47f4efb8 | ||
|
|
080b3ea184 | ||
|
|
13d44720e0 | ||
|
|
57f5d04126 | ||
|
|
463d68163e | ||
|
|
7ad4becedb | ||
|
|
7fa6247770 | ||
|
|
17c827adfb | ||
|
|
a30a53f12a | ||
|
|
7e83f4a531 | ||
|
|
3c3e6978b8 | ||
|
|
19f53d96a2 | ||
|
|
98618c052b | ||
|
|
69e5e97bdf | ||
|
|
99850df96e | ||
|
|
dd658a05b4 | ||
|
|
3ce38ffe91 | ||
|
|
89b04d255e | ||
|
|
410e94aa89 | ||
|
|
7c8d831497 | ||
|
|
c84d02830c | ||
|
|
b3e8d6e9ca | ||
|
|
96fd6f8617 | ||
|
|
cde4ecd08b | ||
|
|
a05ebd4bbc | ||
|
|
9e749ee63a | ||
|
|
e785bff78d | ||
|
|
3aedbe6989 |
No files matched your search
+3
-1
@@ -32,6 +32,8 @@ matrix:
|
||||
env: CXX_BUILD=1 CROSS_COMPILE=x86_64-w64-mingw32- CFLAGS="-D_WIN32_WINNT=0x0501"
|
||||
- compiler: gcc
|
||||
env: CC=gcc-8 CXX=g++-8
|
||||
- compiler: gcc
|
||||
env: CC="gcc-8 --sysroot=/" CXX="g++-8 --sysroot=/"
|
||||
- compiler: gcc
|
||||
env: C89_BUILD=1 CC=gcc-8 CXX=g++-8
|
||||
- compiler: gcc
|
||||
@@ -105,7 +107,7 @@ matrix:
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [ "$CC" = gcc-8 ]; then
|
||||
if [[ "$CC" =~ ^gcc-8.* ]]; then
|
||||
# Install a more recent gcc than the default
|
||||
sudo apt-get install -y g++-8
|
||||
elif [ "$CC" = clang-6.0 ]; then
|
||||
|
||||
Vendored
+26
-1
@@ -40,6 +40,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "PSP-GDB Debugger",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/retroarchpsp.elf",
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "symbol-file ${workspaceFolder}/retroarchpsp.elf",
|
||||
"description": "read symbols for elf file",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Enable all-exceptions",
|
||||
"text": "-exec \"catch throw\"",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"showDisplayString": true,
|
||||
"targetArchitecture": "mips",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "/usr/local/pspdev/bin/psp-gdb",
|
||||
"miDebuggerServerAddress": "127.0.0.1:10001",
|
||||
}
|
||||
]
|
||||
}
|
||||
+57
@@ -1,5 +1,62 @@
|
||||
# Future
|
||||
|
||||
# 1.8.4
|
||||
- ANDROID/BUGFIX: Prevent crash when Android device is minimized and you go back to the app
|
||||
- CAMERA/BUGFIX: Fix crash when a core requires the camera driver and the platform only has a null driver. This would crash mgba on Wii for example
|
||||
- DISK CONTROL: Cycle Disk Tray now becomes Eject Disk or Insert Disk depending upon current drive state
|
||||
- DISK CONTROL: Current Disk Index is only shown when the current disk has been ejected
|
||||
- DISK CONTROL: The old Insert Disk entry has been changed to Load New Disk, and is only shown when a disk is currently inserted (this is because loading a new disk from the filesystem - i.e. bypassing the m3u playlist disk index interface - automatically ejects and inserts disks, and so cannot be done while the virtual drive is empty)
|
||||
- DISK CONTROL: The Current Disk Index may now be set more easily via a drop-down list.
|
||||
- DISK CONTROL: Selecting Eject Disk automatically moves the menu selection to the Current Disk Index entry
|
||||
- DISK CONTROL: Selecting an index via the Current Disk Index drop-down list automatically moves the menu selection back to Insert Disk
|
||||
- DISK CONTROL: The Disk Control entry sublabels have been changed for greater clarity
|
||||
- DISK CONTROL: All of the horrendous notification spam has been removed. Notifications are now only shown in the event of an error, or when the menu itself does not provide sufficient visual feedback (note that using hotkeys to swap disks still produces the old style notifications, since this is typically only done while content is running - i.e. no menu). The duration of disk-related info notifications has also been reduced to a more sane level.
|
||||
- DISK CONTROL: A new Resume content after changing disks option has been added under Settings > User Interface. When enabled (default setting), content is resumed automatically after selecting either Insert Disk or Load New Disk (when disabled, the menu remains open, obviously...)
|
||||
- DISK CONTROL/BUGFIX: The Disk Control menu now has the correct title
|
||||
- DISK CONTROL/BUGFIX: Selecting a disk via the Load New Disk file browser no longer flushes the user back to the top level menu (it now correctly returns to the Disk Control menu)
|
||||
- LIBNX/SWITCH: Updated libnx integration to v3.0.0. This also cherry-picks libnx commit 583d6bb92dcbb33b6bb4a0fa1a9df6e3725d6ef6, which should fix the requirement having to turn rumble off and on in the system settings once per reboot
|
||||
|
||||
# 1.8.3
|
||||
- ANDROID/BUGFIX: Fix 'Install or Restore Core' regression
|
||||
- BUGFIX: Ensure core info is always initialised when calling 'drivers_init()'. This bug could prevent cores from doing content runtime logging
|
||||
- BUGFIX/MENU: History size can only be set to 1 at a minimum
|
||||
- BUGFIX/MENU: (XMB/OZONE) Fix 'quick menu' detection. XMB would not display savestate thumbnails in the quick menu if it was accessed via the main menu
|
||||
- BUGFIX/CRASH/CORE UPDATER: Fix potential double free error
|
||||
- BUGFIX/CRASH/OPENGL/WINDOWS: Fix regression in 1.8.2 that would cause GL-based cores to fail because it would try to erroneously load libGLESv2.dll instead of OpenGL32.dll (cores affected: VitaQuake 2/3/Dhewm3, possibly more)
|
||||
- BUGFIX/MENU/DESKTOP UI: Show desktop menu on startup does not launch Qt UI on Linux
|
||||
- BUGFIX: Entries in the Playlist Thumbnails Updater list were displaying improper sublabels. I have no idea when this broke... The issue is now fixed
|
||||
- CHEEVOS: Don't disable achievement when AddAddress generates an out-of-range address
|
||||
- CHEEVOS: Don't reset triggers/leaderboards that failed to load
|
||||
- CHEEVOS: Don't count unsupported achievements as unlocked
|
||||
- CORE UPDATER: Display number of cores updated when updating installed cores
|
||||
- DINGUX: Initial port
|
||||
- D3D11: Block FL9_3 devices from D3D11 driver because they don't work anyway (current D3D11 driver uses SM4.0 which requires FL10_0 and up)
|
||||
- D3D11: Fallback to GL driver when D3D11 fails
|
||||
- EMSCRIPTEN: Fix assets
|
||||
- HISTORY/FAVORITES: Bump up default to 200 entries from 100
|
||||
- FFMPEG CORE: Implement packet buffer, fixes MP4 video playback for many files
|
||||
- LOCALIZATION: Update Italian translation
|
||||
- LOCALIZATION: Update Polish translation
|
||||
- LOCALIZATION: Update Russian translation
|
||||
- LOCALIZATION: Update Spanish translation
|
||||
- MENU: Added 'Hosting' menu under Netplay menu
|
||||
- MENU: Added 'Subsystems' menu
|
||||
- MENU/FILEBROWSER: Fix file selection issues when starting from (or navigating to) the top level directory
|
||||
- MENU/WIDGETS: Prevent looping of task title text
|
||||
- RASPBERRY PI: Fix BGRA8888 color inversion issues in the menu and elsewhere with VideoCore GL drivers
|
||||
- NETPLAY/RELAY: Add Sao Paulo (Brazil) relay server
|
||||
- NETPLAY/RELAY: Fix the “spectator” bug when using the relay server – When a player switches into the spectator mode (pressing “i”) while using the relay server, all players will disconnect.
|
||||
- NETPLAY/RELAY: Overall stability has improved. Fixed a memory leak that would cause the relay server to become unresponsive after some time.
|
||||
- NETPLAY/RELAY: Fixed critical bug that would cause all players to be disconnected from the relay server if one player was leaving the game. That bug had been open for one year and we were finally able to fix it.
|
||||
- SWITCH/LIBNX/BUGFIX: Fix onscreen keyboard input regression
|
||||
- THUMBNAIL UPDATER: When waiting for individual thumbnail file http transfers to complete, the task status checking is more accurate. This uses the same method as the new core updater - we now wait until the task is 'really' complete, instead of relying on the (slightly nebulous) 'task finished' state
|
||||
- UWP: Add ANGLE support
|
||||
- UWP: Wire up get_metrics to the fake context of D3D9/10/11/12 driver, enabling proper scaling and mouse/touch gestures
|
||||
- VITA: Re-add Online Updater
|
||||
- VULKAN: Fix font driver 'vulkan_get_message_width()' function
|
||||
- VIDEO FILTERS: Only use threads when the number exceeds 1. Fixes race conditions with some CPU filters on Vita
|
||||
- WINDOWS: Add ANGLE support for x64, separate binary (for now?)
|
||||
|
||||
# 1.8.2
|
||||
- BUG/CRASH/GLSLANG: Fix glslang crashing error - managed to reproduce an issue which has been plaguing
|
||||
users for a while, where glslang throws an assert after closing a game (and starting a new one). This would affect all video drivers that use Slang for shaders, such as D3D10/11/12/Vulkan/Metal
|
||||
|
||||
@@ -14,7 +14,11 @@ include config.mk
|
||||
# (It'd be better to put this comment in that file, but .gitignore doesn't work on files that exist in the repo.)
|
||||
-include Makefile.local
|
||||
|
||||
ifeq ($(HAVE_ANGLE), 1)
|
||||
TARGET = retroarch_angle
|
||||
else
|
||||
TARGET = retroarch
|
||||
endif
|
||||
|
||||
OBJ :=
|
||||
LIBS :=
|
||||
@@ -102,10 +106,20 @@ ifneq ($(findstring Win32,$(OS)),)
|
||||
LDFLAGS += -mwindows
|
||||
endif
|
||||
|
||||
ifneq ($(CXX_BUILD), 1)
|
||||
ifneq ($(C89_BUILD),)
|
||||
CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long
|
||||
else ifeq ($(HAVE_C99), 1)
|
||||
CFLAGS += $(C99_CFLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS += -D_GNU_SOURCE
|
||||
endif
|
||||
|
||||
DEF_FLAGS += -Wall $(INCLUDE_DIRS) -I. -Ideps -Ideps/stb
|
||||
|
||||
CFLAGS += $(DEF_FLAGS)
|
||||
CXXFLAGS += $(DEF_FLAGS) -std=c++11 -D__STDC_CONSTANT_MACROS
|
||||
CXXFLAGS += $(DEF_FLAGS) -D__STDC_CONSTANT_MACROS
|
||||
OBJCFLAGS := $(CFLAGS) -D__STDC_CONSTANT_MACROS
|
||||
|
||||
ifeq ($(HAVE_CXX), 1)
|
||||
@@ -123,20 +137,6 @@ else
|
||||
LINK = $(CC)
|
||||
endif
|
||||
|
||||
ifneq ($(CXX_BUILD), 1)
|
||||
ifneq ($(GNU90_BUILD), 1)
|
||||
ifneq ($(findstring icc,$(CC)),)
|
||||
CFLAGS += -std=c99 -D_GNU_SOURCE
|
||||
else
|
||||
CFLAGS += -std=gnu99 -D_GNU_SOURCE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(C89_BUILD),)
|
||||
CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(NOUNUSED), yes)
|
||||
CFLAGS += -Wno-unused-result
|
||||
CXXFLAGS += -Wno-unused-result
|
||||
@@ -203,7 +203,7 @@ endif
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
||||
retroarch: $(RARCH_OBJ)
|
||||
$(TARGET): $(RARCH_OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
|
||||
@@ -280,7 +280,7 @@ install: $(TARGET)
|
||||
fi
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/retroarch
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/$(TARGET)
|
||||
rm -f $(DESTDIR)$(BIN_DIR)/retroarch-cg2glsl
|
||||
rm -f $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg
|
||||
rm -f $(DESTDIR)$(DATA_DIR)/applications/retroarch.desktop
|
||||
|
||||
+26
-21
@@ -7,6 +7,10 @@ ifeq ($(HAVE_STACK_USAGE), 1)
|
||||
DEF_FLAGS += -fstack-usage
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CXX11), 1)
|
||||
CXXFLAGS += $(CXX11_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT),)
|
||||
HAVE_GL_CONTEXT = 0
|
||||
HAVE_GL_MODERN = 0
|
||||
@@ -153,7 +157,6 @@ ifeq ($(HAVE_DR_MP3), 1)
|
||||
endif
|
||||
|
||||
OBJ += frontend/frontend_driver.o \
|
||||
frontend/drivers/platform_null.o \
|
||||
retroarch.o \
|
||||
msg_hash.o \
|
||||
intl/msg_hash_us.o \
|
||||
@@ -202,13 +205,13 @@ endif
|
||||
OBJ += \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_intf.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/file_path.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/file_path_io.o \
|
||||
file_path_special.o \
|
||||
file_path_str.o \
|
||||
$(LIBRETRO_COMM_DIR)/hash/rhash.o \
|
||||
input/common/input_hid_common.o \
|
||||
input/input_mapper.o \
|
||||
led/led_driver.o \
|
||||
led/drivers/led_null.o \
|
||||
gfx/video_coord_array.o \
|
||||
gfx/video_display_server.o \
|
||||
gfx/video_crt_switch.o \
|
||||
@@ -242,23 +245,11 @@ OBJ += \
|
||||
$(LIBRETRO_COMM_DIR)/audio/dsp_filter.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/resampler/drivers/nearest_resampler.o \
|
||||
$(LIBRETRO_COMM_DIR)/audio/resampler/drivers/null_resampler.o \
|
||||
$(LIBRETRO_COMM_DIR)/utils/md5.o \
|
||||
location/drivers/nulllocation.o \
|
||||
camera/drivers/nullcamera.o \
|
||||
wifi/drivers/nullwifi.o \
|
||||
gfx/drivers/nullgfx.o \
|
||||
gfx/display_servers/dispserv_null.o \
|
||||
audio/drivers/nullaudio.o \
|
||||
input/drivers/nullinput.o \
|
||||
input/drivers_hid/null_hid.o \
|
||||
input/drivers_joypad/null_joypad.o \
|
||||
playlist.o \
|
||||
record/drivers/record_null.o \
|
||||
$(LIBRETRO_COMM_DIR)/features/features_cpu.o \
|
||||
performance_counters.o \
|
||||
verbosity.o \
|
||||
midi/drivers/null_midi.o \
|
||||
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o \
|
||||
manual_content_scan.o
|
||||
|
||||
@@ -826,10 +817,8 @@ ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
menu/menu_displaylist.o \
|
||||
menu/menu_animation.o \
|
||||
menu/drivers/menu_generic.o \
|
||||
menu/drivers/null.o \
|
||||
menu/menu_thumbnail_path.o \
|
||||
menu/menu_thumbnail.o \
|
||||
menu/drivers_display/menu_display_null.o
|
||||
menu/menu_thumbnail.o
|
||||
|
||||
ifeq ($(HAVE_MENU_WIDGETS), 1)
|
||||
OBJ += menu/widgets/menu_widgets.o
|
||||
@@ -1284,8 +1273,14 @@ endif
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
DEFINES += -DHAVE_EGL
|
||||
DEF_FLAGS += $(EGL_CFLAGS)
|
||||
LIBS += $(EGL_LIBS)
|
||||
OBJ += gfx/common/egl_common.o
|
||||
|
||||
ifeq ($(HAVE_DYNAMIC_EGL), 1)
|
||||
DEFINES += -DHAVE_DYNAMIC_EGL
|
||||
else
|
||||
LIBS += $(EGL_LIBS)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
@@ -1299,6 +1294,12 @@ else ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/drivers/sdl_gfx.o
|
||||
DEF_FLAGS += $(SDL_CFLAGS)
|
||||
LIBS += $(SDL_LIBS)
|
||||
else ifeq ($(HAVE_SDL_DINGUX), 1)
|
||||
HAVE_SDL_COMMON = 1
|
||||
DEF_FLAGS += -DHAVE_SDL -DHAVE_SDL_DINGUX
|
||||
OBJ += gfx/drivers/sdl_dingux_gfx.o
|
||||
DEF_FLAGS += $(SDL_DINGUX_CFLAGS)
|
||||
LIBS += $(SDL_DINGUX_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL_COMMON), 1)
|
||||
@@ -1751,6 +1752,11 @@ ifeq ($(HAVE_V4L2),1)
|
||||
LIBS += $(V4L2_LIBS)
|
||||
endif
|
||||
|
||||
# Accessibility
|
||||
ifeq ($(HAVE_ACCESSIBILITY), 1)
|
||||
DEFINES += -DHAVE_ACCESSIBILITY
|
||||
endif
|
||||
|
||||
# Things that depend on network availability
|
||||
|
||||
ifeq ($(HAVE_NETWORKING), 1)
|
||||
@@ -1959,8 +1965,6 @@ endif
|
||||
ifeq ($(HAVE_ANGLE), 1)
|
||||
OBJ += gfx/common/angle_common.o
|
||||
DEFINES += -DHAVE_ANGLE
|
||||
# TODO/FIXME - should perhaps set these libraries as separate CFLAG variables in qb system
|
||||
LIBS += -lEGL
|
||||
endif
|
||||
|
||||
# Record
|
||||
@@ -1968,8 +1972,9 @@ endif
|
||||
ifeq ($(HAVE_FFMPEG), 1)
|
||||
OBJ += record/drivers/record_ffmpeg.o \
|
||||
cores/libretro-ffmpeg/ffmpeg_core.o \
|
||||
cores/libretro-ffmpeg/packet_buffer.o \
|
||||
cores/libretro-ffmpeg/video_buffer.o \
|
||||
$(LIBRETRO_COMM_DIR)/rthreads/tpool.o
|
||||
$(LIBRETRO_COMM_DIR)/rthreads/tpool.o
|
||||
|
||||
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(SWRESAMPLE_LIBS) $(FFMPEG_LIBS)
|
||||
DEFINES += -DHAVE_FFMPEG
|
||||
|
||||
@@ -24,11 +24,11 @@ OBJ := ctr/ctr_system.o \
|
||||
frontend/frontend_salamander.o \
|
||||
frontend/frontend_driver.o \
|
||||
frontend/drivers/platform_ctr.o \
|
||||
frontend/drivers/platform_null.o \
|
||||
libretro-common/encodings/encoding_utf.o \
|
||||
libretro-common/compat/compat_strcasestr.o \
|
||||
libretro-common/compat/fopen_utf8.o \
|
||||
libretro-common/file/file_path.o \
|
||||
libretro-common/file/file_path_io.o \
|
||||
libretro-common/string/stdstring.o \
|
||||
libretro-common/lists/string_list.o \
|
||||
libretro-common/lists/dir_list.o \
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
CC = /opt/gcw0-toolchain/usr/bin/mipsel-gcw0-linux-uclibc-gcc
|
||||
CXX = /opt/gcw0-toolchain/usr/bin/mipsel-gcw0-linux-uclibc-g++
|
||||
PACKAGE_NAME = retroarch
|
||||
|
||||
DEBUG ?= 0
|
||||
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_AL = 1
|
||||
# this freezes when switching back from menu
|
||||
HAVE_ALSA = 0
|
||||
HAVE_BUILTINMBEDTLS = 1
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_C99 = 1
|
||||
HAVE_CC = 1
|
||||
HAVE_CC_RESAMPLER = 1
|
||||
HAVE_CHD = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
HAVE_COMMAND = 1
|
||||
HAVE_CXX = 1
|
||||
HAVE_DR_MP3 = 1
|
||||
HAVE_DYNAMIC = 1
|
||||
HAVE_EGL = 1
|
||||
HAVE_FREETYPE = 1
|
||||
HAVE_GDI = 1
|
||||
HAVE_GETADDRINFO = 1
|
||||
HAVE_GETOPT_LONG = 1
|
||||
HAVE_GLSL = 1
|
||||
HAVE_HID = 1
|
||||
HAVE_IBXM = 1
|
||||
HAVE_IMAGEVIEWER = 1
|
||||
HAVE_LANGEXTRA = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_MENU_COMMON = 1
|
||||
HAVE_MENU_WIDGETS = 1
|
||||
HAVE_MMAP = 1
|
||||
HAVE_NETWORKING = 1
|
||||
HAVE_OPENDINGUX_FBDEV = 1
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_OPENGL1 = 0
|
||||
HAVE_OPENGLES = 1
|
||||
HAVE_OPENGLES3 = 0
|
||||
HAVE_OPENGL_CORE = 0
|
||||
HAVE_OPENSSL = 1
|
||||
HAVE_OVERLAY = 1
|
||||
HAVE_RBMP = 1
|
||||
HAVE_RJPEG = 1
|
||||
HAVE_RPILED = 1
|
||||
HAVE_RPNG = 1
|
||||
HAVE_RUNAHEAD = 1
|
||||
HAVE_SDL_DINGUX = 1
|
||||
HAVE_SHADERPIPELINE = 1
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_STB_IMAGE = 1
|
||||
HAVE_STB_VORBIS = 1
|
||||
HAVE_STDIN_CMD = 1
|
||||
HAVE_STRCASESTR = 1
|
||||
HAVE_THREADS = 1
|
||||
HAVE_TRANSLATE = 1
|
||||
HAVE_UDEV = 1
|
||||
HAVE_VIDEO_LAYOUT = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_ZLIB = 1
|
||||
|
||||
OS = Linux
|
||||
TARGET = retroarch
|
||||
OPK_NAME = retroarch.opk
|
||||
|
||||
OBJ :=
|
||||
LINK := $(CXX)
|
||||
DEF_FLAGS := -march=mips32 -mtune=mips32r2 -mhard-float -ffast-math -fomit-frame-pointer -fdata-sections
|
||||
DEF_FLAGS += -I. -Ideps -Ideps/stb -DDINGUX=1 -MMD
|
||||
DEF_FLAGS += -Wall -Wno-unused-variable
|
||||
DEF_FLAGS += -std=gnu99 -D_GNU_SOURCE
|
||||
LIBS := -ldl -lz -lrt -lcrypto -lssl -ludev -pthread
|
||||
CFLAGS :=
|
||||
CXXFLAGS := -fno-exceptions -fno-rtti -std=c++11 -D__STDC_CONSTANT_MACROS
|
||||
ASFLAGS :=
|
||||
LDFLAGS := -flto
|
||||
INCLUDE_DIRS = -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include
|
||||
LIBRARY_DIRS = -L/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/lib
|
||||
DEFINES := -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64 -UHAVE_STATIC_DUMMY
|
||||
DEFINES += -DHAVE_C99=1 -DHAVE_CXX=1 -DHAVE_OPENDINGUX_FBDEV=1
|
||||
DEFINES += -DHAVE_GETOPT_LONG=1 -DHAVE_STRCASESTR=1 -DHAVE_DYNAMIC=1
|
||||
DEFINES += -DHAVE_AL=1
|
||||
DEFINES += -DHAVE_ONLINE_UPDATER=1
|
||||
DEFINES += -DHAVE_UPDATE_ASSETS=1
|
||||
DEFINES += -DHAVE_UDEV=1
|
||||
|
||||
SDL_DINGUX_CFLAGS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config --cflags)
|
||||
SDL_DINGUX_LIBS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/sdl-config --libs)
|
||||
FREETYPE_CFLAGS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/freetype-config --cflags)
|
||||
FREETYPE_LIBS := $(shell /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/freetype-config --libs)
|
||||
AL_LIBS := -lopenal
|
||||
OPENGLES_CFLAGS := -DMESA_EGL_NO_X11_HEADERS
|
||||
OPENGLES_LIBS := -lGLESv2 -lEGL
|
||||
MMAP_LIBS = -lc
|
||||
|
||||
OBJDIR_BASE := obj-unix
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OBJDIR := $(OBJDIR_BASE)/debug
|
||||
DEF_FLAGS += -O0 -g -DDEBUG -D_DEBUG
|
||||
else
|
||||
OBJDIR := $(OBJDIR_BASE)/release
|
||||
DEF_FLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
include Makefile.common
|
||||
|
||||
DEF_FLAGS += $(INCLUDE_DIRS)
|
||||
CFLAGS += $(DEF_FLAGS)
|
||||
CXXFLAGS += $(DEF_FLAGS)
|
||||
|
||||
HEADERS = $(wildcard */*/*.h) $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
Q := @
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
define DESKTOP_ENTRY
|
||||
[Desktop Entry]
|
||||
Name=retroarch
|
||||
Comment=Retroarch
|
||||
Exec=retroarch
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Icon=retroarch
|
||||
Categories=emulators;
|
||||
X-OD-NeedsDownscaling=true
|
||||
endef
|
||||
export DESKTOP_ENTRY
|
||||
|
||||
all: $(TARGET) opk
|
||||
|
||||
-include $(RARCH_OBJ:.o=.d)
|
||||
|
||||
SYMBOL_MAP := -Wl,-Map=output.map
|
||||
|
||||
$(TARGET): $(RARCH_OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.m
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo OBJC $<),)
|
||||
$(CXX) $(OBJCFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
.FORCE:
|
||||
|
||||
$(OBJDIR)/git_version.o: git_version.c .FORCE
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(CC) $(CFLAGS) $(DEFINES) -MMD -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.S $(HEADERS)
|
||||
@mkdir -p $(dir $@)
|
||||
@$(if $(Q), $(shell echo echo AS $<),)
|
||||
$(CC) $(CFLAGS) $(ASFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR_BASE)
|
||||
rm -f $(TARGET)
|
||||
rm -f *.d
|
||||
rm -rf $(OPK_NAME)
|
||||
|
||||
opk: $(TARGET)
|
||||
echo "$$DESKTOP_ENTRY" > default.gcw0.desktop
|
||||
rm -f $(OPK_NAME)
|
||||
cp media/ico_src/icon32.png retroarch.png
|
||||
mksquashfs retroarch default.gcw0.desktop retroarch.png $(OPK_NAME) -all-root -no-xattrs -noappend -no-exports
|
||||
rm -f default.gcw0.desktop retroarch.png
|
||||
|
||||
.PHONY: all clean opk
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
||||
+2
-1
@@ -17,6 +17,7 @@ HAVE_CC_RESAMPLER = 1
|
||||
HAVE_EGL = 1
|
||||
HAVE_OPENGLES = 1
|
||||
HAVE_RJPEG = 0
|
||||
HAVE_RPNG = 1
|
||||
HAVE_EMSCRIPTEN = 1
|
||||
HAVE_MENU = 1
|
||||
HAVE_MENU_WIDGETS = 1
|
||||
@@ -37,7 +38,7 @@ OBJDIR := obj-emscripten
|
||||
|
||||
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
|
||||
|
||||
LIBS := -s USE_ZLIB=1 -s USE_LIBPNG=1
|
||||
LIBS := -s USE_ZLIB=1
|
||||
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
||||
--js-library emscripten/library_rwebaudio.js \
|
||||
|
||||
@@ -71,6 +71,7 @@ PPU_SRCS = griffin/griffin.c
|
||||
|
||||
#DEFINES += -DHAVE_VIDEO_LAYOUT
|
||||
DEFINES += -DHAVE_MENU -DHAVE_MENU_WIDGETS -DHAVE_RGUI -DHAVE_XMB -DHAVE_OZONE -DHAVE_LIBRETRODB -DHAVE_MATERIALUI -DHAVE_SHADERPIPELINE -DRARCH_INTERNAL -DMSB_FIRST -DHAVE_OVERLAY -DHAVE_CC_RESAMPLER -DHAVE_STB_VORBIS -DHAVE_STB_FONT -DHAVE_RUNAHEAD -DHAVE_DR_MP3 -DHAVE_DR_FLAC
|
||||
DEFINES += -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
|
||||
ifeq ($(DEX_BUILD), 1)
|
||||
DEFINES += -DDEX_BUILD
|
||||
|
||||
@@ -45,8 +45,8 @@ 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/file/file_path_io.c \
|
||||
libretro-common/lists/dir_list.c \
|
||||
libretro-common/lists/string_list.c \
|
||||
libretro-common/file/retro_dirent.c \
|
||||
|
||||
@@ -58,3 +58,18 @@ OBJS = $(PSP_OBJECTS)
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build.mak
|
||||
|
||||
pspsh-debug:
|
||||
pspsh -e reset
|
||||
read -p "Start debugger in VSCode and press any key to continue... \n" -n1 -s
|
||||
pspsh -e debug ./retroarchpsp.prx
|
||||
pspsh
|
||||
|
||||
pspsh-run:
|
||||
pspsh -e reset
|
||||
pspsh -e ./retroarchpsp.prx
|
||||
pspsh
|
||||
|
||||
debug: clean all pspsh-debug
|
||||
|
||||
run: clean all pspsh-run
|
||||
@@ -35,8 +35,8 @@ PSP_EBOOT_PIC1 = pkg/psp1/PIC1.PNG
|
||||
OBJS = frontend/frontend_salamander.o \
|
||||
frontend/frontend_driver.o \
|
||||
frontend/drivers/platform_psp.o \
|
||||
frontend/drivers/platform_null.o \
|
||||
libretro-common/file/file_path.o \
|
||||
libretro-common/file/file_path_io.o \
|
||||
libretro-common/string/stdstring.o \
|
||||
libretro-common/lists/string_list.o \
|
||||
libretro-common/lists/dir_list.o \
|
||||
|
||||
+4
-2
@@ -11,20 +11,22 @@ PC_DEVELOPMENT_UDP_PORT =
|
||||
|
||||
OBJ :=
|
||||
|
||||
DEFINES :=
|
||||
DEFINES := -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS
|
||||
INCDIRS :=
|
||||
|
||||
ifeq ($(GRIFFIN_BUILD), 1)
|
||||
OBJ += griffin/griffin.o
|
||||
DEFINES += -DHAVE_GRIFFIN=1
|
||||
DEFINES += -DHAVE_NEON -DHAVE_MENU -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB DEFINES -DHAVE_KEYMAPPER
|
||||
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_CC_RESAMPLER -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
|
||||
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_CC_RESAMPLER
|
||||
ifeq ($(DEBUG), 1)
|
||||
DEFINES += -DHAVE_NETLOGGER
|
||||
endif
|
||||
INCDIRS += -I. -Ideps/7zip -Ilibretro-common/include -Ilibretro-common/include/compat/zlib -Ideps/stb
|
||||
else
|
||||
|
||||
HAVE_UPDATE_ASSETS := 1
|
||||
HAVE_ONLINE_UPDATER := 1
|
||||
HAVE_NEON := 1
|
||||
HAVE_MATH_NEON := 1
|
||||
HAVE_FILTERS_BUILTIN := 1
|
||||
|
||||
@@ -35,8 +35,8 @@ CFLAGS += $(RARCH_DEFINES)
|
||||
OBJS = frontend/frontend_salamander.o \
|
||||
frontend/frontend_driver.o \
|
||||
frontend/drivers/platform_psp.o \
|
||||
frontend/drivers/platform_null.o \
|
||||
libretro-common/file/file_path.o \
|
||||
libretro-common/file/file_path_io.o \
|
||||
libretro-common/string/stdstring.o \
|
||||
libretro-common/lists/string_list.o \
|
||||
libretro-common/lists/dir_list.o \
|
||||
|
||||
@@ -55,8 +55,8 @@ OBJ = frontend/frontend_salamander.o \
|
||||
frontend/frontend_driver.o \
|
||||
frontend/drivers/platform_gx.o \
|
||||
frontend/drivers/platform_wii.o \
|
||||
frontend/drivers/platform_null.o \
|
||||
libretro-common/file/file_path.o \
|
||||
libretro-common/file/file_path_io.o \
|
||||
libretro-common/hash/rhash.o \
|
||||
libretro-common/string/stdstring.o \
|
||||
libretro-common/lists/string_list.o \
|
||||
|
||||
+1
-1
@@ -53,11 +53,11 @@ ifeq ($(SALAMANDER_BUILD),1)
|
||||
OBJ += frontend/frontend_salamander.o
|
||||
OBJ += frontend/frontend_driver.o
|
||||
OBJ += frontend/drivers/platform_wiiu.o
|
||||
OBJ += frontend/drivers/platform_null.o
|
||||
OBJ += libretro-common/encodings/encoding_utf.o
|
||||
OBJ += libretro-common/compat/compat_strcasestr.o
|
||||
OBJ += libretro-common/compat/fopen_utf8.o
|
||||
OBJ += libretro-common/file/file_path.o
|
||||
OBJ += libretro-common/file/file_path_io.o
|
||||
OBJ += libretro-common/string/stdstring.o
|
||||
OBJ += libretro-common/lists/string_list.o
|
||||
OBJ += libretro-common/lists/dir_list.o
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
@@ -12,16 +14,29 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../led_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
#ifndef __RETROARCH_ACCESSIBILITY_H
|
||||
#define __RETROARCH_ACCESSIBILITY_H
|
||||
|
||||
static void null_led_init(void) { }
|
||||
static void null_led_free(void) { }
|
||||
static void null_led_set(int led, int state) { }
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const led_driver_t null_led_driver = {
|
||||
null_led_init,
|
||||
null_led_free,
|
||||
null_led_set,
|
||||
"null"
|
||||
};
|
||||
#include <boolean.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
bool is_accessibility_enabled(void);
|
||||
|
||||
bool accessibility_speak_priority(const char* speak_text, int priority);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -372,7 +372,7 @@ static void *alsa_device_list_new(void *data)
|
||||
|
||||
n = hints;
|
||||
|
||||
while (*n != NULL)
|
||||
while (*n)
|
||||
{
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
|
||||
@@ -361,7 +361,7 @@ static void *alsa_thread_device_list_new(void *data)
|
||||
|
||||
n = hints;
|
||||
|
||||
while (*n != NULL)
|
||||
while (*n)
|
||||
{
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
|
||||
@@ -52,7 +52,9 @@ typedef struct coreaudio
|
||||
size_t buffer_size;
|
||||
} coreaudio_t;
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
static bool g_interrupted;
|
||||
#endif
|
||||
|
||||
static void coreaudio_free(void *data)
|
||||
{
|
||||
@@ -344,7 +346,11 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
while (!g_interrupted && size > 0)
|
||||
#else
|
||||
while (size > 0)
|
||||
#endif
|
||||
{
|
||||
size_t write_avail;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
bool playing;
|
||||
int16_t* l;
|
||||
int16_t* r;
|
||||
@@ -180,7 +180,7 @@ static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size)
|
||||
(((ctr->pos - ctr->playpos ) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)) ||
|
||||
(((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (size >> 2)))
|
||||
{
|
||||
if (ctr->nonblocking)
|
||||
if (ctr->nonblock)
|
||||
ctr->pos = (ctr->playpos + (CTR_CSND_AUDIO_COUNT >> 1)) & CTR_CSND_AUDIO_COUNT_MASK;
|
||||
else
|
||||
{
|
||||
@@ -189,7 +189,7 @@ static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size)
|
||||
retro_sleep(1);
|
||||
ctr_csnd_audio_update_playpos(ctr);
|
||||
}while (((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 1)
|
||||
|| (((ctr->pos - ctr->playpos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)));
|
||||
|| (((ctr->pos - ctr->playpos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ static void ctr_csnd_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
|
||||
if (ctr)
|
||||
ctr->nonblocking = state;
|
||||
ctr->nonblock = state;
|
||||
}
|
||||
|
||||
static bool ctr_csnd_audio_use_float(void *data)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
bool playing;
|
||||
int channel;
|
||||
ndspWaveBuf dsp_buf;
|
||||
@@ -102,7 +102,7 @@ static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
|
||||
(((ctr->pos - sample_pos ) & CTR_DSP_AUDIO_COUNT_MASK) < (CTR_DSP_AUDIO_COUNT >> 4)) ||
|
||||
(((sample_pos - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK) < (size >> 2)))
|
||||
{
|
||||
if (ctr->nonblocking)
|
||||
if (ctr->nonblock)
|
||||
ctr->pos = (sample_pos + (CTR_DSP_AUDIO_COUNT >> 1)) & CTR_DSP_AUDIO_COUNT_MASK;
|
||||
else
|
||||
{
|
||||
@@ -173,7 +173,7 @@ static void ctr_dsp_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
|
||||
if (ctr)
|
||||
ctr->nonblocking = state;
|
||||
ctr->nonblock = state;
|
||||
}
|
||||
|
||||
static bool ctr_dsp_audio_use_float(void *data)
|
||||
|
||||
+66
-36
@@ -94,30 +94,25 @@ struct audio_lock
|
||||
DWORD size2;
|
||||
};
|
||||
|
||||
static INLINE bool grab_region(dsound_t *ds, uint32_t write_ptr,
|
||||
struct audio_lock *region)
|
||||
static bool grab_region(dsound_t *ds, uint32_t write_ptr,
|
||||
struct audio_lock *region, HRESULT res)
|
||||
{
|
||||
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
||||
®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||
|
||||
if (res == DSERR_BUFFERLOST)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RARCH_WARN("[DirectSound error]: %s\n", "DSERR_BUFFERLOST");
|
||||
#endif
|
||||
if ((res = IDirectSoundBuffer_Restore(ds->dsb)) != DS_OK)
|
||||
return false;
|
||||
if ((res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
||||
®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0)) != DS_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res == DS_OK)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (res)
|
||||
{
|
||||
case DSERR_BUFFERLOST:
|
||||
RARCH_WARN("[DirectSound error]: %s\n", "DSERR_BUFFERLOST");
|
||||
break;
|
||||
case DSERR_INVALIDCALL:
|
||||
RARCH_WARN("[DirectSound error]: %s\n", "DSERR_INVALIDCALL");
|
||||
break;
|
||||
@@ -151,6 +146,7 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
|
||||
while (ds->thread_alive)
|
||||
{
|
||||
HRESULT res;
|
||||
bool is_pull = false;
|
||||
struct audio_lock region;
|
||||
DWORD read_ptr, avail, fifo_avail;
|
||||
@@ -175,11 +171,15 @@ static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!grab_region(ds, write_ptr, ®ion))
|
||||
if ((res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
||||
®ion.chunk1, ®ion.size1, ®ion.chunk2, ®ion.size2, 0)) != DS_OK)
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
SetEvent(ds->event);
|
||||
break;
|
||||
if (!grab_region(ds, write_ptr, ®ion, res))
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
SetEvent(ds->event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fifo_avail < CHUNK_SIZE)
|
||||
@@ -328,6 +328,19 @@ static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOI
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void dsound_set_wavefmt(WAVEFORMATEX *wfx,
|
||||
unsigned channels, unsigned samplerate)
|
||||
{
|
||||
wfx->wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx->nBlockAlign = channels * sizeof(int16_t);
|
||||
wfx->wBitsPerSample = 16;
|
||||
|
||||
wfx->nChannels = channels;
|
||||
wfx->nSamplesPerSec = samplerate;
|
||||
wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
|
||||
wfx->cbSize = 0;
|
||||
}
|
||||
|
||||
static void *dsound_init(const char *dev, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
@@ -390,12 +403,7 @@ static void *dsound_init(const char *dev, unsigned rate, unsigned latency,
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = rate;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = 2 * sizeof(int16_t);
|
||||
wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t);
|
||||
dsound_set_wavefmt(&wfx, 2, rate);
|
||||
|
||||
ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000;
|
||||
ds->buffer_size /= CHUNK_SIZE;
|
||||
@@ -496,27 +504,49 @@ static ssize_t dsound_write(void *data, const void *buf_, size_t size)
|
||||
if (!ds->thread_alive)
|
||||
return -1;
|
||||
|
||||
while (size > 0)
|
||||
if (ds->nonblock)
|
||||
{
|
||||
size_t avail;
|
||||
if (size > 0)
|
||||
{
|
||||
size_t avail;
|
||||
|
||||
EnterCriticalSection(&ds->crit);
|
||||
avail = fifo_write_avail(ds->buffer);
|
||||
if (avail > size)
|
||||
avail = size;
|
||||
EnterCriticalSection(&ds->crit);
|
||||
avail = fifo_write_avail(ds->buffer);
|
||||
if (avail > size)
|
||||
avail = size;
|
||||
|
||||
fifo_write(ds->buffer, buf, avail);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
fifo_write(ds->buffer, buf, avail);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
|
||||
buf += avail;
|
||||
size -= avail;
|
||||
written += avail;
|
||||
buf += avail;
|
||||
size -= avail;
|
||||
written += avail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (size > 0)
|
||||
{
|
||||
size_t avail;
|
||||
|
||||
if (ds->nonblock || !ds->thread_alive)
|
||||
break;
|
||||
EnterCriticalSection(&ds->crit);
|
||||
avail = fifo_write_avail(ds->buffer);
|
||||
if (avail > size)
|
||||
avail = size;
|
||||
|
||||
if (avail == 0)
|
||||
WaitForSingleObject(ds->event, INFINITE);
|
||||
fifo_write(ds->buffer, buf, avail);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
|
||||
buf += avail;
|
||||
size -= avail;
|
||||
written += avail;
|
||||
|
||||
if (!ds->thread_alive)
|
||||
break;
|
||||
|
||||
if (avail == 0)
|
||||
WaitForSingleObject(ds->event, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
|
||||
@@ -166,7 +166,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
#endif
|
||||
|
||||
jd->client = jack_client_open("RetroArch", JackNullOption, NULL);
|
||||
if (jd->client == NULL)
|
||||
if (!jd->client)
|
||||
goto error;
|
||||
|
||||
*new_rate = jack_get_sample_rate(jd->client);
|
||||
@@ -176,14 +176,14 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
|
||||
jd->ports[0] = jack_port_register(jd->client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||
jd->ports[1] = jack_port_register(jd->client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||
if (jd->ports[0] == NULL || jd->ports[1] == NULL)
|
||||
if (!jd->ports[0] || !jd->ports[1])
|
||||
{
|
||||
RARCH_ERR("[JACK]: Failed to register ports.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
|
||||
if (jports == NULL)
|
||||
if (!jports)
|
||||
{
|
||||
RARCH_ERR("[JACK]: Failed to get ports.\n");
|
||||
goto error;
|
||||
@@ -196,7 +196,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
jd->buffer[i] = jack_ringbuffer_create(bufsize);
|
||||
if (jd->buffer[i] == NULL)
|
||||
if (!jd->buffer[i])
|
||||
{
|
||||
RARCH_ERR("[JACK]: Failed to create buffers.\n");
|
||||
goto error;
|
||||
@@ -229,7 +229,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency,
|
||||
error:
|
||||
for (i = 0; i < parsed; i++)
|
||||
free(dest_ports[i]);
|
||||
if (jports != NULL)
|
||||
if (jports)
|
||||
jack_free(jports);
|
||||
free(jd);
|
||||
return NULL;
|
||||
@@ -334,14 +334,14 @@ static void ja_free(void *data)
|
||||
|
||||
jd->shutdown = true;
|
||||
|
||||
if (jd->client != NULL)
|
||||
if (jd->client)
|
||||
{
|
||||
jack_deactivate(jd->client);
|
||||
jack_client_close(jd->client);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
if (jd->buffer[i] != NULL)
|
||||
if (jd->buffer[i])
|
||||
jack_ringbuffer_free(jd->buffer[i]);
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../retroarch.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
static void *null_audio_init(const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
RARCH_ERR("Using the null audio driver. RetroArch will be silent.\n");
|
||||
|
||||
(void)device;
|
||||
(void)rate;
|
||||
(void)latency;
|
||||
(void)new_rate;
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
static void null_audio_free(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static ssize_t null_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
(void)data;
|
||||
(void)buf;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool null_audio_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_audio_alive(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_audio_start(void *data, bool is_shutdown)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void null_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
(void)data;
|
||||
(void)state;
|
||||
}
|
||||
|
||||
static bool null_audio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t null_audio_write_avail(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
audio_driver_t audio_null = {
|
||||
null_audio_init,
|
||||
null_audio_write,
|
||||
null_audio_stop,
|
||||
null_audio_start,
|
||||
null_audio_alive,
|
||||
null_audio_set_nonblock_state,
|
||||
null_audio_free,
|
||||
null_audio_use_float,
|
||||
"null",
|
||||
NULL,
|
||||
NULL,
|
||||
null_audio_write_avail,
|
||||
NULL
|
||||
};
|
||||
@@ -115,7 +115,7 @@ static void *al_init(const char *device, unsigned rate, unsigned latency,
|
||||
|
||||
al->buffers = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->res_buf = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
if (al->buffers == NULL || al->res_buf == NULL)
|
||||
if (!al->buffers || !al->res_buf)
|
||||
goto error;
|
||||
|
||||
alGenSources(1, &al->source);
|
||||
|
||||
+56
-26
@@ -238,45 +238,75 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
|
||||
size_t written = 0;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
while (size)
|
||||
if (sl->nonblock)
|
||||
{
|
||||
size_t avail_write;
|
||||
|
||||
if (sl->nonblock)
|
||||
while (size)
|
||||
{
|
||||
size_t avail_write;
|
||||
|
||||
if (sl->buffered_blocks == sl->buf_count)
|
||||
break;
|
||||
|
||||
avail_write = MIN(sl->buf_size - sl->buffer_ptr, size);
|
||||
|
||||
if (avail_write)
|
||||
{
|
||||
memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
|
||||
sl->buffer_ptr += avail_write;
|
||||
buf += avail_write;
|
||||
size -= avail_write;
|
||||
written += avail_write;
|
||||
}
|
||||
|
||||
if (sl->buffer_ptr >= sl->buf_size)
|
||||
{
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
|
||||
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
|
||||
__sync_fetch_and_add(&sl->buffered_blocks, 1);
|
||||
sl->buffer_ptr = 0;
|
||||
|
||||
if (res != SL_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
while (size)
|
||||
{
|
||||
size_t avail_write;
|
||||
|
||||
slock_lock(sl->lock);
|
||||
while (sl->buffered_blocks == sl->buf_count)
|
||||
scond_wait(sl->cond, sl->lock);
|
||||
slock_unlock(sl->lock);
|
||||
}
|
||||
|
||||
avail_write = MIN(sl->buf_size - sl->buffer_ptr, size);
|
||||
avail_write = MIN(sl->buf_size - sl->buffer_ptr, size);
|
||||
|
||||
if (avail_write)
|
||||
{
|
||||
memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
|
||||
sl->buffer_ptr += avail_write;
|
||||
buf += avail_write;
|
||||
size -= avail_write;
|
||||
written += avail_write;
|
||||
}
|
||||
|
||||
if (sl->buffer_ptr >= sl->buf_size)
|
||||
{
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
|
||||
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
|
||||
__sync_fetch_and_add(&sl->buffered_blocks, 1);
|
||||
sl->buffer_ptr = 0;
|
||||
|
||||
if (res != SL_RESULT_SUCCESS)
|
||||
if (avail_write)
|
||||
{
|
||||
RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
|
||||
return -1;
|
||||
memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
|
||||
sl->buffer_ptr += avail_write;
|
||||
buf += avail_write;
|
||||
size -= avail_write;
|
||||
written += avail_write;
|
||||
}
|
||||
|
||||
if (sl->buffer_ptr >= sl->buf_size)
|
||||
{
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
|
||||
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
|
||||
__sync_fetch_and_add(&sl->buffered_blocks, 1);
|
||||
sl->buffer_ptr = 0;
|
||||
|
||||
if (res != SL_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
|
||||
typedef struct ps2_audio
|
||||
{
|
||||
bool nonblocking;
|
||||
/* TODO/FIXME - nonblock is not implemented */
|
||||
bool nonblock;
|
||||
bool running;
|
||||
|
||||
} ps2_audio_t;
|
||||
@@ -39,11 +40,11 @@ static void audioConfigure(ps2_audio_t *ps2, unsigned rate)
|
||||
int err;
|
||||
struct audsrv_fmt_t format;
|
||||
|
||||
format.bits = AUDIO_BITS;
|
||||
format.freq = rate;
|
||||
format.bits = AUDIO_BITS;
|
||||
format.freq = rate;
|
||||
format.channels = AUDIO_CHANNELS;
|
||||
|
||||
err = audsrv_set_format(&format);
|
||||
err = audsrv_set_format(&format);
|
||||
|
||||
if (err)
|
||||
{
|
||||
@@ -82,15 +83,12 @@ static void ps2_audio_free(void *data)
|
||||
|
||||
static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
int bytes_sent;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (!ps2->running)
|
||||
return -1;
|
||||
|
||||
bytes_sent = audsrv_play_audio(buf, size);
|
||||
|
||||
return bytes_sent;
|
||||
return audsrv_play_audio(buf, size);
|
||||
}
|
||||
|
||||
static bool ps2_audio_alive(void *data)
|
||||
@@ -134,7 +132,7 @@ static void ps2_audio_set_nonblock_state(void *data, bool toggle)
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2)
|
||||
ps2->nonblocking = toggle;
|
||||
ps2->nonblock = toggle;
|
||||
}
|
||||
|
||||
static bool ps2_audio_use_float(void *data)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
typedef struct
|
||||
{
|
||||
uint32_t audio_port;
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
bool started;
|
||||
volatile bool quit_thread;
|
||||
fifo_buffer_t *buffer;
|
||||
@@ -150,7 +150,7 @@ static ssize_t ps3_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
ps3_audio_t *aud = data;
|
||||
|
||||
if (aud->nonblocking)
|
||||
if (aud->nonblock)
|
||||
{
|
||||
if (fifo_write_avail(aud->buffer) < size)
|
||||
return 0;
|
||||
@@ -200,7 +200,7 @@ static void ps3_audio_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
ps3_audio_t *aud = data;
|
||||
if (aud)
|
||||
aud->nonblocking = toggle;
|
||||
aud->nonblock = toggle;
|
||||
}
|
||||
|
||||
static void ps3_audio_free(void *data)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
typedef struct psp_audio
|
||||
{
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
|
||||
uint32_t* buffer;
|
||||
uint32_t* zeroBuffer;
|
||||
@@ -167,7 +167,7 @@ static void *psp_audio_init(const char *device,
|
||||
psp->cond_lock = slock_new();
|
||||
psp->cond = scond_new();
|
||||
|
||||
psp->nonblocking = false;
|
||||
psp->nonblock = false;
|
||||
psp->running = true;
|
||||
psp->worker_thread = sthread_create(audioMainLoop, psp);
|
||||
|
||||
@@ -202,18 +202,18 @@ static void psp_audio_free(void *data)
|
||||
|
||||
static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
uint16_t write_pos = psp->write_pos;
|
||||
uint16_t sampleCount = size / sizeof(uint32_t);
|
||||
|
||||
if (!psp->running)
|
||||
return -1;
|
||||
|
||||
if (psp->nonblocking)
|
||||
if (psp->nonblock)
|
||||
{
|
||||
if (AUDIO_BUFFER_SIZE - ((uint16_t)
|
||||
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
|
||||
return 0;
|
||||
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
slock_lock(psp->cond_lock);
|
||||
@@ -287,7 +287,7 @@ static void psp_audio_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
psp_audio_t* psp = (psp_audio_t*)data;
|
||||
if (psp)
|
||||
psp->nonblocking = toggle;
|
||||
psp->nonblock = toggle;
|
||||
}
|
||||
|
||||
static bool psp_audio_use_float(void *data)
|
||||
|
||||
@@ -165,7 +165,7 @@ static bool rs_stop(void *data)
|
||||
|
||||
static void rs_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd->nonblock = state;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,27 +92,25 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
if (!swa->current_buffer)
|
||||
{
|
||||
if (swa->blocking)
|
||||
/* no buffer, nonblocking... */
|
||||
if (!swa->blocking)
|
||||
return 0;
|
||||
|
||||
while (!swa->current_buffer)
|
||||
{
|
||||
while(swa->current_buffer == NULL)
|
||||
{
|
||||
uint32_t handle_idx = 0;
|
||||
num = 0;
|
||||
uint32_t handle_idx = 0;
|
||||
num = 0;
|
||||
|
||||
#ifdef HAVE_LIBNX
|
||||
if (audoutWaitPlayFinish(&swa->current_buffer, &num, U64_MAX) != 0) { }
|
||||
if (audoutWaitPlayFinish(&swa->current_buffer, &num, U64_MAX) != 0) { }
|
||||
#else
|
||||
svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333);
|
||||
svcResetSignal(swa->event);
|
||||
svcWaitSynchronization(&handle_idx, &swa->event, 1, 33333333);
|
||||
svcResetSignal(swa->event);
|
||||
|
||||
if (switch_audio_ipc_output_get_released_buffer(swa, num) != 0)
|
||||
return -1;
|
||||
if (switch_audio_ipc_output_get_released_buffer(swa, num) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
/* no buffer, nonblocking... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
swa->current_buffer->data_size = 0;
|
||||
@@ -297,7 +295,7 @@ static void *switch_audio_init(const char *device,
|
||||
swa->buffers[i].data_offset = 0;
|
||||
swa->buffers[i].buffer = memalign(0x1000, switch_audio_buffer_size(NULL));
|
||||
|
||||
if (swa->buffers[i].buffer == NULL)
|
||||
if (!swa->buffers[i].buffer)
|
||||
goto fail_audio_output;
|
||||
|
||||
memset(swa->buffers[i].buffer, 0, switch_audio_buffer_size(NULL));
|
||||
@@ -306,7 +304,7 @@ static void *switch_audio_init(const char *device,
|
||||
swa->buffers[i].unknown = 0;
|
||||
swa->buffers[i].sample_data = alloc_pages(sample_buffer_size, switch_audio_buffer_size(NULL), NULL);
|
||||
|
||||
if (swa->buffers[i].sample_data == NULL)
|
||||
if (!swa->buffers[i].sample_data)
|
||||
goto fail_audio_output;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ typedef Thread compat_thread;
|
||||
typedef CondVar compat_condvar;
|
||||
|
||||
#define compat_thread_create(thread, func, data, stack_size, prio, cpu) \
|
||||
threadCreate(thread, func, data, stack_size, prio, cpu)
|
||||
threadCreate(thread, func, data, NULL, stack_size, prio, cpu)
|
||||
#define compat_thread_start(thread) \
|
||||
threadStart(thread)
|
||||
#define compat_thread_join(thread) \
|
||||
|
||||
@@ -42,7 +42,8 @@ static const AudioRendererConfig audio_renderer_config =
|
||||
.num_mix_buffers = 2,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
AudioDriver drv;
|
||||
void* mempool;
|
||||
AudioDriverWaveBuf wavebufs[BUFFER_COUNT];
|
||||
@@ -52,10 +53,11 @@ typedef struct {
|
||||
size_t buffer_size;
|
||||
size_t samples;
|
||||
Mutex update_lock;
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
} libnx_audren_t;
|
||||
|
||||
static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned latency,
|
||||
static void *libnx_audren_audio_init(
|
||||
const char *device, unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
@@ -79,14 +81,14 @@ static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned
|
||||
real_latency = MAX(5, latency);
|
||||
RARCH_LOG("[Audio]: real_latency is %u\n", real_latency);
|
||||
|
||||
aud->nonblocking = !block_frames;
|
||||
aud->buffer_size = (real_latency * sample_rate / 1000);
|
||||
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
|
||||
aud->nonblock = !block_frames;
|
||||
aud->buffer_size = (real_latency * sample_rate / 1000);
|
||||
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
|
||||
aud->current_size = 0;
|
||||
*new_rate = sample_rate;
|
||||
*new_rate = sample_rate;
|
||||
|
||||
mempool_size = (aud->buffer_size * BUFFER_COUNT + (AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1);
|
||||
aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size);
|
||||
mempool_size = (aud->buffer_size * BUFFER_COUNT + (AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1);
|
||||
aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size);
|
||||
if (!aud->mempool)
|
||||
{
|
||||
RARCH_ERR("[Audio]: mempool alloc failed\n");
|
||||
@@ -94,14 +96,14 @@ static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned
|
||||
}
|
||||
|
||||
rc = audrenInitialize(&audio_renderer_config);
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrenInitialize: %x\n", rc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = audrvCreate(&aud->drv, &audio_renderer_config, num_channels);
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrvCreate: %x\n", rc);
|
||||
goto fail_init;
|
||||
@@ -123,7 +125,7 @@ static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned
|
||||
audrvDeviceSinkAdd(&aud->drv, AUDREN_DEFAULT_DEVICE_NAME, num_channels, sink_channels);
|
||||
|
||||
rc = audrenStartAudioRenderer();
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrenStartAudioRenderer: %x\n", rc);
|
||||
}
|
||||
@@ -150,9 +152,7 @@ fail:
|
||||
if (aud)
|
||||
{
|
||||
if (aud->mempool)
|
||||
{
|
||||
free(aud->mempool);
|
||||
}
|
||||
|
||||
free(aud);
|
||||
}
|
||||
@@ -176,24 +176,25 @@ static ssize_t libnx_audren_audio_get_free_wavebuf_idx(libnx_audren_t* aud)
|
||||
|
||||
for (i = 0; i < BUFFER_COUNT; i++)
|
||||
{
|
||||
if (aud->wavebufs[i].state == AudioDriverWaveBufState_Free
|
||||
if (
|
||||
aud->wavebufs[i].state == AudioDriverWaveBufState_Free
|
||||
|| aud->wavebufs[i].state == AudioDriverWaveBufState_Done)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, size_t size)
|
||||
static size_t libnx_audren_audio_append(
|
||||
libnx_audren_t* aud, const void *buf, size_t size)
|
||||
{
|
||||
void *dstbuf = NULL;
|
||||
ssize_t free_idx = -1;
|
||||
|
||||
if(!aud->current_wavebuf)
|
||||
if (!aud->current_wavebuf)
|
||||
{
|
||||
free_idx = libnx_audren_audio_get_free_wavebuf_idx(aud);
|
||||
if(free_idx == -1)
|
||||
if (free_idx == -1)
|
||||
return 0;
|
||||
|
||||
aud->current_wavebuf = &aud->wavebufs[free_idx];
|
||||
@@ -201,18 +202,16 @@ static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, si
|
||||
aud->current_size = 0;
|
||||
}
|
||||
|
||||
if(size > aud->buffer_size - aud->current_size)
|
||||
{
|
||||
if (size > aud->buffer_size - aud->current_size)
|
||||
size = aud->buffer_size - aud->current_size;
|
||||
}
|
||||
|
||||
void *dstbuf = aud->current_pool_ptr + aud->current_size;
|
||||
dstbuf = aud->current_pool_ptr + aud->current_size;
|
||||
memcpy(dstbuf, buf, size);
|
||||
armDCacheFlush(dstbuf, size);
|
||||
|
||||
aud->current_size += size;
|
||||
|
||||
if(aud->current_size == aud->buffer_size)
|
||||
if (aud->current_size == aud->buffer_size)
|
||||
{
|
||||
audrvVoiceAddWaveBuf(&aud->drv, 0, aud->current_wavebuf);
|
||||
|
||||
@@ -231,24 +230,32 @@ static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, si
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t libnx_audren_audio_write(void *data, const void *buf, size_t size)
|
||||
static ssize_t libnx_audren_audio_write(void *data,
|
||||
const void *buf, size_t size)
|
||||
{
|
||||
libnx_audren_t *aud = (libnx_audren_t*)data;
|
||||
size_t written = 0;
|
||||
size_t written = 0;
|
||||
|
||||
if (!aud)
|
||||
return -1;
|
||||
|
||||
while(written < size)
|
||||
if (aud->nonblock)
|
||||
{
|
||||
written += libnx_audren_audio_append(aud, buf + written, size - written);
|
||||
if(written != size)
|
||||
while(written < size)
|
||||
{
|
||||
if(aud->nonblocking)
|
||||
{
|
||||
written += libnx_audren_audio_append(
|
||||
aud, buf + written, size - written);
|
||||
if (written != size)
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(written < size)
|
||||
{
|
||||
written += libnx_audren_audio_append(
|
||||
aud, buf + written, size - written);
|
||||
if (written != size)
|
||||
{
|
||||
mutexLock(&aud->update_lock);
|
||||
audrvUpdate(&aud->drv);
|
||||
@@ -341,7 +348,7 @@ static void libnx_audren_audio_set_nonblock_state(void *data, bool state)
|
||||
if (!aud)
|
||||
return;
|
||||
|
||||
aud->nonblocking = state;
|
||||
aud->nonblock = state;
|
||||
}
|
||||
|
||||
audio_driver_t audio_switch_libnx_audren = {
|
||||
|
||||
@@ -43,13 +43,14 @@ static const AudioRendererConfig audio_renderer_config =
|
||||
.num_mix_buffers = 2,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
AudioDriver drv;
|
||||
void* mempool;
|
||||
AudioDriverWaveBuf wavebufs[BUFFER_COUNT];
|
||||
size_t buffer_size;
|
||||
size_t samples;
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
|
||||
fifo_buffer_t* fifo;
|
||||
Mutex fifo_lock;
|
||||
@@ -63,21 +64,21 @@ typedef struct {
|
||||
|
||||
static void thread_job(void* data)
|
||||
{
|
||||
libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data;
|
||||
size_t available = 0;
|
||||
size_t current_size = 0;
|
||||
size_t written_tmp = 0;
|
||||
AudioDriverWaveBuf* current_wavebuf = NULL;
|
||||
void* current_pool_ptr = NULL;
|
||||
void* dstbuf = NULL;
|
||||
unsigned i;
|
||||
libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data;
|
||||
size_t available = 0;
|
||||
size_t current_size = 0;
|
||||
size_t written_tmp = 0;
|
||||
AudioDriverWaveBuf* current_wavebuf = NULL;
|
||||
void* current_pool_ptr = NULL;
|
||||
void* dstbuf = NULL;
|
||||
|
||||
if (!aud)
|
||||
return;
|
||||
|
||||
while(aud->running)
|
||||
while (aud->running)
|
||||
{
|
||||
if(!current_wavebuf)
|
||||
if (!current_wavebuf)
|
||||
{
|
||||
for (i = 0; i < BUFFER_COUNT; i++)
|
||||
{
|
||||
@@ -92,19 +93,17 @@ static void thread_job(void* data)
|
||||
}
|
||||
}
|
||||
|
||||
if(current_wavebuf)
|
||||
if (current_wavebuf)
|
||||
{
|
||||
mutexLock(&aud->fifo_lock);
|
||||
available = aud->paused ? 0 : fifo_read_avail(aud->fifo);
|
||||
written_tmp = MIN(available, aud->buffer_size - current_size);
|
||||
dstbuf = current_pool_ptr + current_size;
|
||||
if(written_tmp > 0)
|
||||
{
|
||||
if (written_tmp > 0)
|
||||
fifo_read(aud->fifo, dstbuf, written_tmp);
|
||||
}
|
||||
mutexUnlock(&aud->fifo_lock);
|
||||
|
||||
if(written_tmp > 0)
|
||||
if (written_tmp > 0)
|
||||
{
|
||||
condvarWakeAll(&aud->fifo_condvar);
|
||||
|
||||
@@ -112,7 +111,7 @@ static void thread_job(void* data)
|
||||
armDCacheFlush(dstbuf, written_tmp);
|
||||
}
|
||||
|
||||
if(current_size == aud->buffer_size)
|
||||
if (current_size == aud->buffer_size)
|
||||
{
|
||||
audrvVoiceAddWaveBuf(&aud->drv, 0, current_wavebuf);
|
||||
|
||||
@@ -157,17 +156,19 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
|
||||
goto fail;
|
||||
}
|
||||
|
||||
real_latency = MAX(latency, 5);
|
||||
real_latency = MAX(latency, 5);
|
||||
RARCH_LOG("[Audio]: real_latency is %u\n", real_latency);
|
||||
|
||||
aud->running = true;
|
||||
aud->paused = false;
|
||||
aud->nonblocking = !block_frames;
|
||||
aud->running = true;
|
||||
aud->paused = false;
|
||||
aud->nonblock = !block_frames;
|
||||
aud->buffer_size = (real_latency * sample_rate / 1000);
|
||||
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
|
||||
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
|
||||
|
||||
mempool_size = (aud->buffer_size * BUFFER_COUNT +
|
||||
(AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1);
|
||||
aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size);
|
||||
|
||||
mempool_size = (aud->buffer_size * BUFFER_COUNT + (AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1);
|
||||
aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size);
|
||||
if (!aud->mempool)
|
||||
{
|
||||
RARCH_ERR("[Audio]: mempool alloc failed\n");
|
||||
@@ -175,43 +176,44 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
|
||||
}
|
||||
|
||||
rc = audrenInitialize(&audio_renderer_config);
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrenInitialize: %x\n", rc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = audrvCreate(&aud->drv, &audio_renderer_config, num_channels);
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrvCreate: %x\n", rc);
|
||||
goto fail_init;
|
||||
}
|
||||
|
||||
for(i = 0; i < BUFFER_COUNT; i++)
|
||||
for (i = 0; i < BUFFER_COUNT; i++)
|
||||
{
|
||||
aud->wavebufs[i].data_raw = aud->mempool;
|
||||
aud->wavebufs[i].size = mempool_size;
|
||||
aud->wavebufs[i].data_raw = aud->mempool;
|
||||
aud->wavebufs[i].size = mempool_size;
|
||||
aud->wavebufs[i].start_sample_offset = i * aud->samples;
|
||||
aud->wavebufs[i].end_sample_offset = aud->wavebufs[i].start_sample_offset + aud->samples;
|
||||
aud->wavebufs[i].end_sample_offset = aud->wavebufs[i].start_sample_offset + aud->samples;
|
||||
}
|
||||
|
||||
mpid = audrvMemPoolAdd(&aud->drv, aud->mempool, mempool_size);
|
||||
audrvMemPoolAttach(&aud->drv, mpid);
|
||||
|
||||
audrvDeviceSinkAdd(&aud->drv, AUDREN_DEFAULT_DEVICE_NAME, num_channels, sink_channels);
|
||||
audrvDeviceSinkAdd(&aud->drv, AUDREN_DEFAULT_DEVICE_NAME,
|
||||
num_channels, sink_channels);
|
||||
|
||||
rc = audrenStartAudioRenderer();
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: audrenStartAudioRenderer: %x\n", rc);
|
||||
}
|
||||
|
||||
audrvVoiceInit(&aud->drv, 0, num_channels, PcmFormat_Int16, sample_rate);
|
||||
audrvVoiceSetDestinationMix(&aud->drv, 0, AUDREN_FINAL_MIX_ID);
|
||||
for(i = 0; i < num_channels; i++)
|
||||
for (i = 0; i < num_channels; i++)
|
||||
{
|
||||
for(j = 0; j < num_channels; j++)
|
||||
for (j = 0; j < num_channels; j++)
|
||||
{
|
||||
audrvVoiceSetMixFactor(&aud->drv, 0, i == j ? 1.0f : 0.0f, i, j);
|
||||
}
|
||||
@@ -229,15 +231,17 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
|
||||
mutexInit(&aud->fifo_condlock);
|
||||
|
||||
svcGetThreadPriority(&thread_priority, CUR_THREAD_HANDLE);
|
||||
rc = threadCreate(&aud->thread, &thread_job, (void*)aud, thread_stack_size, thread_priority - 1, thread_preferred_cpu);
|
||||
if(R_FAILED(rc))
|
||||
rc = threadCreate(&aud->thread, &thread_job,
|
||||
(void*)aud, NULL, thread_stack_size,
|
||||
thread_priority - 1, thread_preferred_cpu);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: threadCreate: %x\n", rc);
|
||||
goto fail_drv;
|
||||
}
|
||||
|
||||
rc = threadStart(&aud->thread);
|
||||
if(R_FAILED(rc))
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
RARCH_ERR("[Audio]: threadStart: %x\n", rc);
|
||||
threadClose(&aud->thread);
|
||||
@@ -258,9 +262,7 @@ fail:
|
||||
if (aud)
|
||||
{
|
||||
if (aud->mempool)
|
||||
{
|
||||
free(aud->mempool);
|
||||
}
|
||||
|
||||
free(aud);
|
||||
}
|
||||
@@ -278,7 +280,8 @@ static size_t libnx_audren_thread_audio_buffer_size(void *data)
|
||||
return aud->buffer_size;
|
||||
}
|
||||
|
||||
static ssize_t libnx_audren_thread_audio_write(void *data, const void *buf, size_t size)
|
||||
static ssize_t libnx_audren_thread_audio_write(void *data,
|
||||
const void *buf, size_t size)
|
||||
{
|
||||
libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data;
|
||||
size_t available, written, written_tmp;
|
||||
@@ -286,18 +289,16 @@ static ssize_t libnx_audren_thread_audio_write(void *data, const void *buf, size
|
||||
if (!aud || !aud->running)
|
||||
return -1;
|
||||
|
||||
if(aud->paused)
|
||||
if (aud->paused)
|
||||
return 0;
|
||||
|
||||
if(aud->nonblocking)
|
||||
if (aud->nonblock)
|
||||
{
|
||||
mutexLock(&aud->fifo_lock);
|
||||
available = fifo_write_avail(aud->fifo);
|
||||
written = MIN(available, size);
|
||||
if(written > 0)
|
||||
{
|
||||
if (written > 0)
|
||||
fifo_write(aud->fifo, buf, written);
|
||||
}
|
||||
mutexUnlock(&aud->fifo_lock);
|
||||
}
|
||||
else
|
||||
@@ -307,7 +308,7 @@ static ssize_t libnx_audren_thread_audio_write(void *data, const void *buf, size
|
||||
{
|
||||
mutexLock(&aud->fifo_lock);
|
||||
available = fifo_write_avail(aud->fifo);
|
||||
if(available)
|
||||
if (available)
|
||||
{
|
||||
written_tmp = MIN(size - written, available);
|
||||
fifo_write(aud->fifo, (const char*)buf + written, written_tmp);
|
||||
@@ -419,7 +420,7 @@ static void libnx_audren_thread_audio_set_nonblock_state(void *data, bool state)
|
||||
if (!aud)
|
||||
return;
|
||||
|
||||
aud->nonblocking = state;
|
||||
aud->nonblock = state;
|
||||
}
|
||||
|
||||
audio_driver_t audio_switch_libnx_audren_thread = {
|
||||
|
||||
@@ -53,7 +53,7 @@ typedef struct
|
||||
size_t fifoSize;
|
||||
|
||||
volatile bool running;
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
|
||||
compat_audio_out_buffer buffers[AUDIO_BUFFER_COUNT];
|
||||
@@ -152,7 +152,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
|
||||
return NULL;
|
||||
|
||||
swa->running = true;
|
||||
swa->nonblocking = true;
|
||||
swa->nonblock = true;
|
||||
swa->is_paused = true;
|
||||
swa->latency = MAX(latency, 8);
|
||||
|
||||
@@ -217,7 +217,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
|
||||
swa->buffers[i].data_size = swa->buffers[i].buffer_size;
|
||||
swa->buffers[i].buffer = memalign(0x1000, swa->buffers[i].buffer_size);
|
||||
|
||||
if (swa->buffers[i].buffer == NULL)
|
||||
if (!swa->buffers[i].buffer)
|
||||
goto fail;
|
||||
|
||||
memset(swa->buffers[i].buffer, 0, swa->buffers[i].buffer_size);
|
||||
@@ -228,7 +228,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
|
||||
swa->buffers[i].data_size = swa->buffers[i].buffer_size;
|
||||
swa->buffers[i].sample_data = alloc_pages(swa->buffers[i].buffer_size, swa->buffers[i].buffer_size, NULL);
|
||||
|
||||
if (swa->buffers[i].sample_data == NULL)
|
||||
if (!swa->buffers[i].sample_data)
|
||||
goto fail_audio_output;
|
||||
|
||||
memset(swa->buffers[i].sample_data, 0, swa->buffers[i].buffer_size);
|
||||
@@ -345,7 +345,7 @@ static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t siz
|
||||
if (!swa || !swa->running)
|
||||
return 0;
|
||||
|
||||
if (swa->nonblocking)
|
||||
if (swa->nonblock)
|
||||
{
|
||||
compat_mutex_lock(&swa->fifoLock);
|
||||
avail = fifo_write_avail(swa->fifo);
|
||||
@@ -397,7 +397,7 @@ static void switch_thread_audio_set_nonblock_state(void *data, bool state)
|
||||
switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
|
||||
|
||||
if (swa)
|
||||
swa->nonblocking = state;
|
||||
swa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool switch_thread_audio_use_float(void *data)
|
||||
|
||||
@@ -808,7 +808,7 @@ static unsigned int pcm_get_channels(const struct pcm *pcm)
|
||||
* */
|
||||
static const struct pcm_config * pcm_get_config(const struct pcm *pcm)
|
||||
{
|
||||
if (pcm == NULL)
|
||||
if (!pcm)
|
||||
return NULL;
|
||||
return &pcm->config;
|
||||
}
|
||||
@@ -929,7 +929,7 @@ static int pcm_set_config(struct pcm *pcm, const struct pcm_config *config)
|
||||
struct snd_pcm_sw_params sparams;
|
||||
struct snd_pcm_hw_params params;
|
||||
|
||||
if (pcm == NULL)
|
||||
if (!pcm)
|
||||
return -EFAULT;
|
||||
|
||||
if (config)
|
||||
@@ -1293,7 +1293,7 @@ static int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
|
||||
*/
|
||||
static int pcm_is_ready(const struct pcm *pcm)
|
||||
{
|
||||
if (pcm != NULL)
|
||||
if (pcm)
|
||||
return pcm->fd >= 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -1582,7 +1582,7 @@ static const struct pcm_mask *pcm_params_get_mask(const struct pcm_params *pcm_p
|
||||
{
|
||||
int p;
|
||||
struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
|
||||
if (params == NULL)
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
p = pcm_param_to_alsa(param);
|
||||
@@ -2185,7 +2185,7 @@ static void * tinyalsa_init(const char *devicestr, unsigned rate,
|
||||
RARCH_LOG("[TINYALSA]: Using card: %u, device: %u.\n", card, device);
|
||||
|
||||
tinyalsa->params = pcm_params_get(card, device, PCM_OUT);
|
||||
if (tinyalsa->params == NULL)
|
||||
if (!tinyalsa->params)
|
||||
{
|
||||
RARCH_ERR("[TINYALSA]: params: Cannot open audio device.\n");
|
||||
goto error;
|
||||
@@ -2224,7 +2224,7 @@ static void * tinyalsa_init(const char *devicestr, unsigned rate,
|
||||
|
||||
tinyalsa->pcm = pcm_open(card, device, PCM_OUT, &config);
|
||||
|
||||
if (tinyalsa->pcm == NULL)
|
||||
if (!tinyalsa->pcm)
|
||||
{
|
||||
RARCH_ERR("[TINYALSA]: Failed to allocate memory for pcm.\n");
|
||||
goto error;
|
||||
|
||||
+109
-64
@@ -29,7 +29,7 @@
|
||||
typedef struct
|
||||
{
|
||||
bool exclusive;
|
||||
bool blocking;
|
||||
bool nonblock;
|
||||
bool running;
|
||||
size_t frame_size; /* 4 or 8 only */
|
||||
size_t engine_buffer_size;
|
||||
@@ -575,7 +575,7 @@ static void *wasapi_init(const char *dev_id, unsigned rate, unsigned latency,
|
||||
if (FAILED(hr))
|
||||
goto error;
|
||||
w->running = true;
|
||||
w->blocking = settings->bools.audio_sync;
|
||||
w->nonblock = !settings->bools.audio_sync;
|
||||
|
||||
return w;
|
||||
|
||||
@@ -596,16 +596,15 @@ static bool wasapi_flush(wasapi_t * w, const void * data, size_t size)
|
||||
{
|
||||
BYTE *dest = NULL;
|
||||
UINT32 frame_count = size / w->frame_size;
|
||||
HRESULT hr = _IAudioRenderClient_GetBuffer(
|
||||
w->renderer, frame_count, &dest);
|
||||
if (FAILED(hr))
|
||||
|
||||
if (FAILED(_IAudioRenderClient_GetBuffer(
|
||||
w->renderer, frame_count, &dest)))
|
||||
return false;
|
||||
|
||||
memcpy(dest, data, size);
|
||||
hr = _IAudioRenderClient_ReleaseBuffer(
|
||||
w->renderer, frame_count,
|
||||
0);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
||||
w->renderer, frame_count,
|
||||
0)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -615,25 +614,76 @@ static bool wasapi_flush_buffer(wasapi_t * w, size_t size)
|
||||
{
|
||||
BYTE *dest = NULL;
|
||||
UINT32 frame_count = size / w->frame_size;
|
||||
HRESULT hr = _IAudioRenderClient_GetBuffer(
|
||||
w->renderer, frame_count, &dest);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioRenderClient_GetBuffer(
|
||||
w->renderer, frame_count, &dest)))
|
||||
return false;
|
||||
|
||||
fifo_read(w->buffer, dest, size);
|
||||
hr = _IAudioRenderClient_ReleaseBuffer(
|
||||
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
||||
w->renderer, frame_count,
|
||||
0);
|
||||
if (FAILED(hr))
|
||||
0)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ssize_t wasapi_write_sh_buffer(wasapi_t *w, const void * data, size_t size)
|
||||
{
|
||||
ssize_t written = -1;
|
||||
UINT32 padding = 0;
|
||||
size_t write_avail = fifo_write_avail(w->buffer);
|
||||
|
||||
if (!write_avail)
|
||||
{
|
||||
size_t read_avail = 0;
|
||||
if (!(WaitForSingleObject(w->write_event, INFINITE) == WAIT_OBJECT_0))
|
||||
return -1;
|
||||
|
||||
if (FAILED(_IAudioClient_GetCurrentPadding(w->client, &padding)))
|
||||
return -1;
|
||||
|
||||
read_avail = fifo_read_avail(w->buffer);
|
||||
write_avail = w->engine_buffer_size - padding * w->frame_size;
|
||||
written = read_avail < write_avail ? read_avail : write_avail;
|
||||
if (written)
|
||||
if (!wasapi_flush_buffer(w, written))
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_avail = fifo_write_avail(w->buffer);
|
||||
written = size < write_avail ? size : write_avail;
|
||||
if (written)
|
||||
fifo_write(w->buffer, data, written);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||
{
|
||||
DWORD ir;
|
||||
HRESULT hr;
|
||||
size_t write_avail = 0;
|
||||
ssize_t written = -1;
|
||||
UINT32 padding = 0;
|
||||
|
||||
if (!(WaitForSingleObject(w->write_event, INFINITE) == WAIT_OBJECT_0))
|
||||
return -1;
|
||||
|
||||
if (FAILED(_IAudioClient_GetCurrentPadding(w->client, &padding)))
|
||||
return -1;
|
||||
|
||||
write_avail = w->engine_buffer_size - padding * w->frame_size;
|
||||
if (!write_avail)
|
||||
return 0;
|
||||
|
||||
written = size < write_avail ? size : write_avail;
|
||||
if (written)
|
||||
if (!wasapi_flush(w, data, written))
|
||||
return -1;
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static ssize_t wasapi_write_sh_nonblock(wasapi_t *w, const void * data, size_t size)
|
||||
{
|
||||
size_t write_avail = 0;
|
||||
ssize_t written = -1;
|
||||
UINT32 padding = 0;
|
||||
@@ -644,16 +694,7 @@ static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||
if (!write_avail)
|
||||
{
|
||||
size_t read_avail = 0;
|
||||
|
||||
if (w->blocking)
|
||||
{
|
||||
ir = WaitForSingleObject(w->write_event, INFINITE);
|
||||
if (!(ir == WAIT_OBJECT_0))
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = _IAudioClient_GetCurrentPadding(w->client, &padding);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioClient_GetCurrentPadding(w->client, &padding)))
|
||||
return -1;
|
||||
|
||||
read_avail = fifo_read_avail(w->buffer);
|
||||
@@ -671,19 +712,10 @@ static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (w->blocking)
|
||||
{
|
||||
ir = WaitForSingleObject(w->write_event, INFINITE);
|
||||
if (!(ir == WAIT_OBJECT_0))
|
||||
return -1;
|
||||
}
|
||||
|
||||
hr = _IAudioClient_GetCurrentPadding(w->client, &padding);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioClient_GetCurrentPadding(w->client, &padding)))
|
||||
return -1;
|
||||
|
||||
write_avail = w->engine_buffer_size - padding * w->frame_size;
|
||||
if (!write_avail)
|
||||
if (!(write_avail = w->engine_buffer_size - padding * w->frame_size))
|
||||
return 0;
|
||||
|
||||
written = size < write_avail ? size : write_avail;
|
||||
@@ -695,21 +727,15 @@ static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||
return written;
|
||||
}
|
||||
|
||||
static ssize_t wasapi_write_ex(wasapi_t *w, const void * data, size_t size)
|
||||
static ssize_t wasapi_write_ex(wasapi_t *w, const void * data, size_t size, DWORD ms)
|
||||
{
|
||||
ssize_t written = 0;
|
||||
size_t write_avail = fifo_write_avail(w->buffer);
|
||||
|
||||
if (!write_avail)
|
||||
{
|
||||
DWORD ir = WaitForSingleObject(
|
||||
w->write_event, w->blocking ? INFINITE : 0);
|
||||
if (ir != WAIT_OBJECT_0)
|
||||
{
|
||||
if (w->blocking)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
if (WaitForSingleObject(w->write_event, ms) != WAIT_OBJECT_0)
|
||||
return -1;
|
||||
|
||||
if (!wasapi_flush_buffer(w, w->engine_buffer_size))
|
||||
return -1;
|
||||
@@ -725,26 +751,48 @@ static ssize_t wasapi_write_ex(wasapi_t *w, const void * data, size_t size)
|
||||
|
||||
static ssize_t wasapi_write(void *wh, const void *data, size_t size)
|
||||
{
|
||||
size_t written;
|
||||
wasapi_t *w = (wasapi_t*)wh;
|
||||
size_t written = 0;
|
||||
wasapi_t *w = (wasapi_t*)wh;
|
||||
|
||||
if (w->blocking)
|
||||
if (w->nonblock)
|
||||
{
|
||||
if (w->exclusive)
|
||||
return wasapi_write_ex(w, data, size, 0);
|
||||
return wasapi_write_sh_nonblock(w, data, size);
|
||||
}
|
||||
|
||||
if (w->exclusive)
|
||||
{
|
||||
ssize_t ir;
|
||||
for (written = 0, ir = -1; written < size; written += ir)
|
||||
for (ir = -1; written < size; written += ir)
|
||||
{
|
||||
if (w->exclusive)
|
||||
ir = wasapi_write_ex(w, (char*)data + written, size - written);
|
||||
else
|
||||
ir = wasapi_write_sh(w, (char*)data + written, size - written);
|
||||
ir = wasapi_write_ex(w, (char*)data + written, size - written, INFINITE);
|
||||
if (ir == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (w->exclusive)
|
||||
written = wasapi_write_ex(w, data, size);
|
||||
else
|
||||
written = wasapi_write_sh(w, data, size);
|
||||
{
|
||||
ssize_t ir;
|
||||
if (w->buffer)
|
||||
{
|
||||
for (ir = -1; written < size; written += ir)
|
||||
{
|
||||
ir = wasapi_write_sh_buffer(w, (char*)data + written, size - written);
|
||||
if (ir == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ir = -1; written < size; written += ir)
|
||||
{
|
||||
ir = wasapi_write_sh(w, (char*)data + written, size - written);
|
||||
if (ir == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
@@ -752,8 +800,7 @@ static ssize_t wasapi_write(void *wh, const void *data, size_t size)
|
||||
static bool wasapi_stop(void *wh)
|
||||
{
|
||||
wasapi_t *w = (wasapi_t*)wh;
|
||||
HRESULT hr = _IAudioClient_Stop(w->client);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioClient_Stop(w->client)))
|
||||
return !w->running;
|
||||
|
||||
w->running = false;
|
||||
@@ -790,7 +837,7 @@ static void wasapi_set_nonblock_state(void *wh, bool nonblock)
|
||||
|
||||
RARCH_LOG("[WASAPI]: Sync %s.\n", nonblock ? "off" : "on");
|
||||
|
||||
w->blocking = !nonblock;
|
||||
w->nonblock = nonblock;
|
||||
}
|
||||
|
||||
static void wasapi_free(void *wh)
|
||||
@@ -838,15 +885,13 @@ static void wasapi_device_list_free(void *u, void *slp)
|
||||
|
||||
static size_t wasapi_write_avail(void *wh)
|
||||
{
|
||||
HRESULT hr;
|
||||
wasapi_t *w = (wasapi_t*)wh;
|
||||
UINT32 padding = 0;
|
||||
|
||||
if (w->buffer)
|
||||
return fifo_write_avail(w->buffer);
|
||||
|
||||
hr = _IAudioClient_GetCurrentPadding(w->client, &padding);
|
||||
if (FAILED(hr))
|
||||
if (FAILED(_IAudioClient_GetCurrentPadding(w->client, &padding)))
|
||||
return 0;
|
||||
|
||||
return w->engine_buffer_size - padding * w->frame_size;
|
||||
|
||||
+43
-39
@@ -31,7 +31,7 @@ typedef struct
|
||||
AXMVoice* mvoice;
|
||||
uint16_t* buffer_l;
|
||||
uint16_t* buffer_r;
|
||||
bool nonblocking;
|
||||
bool nonblock;
|
||||
|
||||
uint32_t pos;
|
||||
uint32_t written;
|
||||
@@ -56,17 +56,19 @@ typedef struct
|
||||
static volatile ax_audio_t *wiiu_cb_ax = NULL;
|
||||
void wiiu_ax_callback(void)
|
||||
{
|
||||
ax_audio_t *ax = NULL;
|
||||
/*possibly called before unregister */
|
||||
if(wiiu_cb_ax == NULL)
|
||||
if (!wiiu_cb_ax)
|
||||
return;
|
||||
|
||||
ax_audio_t *ax = (ax_audio_t*)wiiu_cb_ax;
|
||||
if(AXIsMultiVoiceRunning(ax->mvoice))
|
||||
ax = (ax_audio_t*)wiiu_cb_ax;
|
||||
|
||||
if (AXIsMultiVoiceRunning(ax->mvoice))
|
||||
{
|
||||
if(OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
|
||||
if (OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
|
||||
{
|
||||
/* Buffer underrun, stop playback to let it fill up */
|
||||
if(ax->written < AX_AUDIO_SAMPLE_MIN)
|
||||
if (ax->written < AX_AUDIO_SAMPLE_MIN)
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
|
||||
ax->written -= AX_AUDIO_SAMPLE_COUNT;
|
||||
OSUninterruptibleSpinLock_Release(&ax->spinlock);
|
||||
@@ -100,7 +102,7 @@ static void* ax_audio_init(const char* device, unsigned rate, unsigned latency,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ax->buffer_l = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
|
||||
ax->buffer_l = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
|
||||
ax->buffer_r = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
|
||||
memset(ax->buffer_l,0,AX_AUDIO_SIZE);
|
||||
memset(ax->buffer_r,0,AX_AUDIO_SIZE);
|
||||
@@ -166,9 +168,9 @@ static bool ax_audio_stop(void* data)
|
||||
|
||||
static int ax_audio_limit(int in)
|
||||
{
|
||||
if(in < 0)
|
||||
if (in < 0)
|
||||
in += AX_AUDIO_COUNT;
|
||||
else if(in >= AX_AUDIO_COUNT)
|
||||
else if (in >= AX_AUDIO_COUNT)
|
||||
in -= AX_AUDIO_COUNT;
|
||||
return in;
|
||||
}
|
||||
@@ -183,57 +185,58 @@ static bool ax_audio_start(void* data, bool is_shutdown)
|
||||
return true;
|
||||
|
||||
/* Set back to playing on enough buffered data */
|
||||
if(ax->written > AX_AUDIO_SAMPLE_LOAD)
|
||||
if (ax->written > AX_AUDIO_SAMPLE_LOAD)
|
||||
{
|
||||
AXSetMultiVoiceCurrentOffset(ax->mvoice, ax_audio_limit(ax->pos - ax->written));
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
{
|
||||
uint32_t i;
|
||||
size_t countAvail = 0;
|
||||
size_t count_avail = 0;
|
||||
ax_audio_t* ax = (ax_audio_t*)data;
|
||||
const uint16_t* src = buf;
|
||||
size_t count = size >> 2;
|
||||
|
||||
if(!size || (size & 0x3))
|
||||
if (!size || (size & 0x3))
|
||||
return 0;
|
||||
|
||||
if(count > AX_AUDIO_MAX_FREE)
|
||||
if (count > AX_AUDIO_MAX_FREE)
|
||||
count = AX_AUDIO_MAX_FREE;
|
||||
|
||||
countAvail = ((ax->written > AX_AUDIO_MAX_FREE) ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
|
||||
count_avail = ((ax->written > AX_AUDIO_MAX_FREE) ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
|
||||
|
||||
if (ax->nonblocking)
|
||||
if (ax->nonblock)
|
||||
{
|
||||
/* Not enough available for 3ms of data */
|
||||
if(countAvail < AX_AUDIO_SAMPLE_COUNT)
|
||||
if (count_avail < AX_AUDIO_SAMPLE_COUNT)
|
||||
count = 0;
|
||||
}
|
||||
else if(countAvail < count)
|
||||
else if (count_avail < count)
|
||||
{
|
||||
/* Sync, wait for free memory */
|
||||
while(AXIsMultiVoiceRunning(ax->mvoice) && (countAvail < count))
|
||||
while(AXIsMultiVoiceRunning(ax->mvoice) && (count_avail < count))
|
||||
{
|
||||
OSYieldThread(); /* Gives threads with same priority time to run */
|
||||
countAvail = (ax->written > AX_AUDIO_MAX_FREE ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
|
||||
count_avail = (ax->written > AX_AUDIO_MAX_FREE ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
|
||||
}
|
||||
}
|
||||
|
||||
/* Over available space, do as much as possible */
|
||||
if(count > countAvail)
|
||||
count = countAvail;
|
||||
if (count > count_avail)
|
||||
count = count_avail;
|
||||
|
||||
/* make sure we have input size */
|
||||
if(count > 0)
|
||||
if (count > 0)
|
||||
{
|
||||
/* write in new data */
|
||||
size_t startPos = ax->pos;
|
||||
int flushP2needed = 0;
|
||||
int flushP2 = 0;
|
||||
size_t start_pos = ax->pos;
|
||||
int flush_p2_needed = 0;
|
||||
int flush_p2 = 0;
|
||||
|
||||
for (i = 0; i < (count << 1); i += 2)
|
||||
{
|
||||
@@ -242,30 +245,31 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
ax->pos = ax_audio_limit(ax->pos + 1);
|
||||
|
||||
/* wrapped around, make sure to store cache */
|
||||
if(ax->pos == 0)
|
||||
if (ax->pos == 0)
|
||||
{
|
||||
flushP2needed = 1;
|
||||
flushP2 = ((count << 1) - i);
|
||||
DCStoreRangeNoSync(ax->buffer_l+startPos, (AX_AUDIO_COUNT-startPos) << 1);
|
||||
DCStoreRangeNoSync(ax->buffer_r+startPos, (AX_AUDIO_COUNT-startPos) << 1);
|
||||
flush_p2_needed = 1;
|
||||
flush_p2 = ((count << 1) - i);
|
||||
DCStoreRangeNoSync(ax->buffer_l + start_pos,
|
||||
(AX_AUDIO_COUNT - start_pos) << 1);
|
||||
DCStoreRangeNoSync(ax->buffer_r + start_pos, (AX_AUDIO_COUNT - start_pos) << 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* standard cache store case */
|
||||
if(!flushP2needed)
|
||||
if (!flush_p2_needed)
|
||||
{
|
||||
DCStoreRangeNoSync(ax->buffer_l+startPos, count << 1);
|
||||
DCStoreRange(ax->buffer_r+startPos, count << 1);
|
||||
DCStoreRangeNoSync(ax->buffer_l + start_pos, count << 1);
|
||||
DCStoreRange(ax->buffer_r + start_pos, count << 1);
|
||||
}
|
||||
/* store the rest after wrap */
|
||||
else if(flushP2 > 0)
|
||||
else if (flush_p2 > 0)
|
||||
{
|
||||
DCStoreRangeNoSync(ax->buffer_l, flushP2);
|
||||
DCStoreRange(ax->buffer_r, flushP2);
|
||||
DCStoreRangeNoSync(ax->buffer_l, flush_p2);
|
||||
DCStoreRange(ax->buffer_r, flush_p2);
|
||||
}
|
||||
|
||||
/* add in new audio data */
|
||||
if(OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
|
||||
if (OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
|
||||
{
|
||||
ax->written += count;
|
||||
OSUninterruptibleSpinLock_Release(&ax->spinlock);
|
||||
@@ -276,7 +280,7 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
*
|
||||
* checks if it can be started
|
||||
*/
|
||||
if(!AXIsMultiVoiceRunning(ax->mvoice))
|
||||
if (!AXIsMultiVoiceRunning(ax->mvoice))
|
||||
ax_audio_start(ax, false);
|
||||
|
||||
/* return what was actually copied */
|
||||
@@ -294,7 +298,7 @@ static void ax_audio_set_nonblock_state(void* data, bool state)
|
||||
ax_audio_t* ax = (ax_audio_t*)data;
|
||||
|
||||
if (ax)
|
||||
ax->nonblocking = state;
|
||||
ax->nonblock = state;
|
||||
}
|
||||
|
||||
static bool ax_audio_use_float(void* data)
|
||||
|
||||
@@ -869,26 +869,27 @@ static INLINE HRESULT XAudio2Create(_Outptr_ IXAudio2** ppXAudio2,
|
||||
typedef HRESULT(__stdcall *XAudio2CreateWithVersionInfoFunc)(_Outptr_ IXAudio2**, UINT32, XAUDIO2_PROCESSOR, DWORD);
|
||||
typedef HRESULT(__stdcall *XAudio2CreateInfoFunc)(_Outptr_ IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
|
||||
|
||||
static HMODULE s_dllInstance = NULL;
|
||||
static XAudio2CreateWithVersionInfoFunc s_pfnAudio2CreateWithVersion = NULL;
|
||||
static XAudio2CreateWithVersionInfoFunc
|
||||
s_pfnAudio2CreateWithVersion = NULL;
|
||||
static XAudio2CreateInfoFunc s_pfnAudio2Create = NULL;
|
||||
static HMODULE s_dllInstance = NULL;
|
||||
|
||||
if (s_dllInstance == NULL)
|
||||
if (!s_dllInstance)
|
||||
{
|
||||
s_dllInstance = LoadLibraryEx(XAUDIO2_DLL, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (s_dllInstance == NULL)
|
||||
if (!s_dllInstance)
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
s_pfnAudio2CreateWithVersion = (XAudio2CreateWithVersionInfoFunc)(void*)GetProcAddress(s_dllInstance, "XAudio2CreateWithVersionInfo");
|
||||
if (s_pfnAudio2CreateWithVersion == NULL)
|
||||
if (!s_pfnAudio2CreateWithVersion)
|
||||
{
|
||||
s_pfnAudio2Create = (XAudio2CreateInfoFunc)(void*)GetProcAddress(s_dllInstance, "XAudio2Create");
|
||||
if (s_pfnAudio2Create == NULL)
|
||||
if (!s_pfnAudio2Create)
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (s_pfnAudio2CreateWithVersion != NULL)
|
||||
if (s_pfnAudio2CreateWithVersion)
|
||||
return (*s_pfnAudio2CreateWithVersion)(ppXAudio2, Flags, XAudio2Processor, NTDDI_VERSION);
|
||||
return (*s_pfnAudio2Create)(ppXAudio2, Flags, XAudio2Processor);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,15 @@ static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
|
||||
for (i = 0; i < (size >> 2); i++)
|
||||
xa->buffer[i] = bswap_32(in_buf[i]);
|
||||
|
||||
if (!xa->nonblock)
|
||||
if (xa->nonblock)
|
||||
{
|
||||
if (xenon_sound_get_unplayed() < MAX_BUFFER)
|
||||
{
|
||||
xenon_sound_submit(xa->buffer, size);
|
||||
written = size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (xenon_sound_get_unplayed() >= MAX_BUFFER)
|
||||
{
|
||||
@@ -78,14 +86,6 @@ static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
|
||||
xenon_sound_submit(xa->buffer, size);
|
||||
written = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xenon_sound_get_unplayed() < MAX_BUFFER)
|
||||
{
|
||||
xenon_sound_submit(xa->buffer, size);
|
||||
written = size;
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2012-2015 - Michael Lelli
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../retroarch.h"
|
||||
|
||||
static void *nullcamera_init(const char *device, uint64_t caps,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
(void)device;
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
static void nullcamera_free(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static bool nullcamera_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nullcamera_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static bool nullcamera_poll(void *data,
|
||||
retro_camera_frame_raw_framebuffer_t frame_raw_cb,
|
||||
retro_camera_frame_opengl_texture_t frame_gl_cb)
|
||||
{
|
||||
(void)data;
|
||||
(void)frame_raw_cb;
|
||||
(void)frame_gl_cb;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
camera_driver_t camera_null = {
|
||||
nullcamera_init,
|
||||
nullcamera_free,
|
||||
nullcamera_start,
|
||||
nullcamera_stop,
|
||||
nullcamera_poll,
|
||||
"null",
|
||||
};
|
||||
+76
-21
@@ -401,6 +401,16 @@ static int rcheevos_parse(const char* json)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rcheevos_patch_address(0, rcheevos_locals.patchdata.console_id))
|
||||
{
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "No memory exposed by core\n");
|
||||
|
||||
if (settings->bools.cheevos_verbose_enable)
|
||||
runloop_msg_queue_push("Cannot activate achievements using this core.", 0, 4 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Allocate memory. */
|
||||
rcheevos_locals.core = (rcheevos_cheevo_t*)
|
||||
calloc(rcheevos_locals.patchdata.core_count, sizeof(rcheevos_cheevo_t));
|
||||
@@ -665,6 +675,20 @@ static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud)
|
||||
return value;
|
||||
}
|
||||
|
||||
static int rcheevos_has_indirect_memref(const rc_memref_value_t* memrefs)
|
||||
{
|
||||
const rc_memref_value_t* memref = memrefs;
|
||||
while (memref != NULL)
|
||||
{
|
||||
if (memref->memref.is_indirect)
|
||||
return 1;
|
||||
|
||||
memref = memref->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rcheevos_test_cheevo_set(bool official)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
@@ -701,17 +725,26 @@ static void rcheevos_test_cheevo_set(bool official)
|
||||
/* if the we're still waiting for the trigger to stabilize, check to see if an error occurred */
|
||||
if (rcheevos_locals.invalid_peek_address)
|
||||
{
|
||||
/* could not map one or more addresses - disable the achievement */
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Achievement disabled (invalid address): %s\n", cheevo->info->title);
|
||||
cheevo->active = 0;
|
||||
|
||||
/* clear out the trigger so it shows up as 'Unsupported' in the menu */
|
||||
CHEEVOS_FREE(cheevo->trigger);
|
||||
cheevo->trigger = NULL;
|
||||
|
||||
/* reset the flag for the next achievement */
|
||||
rcheevos_locals.invalid_peek_address = false;
|
||||
continue;
|
||||
|
||||
if (rcheevos_has_indirect_memref(cheevo->trigger->memrefs))
|
||||
{
|
||||
/* ignore bad addresses possibly generated by AddAddress */
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "Ignoring invalid address in achievement with AddAddress: %s\n", cheevo->info->title);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* could not map one or more addresses - disable the achievement */
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Achievement disabled (invalid address): %s\n", cheevo->info->title);
|
||||
cheevo->active = 0;
|
||||
|
||||
/* clear out the trigger so it shows up as 'Unsupported' in the menu */
|
||||
CHEEVOS_FREE(cheevo->trigger);
|
||||
cheevo->trigger = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* no error, reset any hit counts for the next check */
|
||||
@@ -850,14 +883,17 @@ static void rcheevos_test_leaderboards(void)
|
||||
|
||||
if (rcheevos_locals.invalid_peek_address)
|
||||
{
|
||||
/* disable the leaderboard */
|
||||
CHEEVOS_FREE(lboard->lboard);
|
||||
lboard->lboard = NULL;
|
||||
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard disabled (invalid address): %s\n", lboard->info->title);
|
||||
|
||||
/* reset the flag for the next leaderboard */
|
||||
rcheevos_locals.invalid_peek_address = false;
|
||||
|
||||
if (!rcheevos_has_indirect_memref(lboard->lboard->memrefs))
|
||||
{
|
||||
/* disable the leaderboard */
|
||||
CHEEVOS_FREE(lboard->lboard);
|
||||
lboard->lboard = NULL;
|
||||
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard disabled (invalid address): %s\n", lboard->info->title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -871,28 +907,32 @@ void rcheevos_reset_game(void)
|
||||
cheevo = rcheevos_locals.core;
|
||||
for (i = 0; i < rcheevos_locals.patchdata.core_count; i++, cheevo++)
|
||||
{
|
||||
rc_reset_trigger(cheevo->trigger);
|
||||
if (cheevo->trigger)
|
||||
rc_reset_trigger(cheevo->trigger);
|
||||
cheevo->last = 1;
|
||||
}
|
||||
|
||||
cheevo = rcheevos_locals.unofficial;
|
||||
for (i = 0; i < rcheevos_locals.patchdata.unofficial_count; i++, cheevo++)
|
||||
{
|
||||
rc_reset_trigger(cheevo->trigger);
|
||||
if (cheevo->trigger)
|
||||
rc_reset_trigger(cheevo->trigger);
|
||||
cheevo->last = 1;
|
||||
}
|
||||
|
||||
lboard = rcheevos_locals.lboards;
|
||||
for (i = 0; i < rcheevos_locals.patchdata.lboard_count; i++, lboard++)
|
||||
{
|
||||
rc_reset_lboard(lboard->lboard);
|
||||
if (lboard->lboard)
|
||||
rc_reset_lboard(lboard->lboard);
|
||||
|
||||
if (lboard->active)
|
||||
{
|
||||
lboard->active = 0;
|
||||
|
||||
/* this ensures the leaderboard won't restart until the start trigger is false for at least one frame */
|
||||
lboard->lboard->submitted = 1;
|
||||
if (lboard->lboard)
|
||||
lboard->lboard->submitted = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1738,17 +1778,32 @@ found:
|
||||
const rcheevos_cheevo_t* cheevo = rcheevos_locals.core;
|
||||
const rcheevos_cheevo_t* end = cheevo + rcheevos_locals.patchdata.core_count;
|
||||
int number_of_unlocked = rcheevos_locals.patchdata.core_count;
|
||||
int number_of_unsupported = 0;
|
||||
|
||||
if (coro->settings->bools.cheevos_hardcore_mode_enable && !rcheevos_hardcore_paused)
|
||||
mode = RCHEEVOS_ACTIVE_HARDCORE;
|
||||
|
||||
for (; cheevo < end; cheevo++)
|
||||
if (cheevo->active & mode)
|
||||
{
|
||||
if (!cheevo->trigger)
|
||||
number_of_unsupported++;
|
||||
else if (cheevo->active & mode)
|
||||
number_of_unlocked--;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg),
|
||||
if (!number_of_unsupported)
|
||||
{
|
||||
snprintf(msg, sizeof(msg),
|
||||
"You have %d of %d achievements unlocked.",
|
||||
number_of_unlocked, rcheevos_locals.patchdata.core_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(msg, sizeof(msg),
|
||||
"You have %d of %d achievements unlocked (%d unsupported).",
|
||||
number_of_unlocked - number_of_unsupported, rcheevos_locals.patchdata.core_count, number_of_unsupported);
|
||||
}
|
||||
|
||||
msg[sizeof(msg) - 1] = 0;
|
||||
runloop_msg_queue_push(msg, 0, 6 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
}
|
||||
|
||||
+6
-3
@@ -236,6 +236,7 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console)
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
unsigned addr = address;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -259,9 +260,10 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console)
|
||||
|
||||
core_get_memory(&meminfo);
|
||||
|
||||
if (address < meminfo.size)
|
||||
if (addr < meminfo.size)
|
||||
{
|
||||
pointer = meminfo.data;
|
||||
address = addr;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -270,14 +272,15 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console)
|
||||
* it's size is not always set correctly in the core.
|
||||
*/
|
||||
if (i == 0 && console == RC_CONSOLE_NINTENDO)
|
||||
address -= 0x6000;
|
||||
addr -= 0x6000;
|
||||
else
|
||||
address -= meminfo.size;
|
||||
addr -= meminfo.size;
|
||||
}
|
||||
}
|
||||
|
||||
if (pointer == NULL)
|
||||
{
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "address %X not supported\n", address);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ enum event_command
|
||||
CMD_EVENT_DISK_NEXT,
|
||||
/* Cycle to previous disk. */
|
||||
CMD_EVENT_DISK_PREV,
|
||||
/* Switch to specified disk index */
|
||||
CMD_EVENT_DISK_INDEX,
|
||||
/* Appends disk image to disk image list. */
|
||||
CMD_EVENT_DISK_APPEND_IMAGE,
|
||||
/* Stops rumbling. */
|
||||
|
||||
+15
-4
@@ -89,6 +89,8 @@
|
||||
#define DEFAULT_MAX_PADS 4
|
||||
#elif defined(HAVE_XINPUT) && !defined(HAVE_DINPUT)
|
||||
#define DEFAULT_MAX_PADS 4
|
||||
#elif defined(DINGUX)
|
||||
#define DEFAULT_MAX_PADS 2
|
||||
#else
|
||||
#define DEFAULT_MAX_PADS 16
|
||||
#endif
|
||||
@@ -466,7 +468,9 @@ static bool quick_menu_show_save_core_overrides = true;
|
||||
static bool quick_menu_show_save_game_overrides = true;
|
||||
static bool quick_menu_show_save_content_dir_overrides = true;
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
static bool quick_menu_show_download_thumbnails = true;
|
||||
#endif
|
||||
|
||||
static bool kiosk_mode_enable = false;
|
||||
|
||||
@@ -505,6 +509,8 @@ static bool menu_savestate_resume = true;
|
||||
static bool menu_savestate_resume = false;
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MENU_INSERT_DISK_RESUME true
|
||||
|
||||
static bool content_show_settings = true;
|
||||
static bool content_show_favorites = true;
|
||||
#ifdef HAVE_IMAGEVIEWER
|
||||
@@ -592,7 +598,7 @@ static bool default_savefiles_in_content_dir = false;
|
||||
static bool default_systemfiles_in_content_dir = false;
|
||||
static bool default_screenshots_in_content_dir = false;
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX1) || defined(_XBOX360)
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX1) || defined(_XBOX360) || defined(DINGUX)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L3_R3;
|
||||
#elif defined(PS2) || defined(PSP)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_HOLD_START;
|
||||
@@ -631,7 +637,12 @@ static unsigned input_backtouch_toggle = false;
|
||||
#define DEFAULT_CROP_OVERSCAN true
|
||||
|
||||
/* Font size for on-screen messages. */
|
||||
#if defined(DINGUX)
|
||||
#define DEFAULT_FONT_SIZE 12
|
||||
#else
|
||||
#define DEFAULT_FONT_SIZE 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Offset for where messages will be placed on-screen.
|
||||
* Values are in range [0.0, 1.0]. */
|
||||
@@ -908,11 +919,11 @@ static const bool network_on_demand_thumbnails = false;
|
||||
#endif
|
||||
|
||||
/* Number of entries that will be kept in content history playlist file. */
|
||||
static const unsigned default_content_history_size = 100;
|
||||
static const unsigned default_content_history_size = 200;
|
||||
|
||||
/* Number of entries that will be kept in content favorites playlist file.
|
||||
* -1 == 'unlimited' (99999) */
|
||||
static const int default_content_favorites_size = 100;
|
||||
static const int default_content_favorites_size = 200;
|
||||
|
||||
/* Sort all playlists (apart from histories) alphabetically */
|
||||
static const bool playlist_sort_alphabetical = true;
|
||||
@@ -1045,7 +1056,7 @@ static const bool content_runtime_log_aggregate = false;
|
||||
|
||||
#if defined(__QNX__) || defined(_XBOX1) || defined(_XBOX360) || defined(__CELLOS_LV2__) || (defined(__MACH__) && defined(IOS)) || defined(ANDROID) || defined(WIIU) || defined(HAVE_NEON) || defined(GEKKO) || defined(__ARM_NEON__)
|
||||
static enum resampler_quality audio_resampler_quality_level = RESAMPLER_QUALITY_LOWER;
|
||||
#elif defined(PSP) || defined(_3DS) || defined(VITA) || defined(PS2)
|
||||
#elif defined(PSP) || defined(_3DS) || defined(VITA) || defined(PS2) || defined(DINGUX)
|
||||
static enum resampler_quality audio_resampler_quality_level = RESAMPLER_QUALITY_LOWEST;
|
||||
#else
|
||||
static enum resampler_quality audio_resampler_quality_level = RESAMPLER_QUALITY_NORMAL;
|
||||
|
||||
@@ -105,6 +105,88 @@ static const struct retro_keybind retro_keybinds_1[] = {
|
||||
{ true, RARCH_RECORDING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_STREAMING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_AI_SERVICE, MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
#elif defined(DINGUX)
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_B, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_LALT, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_Y, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, RETROK_LSHIFT, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, RETROK_ESCAPE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_START, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, RETROK_RETURN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, RETROK_UP, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, RETROK_DOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, RETROK_LEFT, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, RETROK_RIGHT, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_A, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, RETROK_LCTRL, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_X, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, RETROK_SPACE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, RETROK_TAB, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, RETROK_BACKSPACE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L2, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, RETROK_PAGEUP, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R2, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, RETROK_PAGEDOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L3, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, RETROK_KP_DIVIDE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R3, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, RETROK_KP_PERIOD, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
|
||||
{ true, RARCH_ANALOG_LEFT_X_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_LEFT_X_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_LEFT_Y_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_LEFT_Y_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_RIGHT_X_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_RIGHT_X_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_RIGHT_Y_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ANALOG_RIGHT_Y_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
|
||||
{ true, RARCH_LIGHTGUN_TRIGGER, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_RELOAD, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_AUX_A, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_AUX_B, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_AUX_C, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_START, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_SELECT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_DPAD_UP, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_DPAD_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_DPAD_LEFT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LIGHTGUN_DPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
|
||||
{ true, RARCH_TURBO_ENABLE, MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
|
||||
{ true, RARCH_FAST_FORWARD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_FAST_FORWARD_HOLD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SLOWMOTION_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SLOWMOTION_HOLD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_FULLSCREEN_TOGGLE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_REWIND, MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_BSV_RECORD_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_BSV_RECORD_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_PAUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_FRAMEADVANCE, MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_RESET, MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SHADER_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SHADER_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_CHEAT_INDEX_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_CHEAT_INDEX_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_CHEAT_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SCREENSHOT, MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_VOLUME_UP, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_VOLUME_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_OVERLAY_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_DISK_EJECT_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_DISK_NEXT, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_DISK_PREV, MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_GRAB_MOUSE_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_GAME_FOCUS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_UI_COMPANION_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, RETROK_HOME, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_RECORDING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_STREAMING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RARCH_AI_SERVICE, MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
#else
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_B, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_z, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_Y, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, RETROK_a, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@
|
||||
#define SUPPORTS_LIBUSB false
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#if defined(HAVE_SDL)
|
||||
#define SUPPORTS_SDL true
|
||||
#else
|
||||
#define SUPPORTS_SDL false
|
||||
|
||||
+8
-2
@@ -144,6 +144,7 @@ enum video_driver_enum
|
||||
VIDEO_XVIDEO,
|
||||
VIDEO_SDL,
|
||||
VIDEO_SDL2,
|
||||
VIDEO_SDL_DINGUX,
|
||||
VIDEO_EXT,
|
||||
VIDEO_WII,
|
||||
VIDEO_WIIU,
|
||||
@@ -321,7 +322,7 @@ enum midi_driver_enum
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL;
|
||||
#elif defined(HAVE_VITA2D)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D;
|
||||
#elif defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)
|
||||
#elif (defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)) && !defined(__WINRT__)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
|
||||
#elif defined(HAVE_OPENGL_CORE)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL_CORE;
|
||||
@@ -357,10 +358,12 @@ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_CTR;
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SWITCH;
|
||||
#elif defined(HAVE_XVIDEO)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XVIDEO;
|
||||
#elif defined(HAVE_SDL)
|
||||
#elif defined(HAVE_SDL) && !defined(HAVE_SDL_DINGUX)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL;
|
||||
#elif defined(HAVE_SDL2)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL2;
|
||||
#elif defined(HAVE_SDL_DINGUX)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_DINGUX;
|
||||
#elif defined(_WIN32) && !defined(_XBOX)
|
||||
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GDI;
|
||||
#elif defined(DJGPP)
|
||||
@@ -808,6 +811,8 @@ const char *config_get_default_video(void)
|
||||
return "switch";
|
||||
case VIDEO_XVIDEO:
|
||||
return "xvideo";
|
||||
case VIDEO_SDL_DINGUX:
|
||||
return "sdl_dingux";
|
||||
case VIDEO_SDL:
|
||||
return "sdl";
|
||||
case VIDEO_SDL2:
|
||||
@@ -1455,6 +1460,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("menu_horizontal_animation", &settings->bools.menu_horizontal_animation, true, DEFAULT_MENU_HORIZONTAL_ANIMATION, false);
|
||||
SETTING_BOOL("menu_pause_libretro", &settings->bools.menu_pause_libretro, true, true, false);
|
||||
SETTING_BOOL("menu_savestate_resume", &settings->bools.menu_savestate_resume, true, menu_savestate_resume, false);
|
||||
SETTING_BOOL("menu_insert_disk_resume", &settings->bools.menu_insert_disk_resume, true, DEFAULT_MENU_INSERT_DISK_RESUME, false);
|
||||
SETTING_BOOL("menu_mouse_enable", &settings->bools.menu_mouse_enable, true, DEFAULT_MOUSE_ENABLE, false);
|
||||
SETTING_BOOL("menu_pointer_enable", &settings->bools.menu_pointer_enable, true, DEFAULT_POINTER_ENABLE, false);
|
||||
SETTING_BOOL("menu_timedate_enable", &settings->bools.menu_timedate_enable, true, true, false);
|
||||
|
||||
@@ -154,6 +154,7 @@ typedef struct settings
|
||||
bool menu_show_start_screen;
|
||||
bool menu_pause_libretro;
|
||||
bool menu_savestate_resume;
|
||||
bool menu_insert_disk_resume;
|
||||
bool menu_timedate_enable;
|
||||
bool menu_battery_level_enable;
|
||||
bool menu_core_enable;
|
||||
|
||||
+34
-15
@@ -26,7 +26,6 @@
|
||||
#include <net/net_http.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "file_path_special.h"
|
||||
#include "core_info.h"
|
||||
|
||||
@@ -400,11 +399,14 @@ static bool core_updater_list_set_crc(
|
||||
* associated paths to the specified core
|
||||
* updater list entry */
|
||||
static bool core_updater_list_set_paths(
|
||||
core_updater_list_entry_t *entry, const char *filename_str)
|
||||
core_updater_list_entry_t *entry,
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info,
|
||||
const char *network_buildbot_url,
|
||||
const char *filename_str)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
char *last_underscore = NULL;
|
||||
char *tmp_url = NULL;
|
||||
char *last_underscore = NULL;
|
||||
char *tmp_url = NULL;
|
||||
char remote_core_path[PATH_MAX_LENGTH];
|
||||
char local_core_path[PATH_MAX_LENGTH];
|
||||
char local_info_path[PATH_MAX_LENGTH];
|
||||
@@ -416,12 +418,12 @@ static bool core_updater_list_set_paths(
|
||||
local_info_path[0] = '\0';
|
||||
display_name[0] = '\0';
|
||||
|
||||
if (!entry || string_is_empty(filename_str) || !settings)
|
||||
if (!entry || string_is_empty(filename_str))
|
||||
return false;
|
||||
|
||||
if (string_is_empty(settings->paths.directory_libretro) ||
|
||||
string_is_empty(settings->paths.path_libretro_info) ||
|
||||
string_is_empty(settings->paths.network_buildbot_url))
|
||||
if (string_is_empty(path_dir_libretro) ||
|
||||
string_is_empty(path_libretro_info) ||
|
||||
string_is_empty(network_buildbot_url))
|
||||
return false;
|
||||
|
||||
/* Check whether remote file is an archive */
|
||||
@@ -439,7 +441,7 @@ static bool core_updater_list_set_paths(
|
||||
/* remote_core_path */
|
||||
fill_pathname_join(
|
||||
remote_core_path,
|
||||
settings->paths.network_buildbot_url,
|
||||
network_buildbot_url,
|
||||
filename_str,
|
||||
sizeof(remote_core_path));
|
||||
|
||||
@@ -462,7 +464,7 @@ static bool core_updater_list_set_paths(
|
||||
/* local_core_path */
|
||||
fill_pathname_join(
|
||||
local_core_path,
|
||||
settings->paths.directory_libretro,
|
||||
path_dir_libretro,
|
||||
filename_str,
|
||||
sizeof(local_core_path));
|
||||
|
||||
@@ -482,7 +484,7 @@ static bool core_updater_list_set_paths(
|
||||
/* local_info_path */
|
||||
fill_pathname_join_noext(
|
||||
local_info_path,
|
||||
settings->paths.path_libretro_info,
|
||||
path_libretro_info,
|
||||
filename_str,
|
||||
sizeof(local_info_path));
|
||||
|
||||
@@ -593,6 +595,9 @@ static bool core_updater_list_push_entry(
|
||||
* core updater list */
|
||||
static void core_updater_list_add_entry(
|
||||
core_updater_list_t *core_list,
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info,
|
||||
const char *network_buildbot_url,
|
||||
struct string_list *network_core_entry_list)
|
||||
{
|
||||
const char *date_str = NULL;
|
||||
@@ -631,7 +636,12 @@ static void core_updater_list_add_entry(
|
||||
if (!core_updater_list_set_crc(&entry, crc_str))
|
||||
goto error;
|
||||
|
||||
if (!core_updater_list_set_paths(&entry, filename_str))
|
||||
if (!core_updater_list_set_paths(
|
||||
&entry,
|
||||
path_dir_libretro,
|
||||
path_libretro_info,
|
||||
network_buildbot_url,
|
||||
filename_str))
|
||||
goto error;
|
||||
|
||||
/* Add entry to list */
|
||||
@@ -693,7 +703,11 @@ static void core_updater_list_qsort(core_updater_list_t *core_list)
|
||||
* core_updater_list_t object.
|
||||
* Returns false in the event of an error. */
|
||||
bool core_updater_list_parse_network_data(
|
||||
core_updater_list_t *core_list, const char *data, size_t len)
|
||||
core_updater_list_t *core_list,
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info,
|
||||
const char *network_buildbot_url,
|
||||
const char *data, size_t len)
|
||||
{
|
||||
struct string_list *network_core_list = NULL;
|
||||
struct string_list *network_core_entry_list = NULL;
|
||||
@@ -729,6 +743,7 @@ bool core_updater_list_parse_network_data(
|
||||
|
||||
/* Temporary data buffer is no longer required */
|
||||
free(data_buf);
|
||||
data_buf = NULL;
|
||||
|
||||
/* Loop over lines */
|
||||
for (i = 0; i < network_core_list->size; i++)
|
||||
@@ -744,7 +759,11 @@ bool core_updater_list_parse_network_data(
|
||||
/* Parse listings info and add to core updater
|
||||
* list */
|
||||
core_updater_list_add_entry(
|
||||
core_list, network_core_entry_list);
|
||||
core_list,
|
||||
path_dir_libretro,
|
||||
path_libretro_info,
|
||||
network_buildbot_url,
|
||||
network_core_entry_list);
|
||||
|
||||
/* Clean up */
|
||||
string_list_free(network_core_entry_list);
|
||||
|
||||
+5
-1
@@ -136,7 +136,11 @@ bool core_updater_list_get_core(
|
||||
* core_updater_list_t object.
|
||||
* Returns false in the event of an error. */
|
||||
bool core_updater_list_parse_network_data(
|
||||
core_updater_list_t *core_list, const char *data, size_t len);
|
||||
core_updater_list_t *core_list,
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info,
|
||||
const char *network_buildbot_url,
|
||||
const char *data, size_t len);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ SWRESAMPLE_DIR := $(BASE_DIR)/libswresample
|
||||
INCFLAGS += -I$(BASE_DIR) -I$(CORE_DIR) -I$(LIBRETRO_COMM_DIR)/include -I$(LIBRETRO_COMM_DIR)/include/compat
|
||||
|
||||
LIBRETRO_SOURCE += $(CORE_DIR)/ffmpeg_core.c \
|
||||
$(CORE_DIR)/packet_buffer.c \
|
||||
$(CORE_DIR)/video_buffer.c \
|
||||
$(LIBRETRO_COMM_DIR)/rthreads/tpool.c \
|
||||
$(LIBRETRO_COMM_DIR)/queues/fifo_queue.c \
|
||||
|
||||
@@ -50,6 +50,7 @@ extern "C" {
|
||||
#include <rthreads/tpool.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
#include <string/stdstring.h>
|
||||
#include "packet_buffer.h"
|
||||
#include "video_buffer.h"
|
||||
|
||||
#include <libretro.h>
|
||||
@@ -93,7 +94,13 @@ static unsigned sw_sws_threads;
|
||||
static video_buffer_t *video_buffer;
|
||||
static tpool_t *tpool;
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
/* If libavutil is at least version 55 or higher,
|
||||
* and if libavcodec is at least version 57.80.100 or higher,
|
||||
* enable hardware acceleration */
|
||||
#define ENABLE_HW_ACCEL ((LIBAVUTIL_VERSION_MAJOR > 55) && ENABLE_HW_ACCEL_CHECK2())
|
||||
#define ENABLE_HW_ACCEL_CHECK2() ((LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 80 && LIBAVCODEC_VERSION_MICRO >= 100) || (LIBAVCODEC_VERSION_MAJOR > 57))
|
||||
|
||||
#if ENABLE_HW_ACCEL
|
||||
static enum AVHWDeviceType hw_decoder;
|
||||
static bool hw_decoding_enabled;
|
||||
static enum AVPixelFormat pix_fmt;
|
||||
@@ -277,11 +284,11 @@ void CORE_PREFIX(retro_get_system_av_info)(struct retro_system_av_info *info)
|
||||
void CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
|
||||
{
|
||||
static const struct retro_variable vars[] = {
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
{ "ffmpeg_hw_decoder", "Use Hardware decoder (restart); off|auto|"
|
||||
"cuda|d3d11va|drm|dxva2|mediacodec|opencl|qsv|vaapi|vdpau|videotoolbox" },
|
||||
#endif
|
||||
{ "ffmpeg_sw_decoder_threads", "Software decoder thread count (restart); auto|1|2|4|8|16" },
|
||||
{ "ffmpeg_sw_decoder_threads", "Software decoder thread count (restart); auto|1|2|4|6|8|10|12|14|16" },
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
||||
{ "ffmpeg_temporal_interp", "Temporal Interpolation; disabled|enabled" },
|
||||
#ifdef HAVE_GL_FFT
|
||||
@@ -408,7 +415,7 @@ static void check_variables(bool firststart)
|
||||
slock_unlock(decode_thread_lock);
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
if (firststart)
|
||||
{
|
||||
hw_var.key = "ffmpeg_hw_decoder";
|
||||
@@ -836,7 +843,7 @@ void CORE_PREFIX(retro_run)(void)
|
||||
CORE_PREFIX(audio_batch_cb)(audio_buffer, to_read_frames);
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
/*
|
||||
* Try to initialize a specific HW decoder defined by type.
|
||||
* Optionaly tests the pixel format list for a compatible pixel format.
|
||||
@@ -935,7 +942,7 @@ static enum AVPixelFormat select_decoder(AVCodecContext *ctx,
|
||||
{
|
||||
enum AVPixelFormat format = AV_PIX_FMT_NONE;
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
if (!force_sw_decoder)
|
||||
{
|
||||
if (hw_decoder == AV_HWDEVICE_TYPE_NONE)
|
||||
@@ -959,7 +966,7 @@ static enum AVPixelFormat select_decoder(AVCodecContext *ctx,
|
||||
|
||||
format = fctx->streams[video_stream_index]->codec->pix_fmt;
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
hw_decoding_enabled = false;
|
||||
}
|
||||
else
|
||||
@@ -969,7 +976,7 @@ static enum AVPixelFormat select_decoder(AVCodecContext *ctx,
|
||||
return format;
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
/* Callback used by ffmpeg to configure the pixelformat to use. */
|
||||
static enum AVPixelFormat get_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
@@ -1004,7 +1011,7 @@ static bool open_codec(AVCodecContext **ctx, enum AVMediaType type, unsigned ind
|
||||
{
|
||||
video_stream_index = index;
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
vctx->get_format = get_format;
|
||||
pix_fmt = select_decoder((*ctx), NULL);
|
||||
#else
|
||||
@@ -1292,7 +1299,7 @@ static void sws_worker_thread(void *arg)
|
||||
AVFrame *tmp_frame = NULL;
|
||||
video_decoder_context_t *ctx = (video_decoder_context_t*) arg;
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
if (hw_decoding_enabled)
|
||||
tmp_frame = ctx->hw_source;
|
||||
else
|
||||
@@ -1335,7 +1342,7 @@ static void sws_worker_thread(void *arg)
|
||||
#endif
|
||||
|
||||
av_frame_unref(ctx->source);
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
av_frame_unref(ctx->hw_source);
|
||||
#endif
|
||||
|
||||
@@ -1354,11 +1361,6 @@ static void decode_video(AVCodecContext *ctx, AVPacket *pkt, size_t frame_size)
|
||||
/* Stop decoding thread until video_buffer is not full again */
|
||||
while (!decode_thread_dead && !video_buffer_has_open_slot(video_buffer))
|
||||
{
|
||||
/* If we don't buffer enough video frames we can run into a deadlock.
|
||||
* for now drop frames in this case. This could happen with MP4 files
|
||||
* since the often save the audio frames into the stream.
|
||||
* Longterm solution: audio and video decoding in their own threads
|
||||
* with their own file handle. */
|
||||
if (main_sleeping)
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, "[FFMPEG] Thread: Video deadlock detected.\n");
|
||||
@@ -1398,7 +1400,7 @@ static void decode_video(AVCodecContext *ctx, AVPacket *pkt, size_t frame_size)
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
#if ENABLE_HW_ACCEL
|
||||
if (hw_decoding_enabled)
|
||||
/* Copy data from VRAM to RAM */
|
||||
if ((ret = av_hwframe_transfer_data(decoder_ctx->hw_source, decoder_ctx->source, 0)) < 0)
|
||||
@@ -1534,14 +1536,30 @@ static void decode_thread_seek(double time)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function makes sure that we don't decode too many
|
||||
* packets and cause stalls in our decoding pipeline.
|
||||
* This could happen if we decode too many packets and
|
||||
* saturate our buffers. We have a window of "still okay"
|
||||
* to decode, that depends on the media fps.
|
||||
**/
|
||||
static bool earlier_or_close_enough(double p1, double p2)
|
||||
{
|
||||
return (p1 <= p2 || (p1-p2) < (1.0 / media.interpolate_fps) );
|
||||
}
|
||||
|
||||
static void decode_thread(void *data)
|
||||
{
|
||||
unsigned i;
|
||||
bool eof = false;
|
||||
struct SwrContext *swr[audio_streams_num];
|
||||
AVFrame *aud_frame = NULL;
|
||||
size_t frame_size = 0;
|
||||
int16_t *audio_buffer = NULL;
|
||||
size_t audio_buffer_cap = 0;
|
||||
packet_buffer_t *audio_packet_buffer;
|
||||
packet_buffer_t *video_packet_buffer;
|
||||
double last_audio_end = 0;
|
||||
|
||||
(void)data;
|
||||
|
||||
@@ -1559,11 +1577,13 @@ static void decode_thread(void *data)
|
||||
}
|
||||
|
||||
aud_frame = av_frame_alloc();
|
||||
audio_packet_buffer = packet_buffer_create();
|
||||
video_packet_buffer = packet_buffer_create();
|
||||
|
||||
if (video_stream_index >= 0)
|
||||
{
|
||||
frame_size = avpicture_get_size(PIX_FMT_RGB32, media.width, media.height);
|
||||
video_buffer = video_buffer_create(32, frame_size, media.width, media.height);
|
||||
video_buffer = video_buffer_create(4, frame_size, media.width, media.height);
|
||||
tpool = tpool_create(sw_sws_threads);
|
||||
log_cb(RETRO_LOG_INFO, "[FFMPEG] Configured worker threads: %d\n", sw_sws_threads);
|
||||
}
|
||||
@@ -1571,12 +1591,19 @@ static void decode_thread(void *data)
|
||||
while (!decode_thread_dead)
|
||||
{
|
||||
bool seek;
|
||||
AVPacket pkt;
|
||||
int subtitle_stream;
|
||||
double seek_time_thread;
|
||||
int audio_stream, audio_stream_ptr;
|
||||
int audio_stream_index, audio_stream_ptr;
|
||||
|
||||
double audio_timebase = 0.0;
|
||||
double video_timebase = 0.0;
|
||||
double next_video_end = 0.0;
|
||||
double next_audio_start = 0.0;
|
||||
|
||||
AVPacket *pkt = av_packet_alloc();
|
||||
AVCodecContext *actx_active = NULL;
|
||||
AVCodecContext *sctx_active = NULL;
|
||||
|
||||
#ifdef HAVE_SSA
|
||||
ASS_Track *ass_track_active = NULL;
|
||||
#endif
|
||||
@@ -1591,22 +1618,25 @@ static void decode_thread(void *data)
|
||||
decode_thread_seek(seek_time_thread);
|
||||
|
||||
slock_lock(fifo_lock);
|
||||
do_seek = false;
|
||||
seek_time = 0.0;
|
||||
do_seek = false;
|
||||
eof = false;
|
||||
seek_time = 0.0;
|
||||
next_video_end = 0.0;
|
||||
next_audio_start = 0.0;
|
||||
last_audio_end = 0.0;
|
||||
|
||||
if (audio_decode_fifo)
|
||||
fifo_clear(audio_decode_fifo);
|
||||
|
||||
packet_buffer_clear(&audio_packet_buffer);
|
||||
packet_buffer_clear(&video_packet_buffer);
|
||||
|
||||
scond_signal(fifo_cond);
|
||||
slock_unlock(fifo_lock);
|
||||
}
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
if (av_read_frame(fctx, &pkt) < 0)
|
||||
break;
|
||||
|
||||
slock_lock(decode_thread_lock);
|
||||
audio_stream = audio_streams[audio_streams_ptr];
|
||||
audio_stream_index = audio_streams[audio_streams_ptr];
|
||||
audio_stream_ptr = audio_streams_ptr;
|
||||
subtitle_stream = subtitle_streams[subtitle_streams_ptr];
|
||||
actx_active = actx[audio_streams_ptr];
|
||||
@@ -1614,22 +1644,84 @@ static void decode_thread(void *data)
|
||||
#ifdef HAVE_SSA
|
||||
ass_track_active = ass_track[subtitle_streams_ptr];
|
||||
#endif
|
||||
audio_timebase = av_q2d(fctx->streams[audio_stream_index]->time_base);
|
||||
if (video_stream_index >= 0)
|
||||
video_timebase = av_q2d(fctx->streams[video_stream_index]->time_base);
|
||||
slock_unlock(decode_thread_lock);
|
||||
|
||||
if (pkt.stream_index == video_stream_index)
|
||||
#ifdef HAVE_SSA
|
||||
decode_video(vctx, &pkt, frame_size, ass_track_active);
|
||||
#else
|
||||
decode_video(vctx, &pkt, frame_size);
|
||||
#endif
|
||||
else if (pkt.stream_index == audio_stream && actx_active)
|
||||
if (!packet_buffer_empty(audio_packet_buffer))
|
||||
next_audio_start = audio_timebase * packet_buffer_peek_start_pts(audio_packet_buffer);
|
||||
|
||||
if (!packet_buffer_empty(video_packet_buffer))
|
||||
next_video_end = video_timebase * packet_buffer_peek_end_pts(video_packet_buffer);
|
||||
|
||||
/*
|
||||
* Decode audio packet if:
|
||||
* 1. it's the start of file or it's audio only media
|
||||
* 2. there is a video packet for in the buffer
|
||||
* 3. EOF
|
||||
**/
|
||||
if (!packet_buffer_empty(audio_packet_buffer) &&
|
||||
(
|
||||
next_video_end == 0.0 ||
|
||||
(!eof && earlier_or_close_enough(next_audio_start, next_video_end)) ||
|
||||
eof
|
||||
)
|
||||
)
|
||||
{
|
||||
audio_buffer = decode_audio(actx_active, &pkt, aud_frame,
|
||||
audio_buffer, &audio_buffer_cap,
|
||||
swr[audio_stream_ptr]);
|
||||
packet_buffer_get_packet(audio_packet_buffer, pkt);
|
||||
last_audio_end = audio_timebase * (pkt->pts + pkt->duration);
|
||||
audio_buffer = decode_audio(actx_active, pkt, aud_frame,
|
||||
audio_buffer, &audio_buffer_cap,
|
||||
swr[audio_stream_ptr]);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
else if (pkt.stream_index == subtitle_stream && sctx_active)
|
||||
|
||||
/*
|
||||
* Decode video packet if:
|
||||
* 1. we already decoded an audio packet
|
||||
* 2. there is no audio stream to play
|
||||
* 3. EOF
|
||||
**/
|
||||
if (!packet_buffer_empty(video_packet_buffer) &&
|
||||
(
|
||||
(!eof && earlier_or_close_enough(next_video_end, last_audio_end)) ||
|
||||
!actx_active ||
|
||||
eof
|
||||
)
|
||||
)
|
||||
{
|
||||
packet_buffer_get_packet(video_packet_buffer, pkt);
|
||||
|
||||
#ifdef HAVE_SSA
|
||||
decode_video(vctx, pkt, frame_size, ass_track_active);
|
||||
#else
|
||||
decode_video(vctx, pkt, frame_size);
|
||||
#endif
|
||||
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
|
||||
if (packet_buffer_empty(audio_packet_buffer) && packet_buffer_empty(video_packet_buffer) && eof)
|
||||
{
|
||||
av_packet_free(&pkt);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read the next frame and stage it in case of audio or video frame.
|
||||
if (av_read_frame(fctx, pkt) < 0)
|
||||
eof = true;
|
||||
else if (pkt->stream_index == audio_stream_index && actx_active)
|
||||
packet_buffer_add_packet(audio_packet_buffer, pkt);
|
||||
else if (pkt->stream_index == video_stream_index)
|
||||
packet_buffer_add_packet(video_packet_buffer, pkt);
|
||||
else if (pkt->stream_index == subtitle_stream && sctx_active)
|
||||
{
|
||||
/**
|
||||
* Decode subtitle packets right away, since SSA/ASS can operate this way.
|
||||
* If we ever support other subtitles, we need to handle this with a
|
||||
* buffer too
|
||||
**/
|
||||
AVSubtitle sub;
|
||||
int finished = 0;
|
||||
|
||||
@@ -1637,13 +1729,12 @@ static void decode_thread(void *data)
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
if (avcodec_decode_subtitle2(sctx_active, &sub, &finished, &pkt) < 0)
|
||||
if (avcodec_decode_subtitle2(sctx_active, &sub, &finished, pkt) < 0)
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, "[FFMPEG] Decode subtitles failed.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSA
|
||||
for (i = 0; i < sub.num_rects; i++)
|
||||
{
|
||||
@@ -1654,18 +1745,22 @@ static void decode_thread(void *data)
|
||||
slock_unlock(ass_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
avsubtitle_free(&sub);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
|
||||
av_free_packet(&pkt);
|
||||
av_packet_free(&pkt);
|
||||
}
|
||||
|
||||
for (i = 0; (int)i < audio_streams_num; i++)
|
||||
swr_free(&swr[i]);
|
||||
|
||||
#if ENABLE_HW_ACCEL
|
||||
if (vctx && vctx->hw_device_ctx)
|
||||
av_buffer_unref(&vctx->hw_device_ctx);
|
||||
#endif
|
||||
|
||||
packet_buffer_destroy(audio_packet_buffer);
|
||||
packet_buffer_destroy(video_packet_buffer);
|
||||
|
||||
av_frame_free(&aud_frame);
|
||||
av_freep(&audio_buffer);
|
||||
@@ -1967,9 +2062,9 @@ bool CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
|
||||
}
|
||||
if (audio_streams_num > 0)
|
||||
{
|
||||
/* audio fifo is 4 seconds deep */
|
||||
/* audio fifo is 2 seconds deep */
|
||||
audio_decode_fifo = fifo_new(
|
||||
media.sample_rate * sizeof(int16_t) * 2 * 4
|
||||
media.sample_rate * sizeof(int16_t) * 2 * 2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "packet_buffer.h"
|
||||
|
||||
struct AVPacketNode {
|
||||
AVPacket *data;
|
||||
struct AVPacketNode *next;
|
||||
struct AVPacketNode *previous;
|
||||
};
|
||||
typedef struct AVPacketNode AVPacketNode_t;
|
||||
|
||||
struct packet_buffer
|
||||
{
|
||||
AVPacketNode_t *head;
|
||||
AVPacketNode_t *tail;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
packet_buffer_t *packet_buffer_create()
|
||||
{
|
||||
packet_buffer_t *b = malloc(sizeof(packet_buffer_t));
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
memset(b, 0, sizeof(packet_buffer_t));
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void packet_buffer_destroy(packet_buffer_t *packet_buffer)
|
||||
{
|
||||
AVPacketNode_t *node;
|
||||
|
||||
if (!packet_buffer)
|
||||
return;
|
||||
|
||||
if (packet_buffer->head)
|
||||
{
|
||||
node = packet_buffer->head;
|
||||
while (node)
|
||||
{
|
||||
AVPacketNode_t *next = node->next;
|
||||
av_packet_free(&node->data);
|
||||
free(node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
free(packet_buffer);
|
||||
}
|
||||
|
||||
void packet_buffer_clear(packet_buffer_t **packet_buffer)
|
||||
{
|
||||
if (!packet_buffer)
|
||||
return;
|
||||
|
||||
packet_buffer_destroy(*packet_buffer);
|
||||
*packet_buffer = packet_buffer_create();
|
||||
}
|
||||
|
||||
bool packet_buffer_empty(packet_buffer_t *packet_buffer)
|
||||
{
|
||||
if (!packet_buffer)
|
||||
return true;
|
||||
|
||||
return packet_buffer->size == 0;
|
||||
}
|
||||
|
||||
size_t packet_buffer_size(packet_buffer_t *packet_buffer)
|
||||
{
|
||||
if (!packet_buffer)
|
||||
return 0;
|
||||
|
||||
return packet_buffer->size;
|
||||
}
|
||||
|
||||
void packet_buffer_add_packet(packet_buffer_t *packet_buffer, AVPacket *pkt)
|
||||
{
|
||||
AVPacketNode_t *new_head = (AVPacketNode_t *) malloc(sizeof(AVPacketNode_t));
|
||||
new_head->data = av_packet_alloc();
|
||||
|
||||
av_packet_move_ref(new_head->data, pkt);
|
||||
|
||||
if (packet_buffer->head)
|
||||
{
|
||||
new_head->next = packet_buffer->head;
|
||||
packet_buffer->head->previous = new_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_head->next = NULL;
|
||||
packet_buffer->tail = new_head;
|
||||
}
|
||||
|
||||
packet_buffer->head = new_head;
|
||||
packet_buffer->head->previous = NULL;
|
||||
packet_buffer->size++;
|
||||
}
|
||||
|
||||
void packet_buffer_get_packet(packet_buffer_t *packet_buffer, AVPacket *pkt)
|
||||
{
|
||||
AVPacketNode_t *new_tail = NULL;
|
||||
|
||||
if (packet_buffer->tail == NULL)
|
||||
return;
|
||||
|
||||
av_packet_move_ref(pkt, packet_buffer->tail->data);
|
||||
if (packet_buffer->tail->previous)
|
||||
{
|
||||
new_tail = packet_buffer->tail->previous;
|
||||
new_tail->next = NULL;
|
||||
}
|
||||
else
|
||||
packet_buffer->head = NULL;
|
||||
|
||||
av_packet_free(&packet_buffer->tail->data);
|
||||
free(packet_buffer->tail);
|
||||
|
||||
packet_buffer->tail = new_tail;
|
||||
packet_buffer->size--;
|
||||
}
|
||||
|
||||
int64_t packet_buffer_peek_start_pts(packet_buffer_t *packet_buffer)
|
||||
{
|
||||
if (!packet_buffer->tail)
|
||||
return 0;
|
||||
|
||||
return packet_buffer->tail->data->pts;
|
||||
}
|
||||
|
||||
int64_t packet_buffer_peek_end_pts(packet_buffer_t *packet_buffer)
|
||||
{
|
||||
if (!packet_buffer->tail)
|
||||
return 0;
|
||||
|
||||
return packet_buffer->tail->data->pts + packet_buffer->tail->data->duration;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#ifndef __LIBRETRO_SDK_PACKETBUFFER_H__
|
||||
#define __LIBRETRO_SDK_PACKETBUFFER_H__
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* packet_buffer
|
||||
*
|
||||
* Just a simple double linked list for AVPackets.
|
||||
*
|
||||
*/
|
||||
struct packet_buffer;
|
||||
typedef struct packet_buffer packet_buffer_t;
|
||||
|
||||
/**
|
||||
* packet_buffer_create:
|
||||
*
|
||||
* Create a packet_buffer.
|
||||
*
|
||||
* Returns: A packet buffer.
|
||||
*/
|
||||
packet_buffer_t *packet_buffer_create();
|
||||
|
||||
/**
|
||||
* packet_buffer_destroy:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Destroys a packet buffer.
|
||||
*
|
||||
**/
|
||||
void packet_buffer_destroy(packet_buffer_t *packet_buffer);
|
||||
|
||||
/**
|
||||
* packet_buffer_clear:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Clears a packet buffer by re-creating it.
|
||||
*
|
||||
**/
|
||||
void packet_buffer_clear(packet_buffer_t **packet_buffer);
|
||||
|
||||
/**
|
||||
* packet_buffer_empty:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Return true if the buffer is empty;
|
||||
*
|
||||
**/
|
||||
bool packet_buffer_empty(packet_buffer_t *packet_buffer);
|
||||
|
||||
/**
|
||||
* packet_buffer_size:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Returns the number of AVPackets the buffer currently
|
||||
* holds.
|
||||
*
|
||||
**/
|
||||
size_t packet_buffer_size(packet_buffer_t *packet_buffer);
|
||||
|
||||
/**
|
||||
* packet_buffer_add_packet:
|
||||
* @packet_buffer : packet buffer
|
||||
* @pkt : packet
|
||||
*
|
||||
* Copies the given packet into the selected buffer.
|
||||
*
|
||||
**/
|
||||
void packet_buffer_add_packet(packet_buffer_t *packet_buffer, AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* packet_buffer_get_packet:
|
||||
* @packet_buffer : packet buffer
|
||||
* @pkt : packet
|
||||
*
|
||||
* Get the next packet. User needs to unref the packet with av_packet_unref().
|
||||
*
|
||||
**/
|
||||
void packet_buffer_get_packet(packet_buffer_t *packet_buffer, AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* packet_buffer_peek_start_pts:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Returns the start pts of the next packet in the buffer.
|
||||
*
|
||||
**/
|
||||
int64_t packet_buffer_peek_start_pts(packet_buffer_t *packet_buffer);
|
||||
|
||||
/**
|
||||
* packet_buffer_peek_end_pts:
|
||||
* @packet_buffer : packet buffer
|
||||
*
|
||||
* Returns the end pts of the next packet in the buffer.
|
||||
*
|
||||
**/
|
||||
int64_t packet_buffer_peek_end_pts(packet_buffer_t *packet_buffer);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ struct video_buffer
|
||||
{
|
||||
video_decoder_context_t *buffer;
|
||||
enum kbStatus *status;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
slock_t *lock;
|
||||
scond_t *open_cond;
|
||||
scond_t *finished_cond;
|
||||
@@ -23,24 +23,19 @@ struct video_buffer
|
||||
int64_t tail;
|
||||
};
|
||||
|
||||
video_buffer_t *video_buffer_create(size_t num, int frame_size, int width, int height)
|
||||
video_buffer_t *video_buffer_create(size_t capacity, int frame_size, int width, int height)
|
||||
{
|
||||
video_buffer_t *b = malloc(sizeof (video_buffer_t));
|
||||
video_buffer_t *b = malloc(sizeof(video_buffer_t));
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
b->lock = NULL;
|
||||
b->open_cond = NULL;
|
||||
b->finished_cond = NULL;
|
||||
b->buffer = NULL;
|
||||
b->size = num;
|
||||
b->head = 0;
|
||||
b->tail = 0;
|
||||
memset(b, 0, sizeof(video_buffer_t));
|
||||
b->capacity = capacity;
|
||||
|
||||
b->status = malloc(sizeof(enum kbStatus) * num);
|
||||
b->status = malloc(sizeof(enum kbStatus) * capacity);
|
||||
if (!b->status)
|
||||
goto fail;
|
||||
for (int i = 0; i < num; i++)
|
||||
for (int i = 0; i < capacity; i++)
|
||||
b->status[i] = KB_OPEN;
|
||||
|
||||
b->lock = slock_new();
|
||||
@@ -49,11 +44,11 @@ video_buffer_t *video_buffer_create(size_t num, int frame_size, int width, int h
|
||||
if (!b->lock || !b->open_cond || !b->finished_cond)
|
||||
goto fail;
|
||||
|
||||
b->buffer = malloc(sizeof(video_decoder_context_t) * num);
|
||||
b->buffer = malloc(sizeof(video_decoder_context_t) * capacity);
|
||||
if (!b->buffer)
|
||||
goto fail;
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
b->buffer[i].index = i;
|
||||
b->buffer[i].pts = 0;
|
||||
@@ -94,7 +89,7 @@ void video_buffer_destroy(video_buffer_t *video_buffer)
|
||||
scond_free(video_buffer->finished_cond);
|
||||
free(video_buffer->status);
|
||||
if (video_buffer->buffer)
|
||||
for (int i = 0; i < video_buffer->size; i++)
|
||||
for (int i = 0; i < video_buffer->capacity; i++)
|
||||
{
|
||||
#if LIBAVUTIL_VERSION_MAJOR > 55
|
||||
av_frame_free(&video_buffer->buffer[i].hw_source);
|
||||
@@ -120,7 +115,7 @@ void video_buffer_clear(video_buffer_t *video_buffer)
|
||||
|
||||
video_buffer->head = 0;
|
||||
video_buffer->tail = 0;
|
||||
for (int i = 0; i < video_buffer->size; i++)
|
||||
for (int i = 0; i < video_buffer->capacity; i++)
|
||||
video_buffer->status[i] = KB_OPEN;
|
||||
|
||||
slock_unlock(video_buffer->lock);
|
||||
@@ -135,7 +130,7 @@ void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_cont
|
||||
*context = &video_buffer->buffer[video_buffer->head];
|
||||
video_buffer->status[video_buffer->head] = KB_IN_PROGRESS;
|
||||
video_buffer->head++;
|
||||
video_buffer->head %= video_buffer->size;
|
||||
video_buffer->head %= video_buffer->capacity;
|
||||
}
|
||||
|
||||
slock_unlock(video_buffer->lock);
|
||||
@@ -149,7 +144,7 @@ void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_c
|
||||
{
|
||||
video_buffer->status[context->index] = KB_OPEN;
|
||||
video_buffer->head--;
|
||||
video_buffer->head %= video_buffer->size;
|
||||
video_buffer->head %= video_buffer->capacity;
|
||||
}
|
||||
|
||||
slock_unlock(video_buffer->lock);
|
||||
@@ -163,7 +158,7 @@ void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_
|
||||
{
|
||||
video_buffer->status[context->index] = KB_OPEN;
|
||||
video_buffer->tail++;
|
||||
video_buffer->tail %= (video_buffer->size);
|
||||
video_buffer->tail %= (video_buffer->capacity);
|
||||
scond_signal(video_buffer->open_cond);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef __LIBRETRO_SDK_SWSBUFFER_H__
|
||||
#define __LIBRETRO_SDK_SWSBUFFER_H__
|
||||
#ifndef __LIBRETRO_SDK_VIDEOBUFFER_H__
|
||||
#define __LIBRETRO_SDK_VIDEOBUFFER_H__
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
@@ -47,7 +47,7 @@ typedef struct video_decoder_context video_decoder_context_t;
|
||||
/**
|
||||
* video_buffer
|
||||
*
|
||||
* The video_buffer is a ring buffer, that can be used as a
|
||||
* The video buffer is a ring buffer, that can be used as a
|
||||
* buffer for many workers while keeping the order.
|
||||
*
|
||||
* It is thread safe in a sensem that it is designed to work
|
||||
@@ -61,26 +61,26 @@ typedef struct video_buffer video_buffer_t;
|
||||
|
||||
/**
|
||||
* video_buffer_create:
|
||||
* @num : Size of the buffer.
|
||||
* @capacity : Size of the buffer.
|
||||
* @frame_size : Size of the target frame.
|
||||
* @width : Width of the target frame.
|
||||
* @height : Height of the target frame.
|
||||
*
|
||||
* Create a video_buffer.
|
||||
* Create a video buffer.
|
||||
*
|
||||
* Returns: A video buffer.
|
||||
*/
|
||||
video_buffer_t *video_buffer_create(size_t num, int frame_size, int width, int height);
|
||||
video_buffer_t *video_buffer_create(size_t capacity, int frame_size, int width, int height);
|
||||
|
||||
/**
|
||||
* video_buffer_destroy:
|
||||
* @video_buffer : video buffer.
|
||||
*
|
||||
* Destory a video_buffer.
|
||||
* Destroys a video buffer.
|
||||
*
|
||||
* Does also free the buffer allocated with video_buffer_create().
|
||||
* User has to shut down any external worker threads that may have
|
||||
* a reference to this video_buffer.
|
||||
* a reference to this video buffer.
|
||||
*
|
||||
**/
|
||||
void video_buffer_destroy(video_buffer_t *video_buffer);
|
||||
@@ -89,7 +89,7 @@ void video_buffer_destroy(video_buffer_t *video_buffer);
|
||||
* video_buffer_clear:
|
||||
* @video_buffer : video buffer.
|
||||
*
|
||||
* Clears a video_buffer.
|
||||
* Clears a video buffer.
|
||||
*
|
||||
**/
|
||||
void video_buffer_clear(video_buffer_t *video_buffer);
|
||||
@@ -97,7 +97,7 @@ void video_buffer_clear(video_buffer_t *video_buffer);
|
||||
/**
|
||||
* video_buffer_get_open_slot:
|
||||
* @video_buffer : video buffer.
|
||||
* @contex : sws context.
|
||||
* @context : sws context.
|
||||
*
|
||||
* Returns the next open context inside the ring buffer
|
||||
* and it's index. The status of the slot will be marked as
|
||||
@@ -110,7 +110,7 @@ void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_cont
|
||||
/**
|
||||
* video_buffer_return_open_slot:
|
||||
* @video_buffer : video buffer.
|
||||
* @contex : sws context.
|
||||
* @context : sws context.
|
||||
*
|
||||
* Marks the given sws context that is "in progress" as "open" again.
|
||||
*
|
||||
@@ -120,7 +120,7 @@ void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_c
|
||||
/**
|
||||
* video_buffer_open_slot:
|
||||
* @video_buffer : video buffer.
|
||||
* @context : sws context.
|
||||
* @context : sws context.
|
||||
*
|
||||
* Sets the status of the given context from "finished" to "open".
|
||||
* The slot is then available for producers to claim again with video_buffer_get_open_slot().
|
||||
@@ -130,21 +130,20 @@ void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_
|
||||
/**
|
||||
* video_buffer_get_finished_slot:
|
||||
* @video_buffer : video buffer.
|
||||
* @context : sws context.
|
||||
* @context : sws context.
|
||||
*
|
||||
* Returns a reference for the next context inside
|
||||
* the ring buffer. User needs to use video_buffer_open_slot()
|
||||
* to open the slot in the ringbuffer for the next
|
||||
* work assignment. User is free to re-allocate or
|
||||
* re-use the context.
|
||||
*
|
||||
*/
|
||||
void video_buffer_get_finished_slot(video_buffer_t *video_buffer, video_decoder_context_t **context);
|
||||
|
||||
/**
|
||||
* video_buffer_finish_slot:
|
||||
* @video_buffer : video buffer.
|
||||
* @context : sws context.
|
||||
* @context : sws context.
|
||||
*
|
||||
* Sets the status of the given context from "in progress" to "finished".
|
||||
* This is normally done by a producer. User can then retrieve the finished work
|
||||
|
||||
@@ -8,6 +8,7 @@ image_core.so: image_core.c
|
||||
../../libretro-common/compat/compat_strcasestr.c \
|
||||
../../libretro-common/compat/compat_strl.c \
|
||||
../../libretro-common/file/file_path.c \
|
||||
../../libretro-common/file/file_path_io.c \
|
||||
../../libretro-common/file/retro_dirent.c \
|
||||
../../libretro-common/lists/dir_list.c \
|
||||
../../libretro-common/lists/string_list.c \
|
||||
|
||||
Vendored
+3
@@ -1,7 +1,10 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse) {
|
||||
rc_condset_t** next;
|
||||
|
||||
Vendored
+3
@@ -1,6 +1,9 @@
|
||||
#include "internal.h"
|
||||
|
||||
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
static void rc_parse_cond_value(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) {
|
||||
rc_condition_t** next;
|
||||
|
||||
+15
-13
@@ -17,13 +17,17 @@
|
||||
#include <string/stdstring.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include <net/net_http.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <file/file_path.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "discord.h"
|
||||
#include "discord_register.h"
|
||||
|
||||
#include "../deps/discord-rpc/include/discord_rpc.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../configuration.h"
|
||||
#include "../core.h"
|
||||
#include "../core_info.h"
|
||||
#include "../paths.h"
|
||||
@@ -47,14 +51,10 @@
|
||||
#include "../../menu/menu_cbs.h"
|
||||
#endif
|
||||
|
||||
#include <net/net_http.h>
|
||||
#include "../network/net_http_special.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
#include <streams/file_stream.h>
|
||||
#include <file/file_path.h>
|
||||
#include "../file_path_special.h"
|
||||
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
static int64_t start_time = 0;
|
||||
static int64_t pause_time = 0;
|
||||
@@ -211,7 +211,7 @@ static void handle_discord_join_cb(retro_task_t *task,
|
||||
task_push_netplay_crc_scan(room->gamecrc,
|
||||
room->gamename, join_hostname, room->corename, room->subsystem_name);
|
||||
connecting = true;
|
||||
discord_update(DISCORD_PRESENCE_NETPLAY_CLIENT);
|
||||
discord_update(DISCORD_PRESENCE_NETPLAY_CLIENT, false);
|
||||
}
|
||||
|
||||
finish:
|
||||
@@ -303,7 +303,9 @@ static void handle_discord_join_request(const DiscordUser* request)
|
||||
#endif
|
||||
}
|
||||
|
||||
void discord_update(enum discord_presence presence)
|
||||
/* TODO/FIXME - replace last parameter with struct type to allow for more
|
||||
* arguments to be passed later */
|
||||
void discord_update(enum discord_presence presence, bool fuzzy_archive_match)
|
||||
{
|
||||
core_info_t *core_info = NULL;
|
||||
|
||||
@@ -351,7 +353,8 @@ void discord_update(enum discord_presence presence)
|
||||
if (current_playlist)
|
||||
{
|
||||
playlist_get_index_by_path(
|
||||
current_playlist, path_get(RARCH_PATH_CONTENT), &entry);
|
||||
current_playlist, path_get(RARCH_PATH_CONTENT), &entry,
|
||||
fuzzy_archive_match);
|
||||
|
||||
if (entry && !string_is_empty(entry->label))
|
||||
label = entry->label;
|
||||
@@ -464,11 +467,10 @@ void discord_update(enum discord_presence presence)
|
||||
discord_status = presence;
|
||||
}
|
||||
|
||||
void discord_init(void)
|
||||
void discord_init(const char *discord_app_id)
|
||||
{
|
||||
char full_path[PATH_MAX_LENGTH];
|
||||
char command[PATH_MAX_LENGTH];
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
DiscordEventHandlers handlers;
|
||||
|
||||
@@ -483,10 +485,10 @@ void discord_init(void)
|
||||
handlers.spectateGame = handle_discord_spectate;
|
||||
handlers.joinRequest = handle_discord_join_request;
|
||||
|
||||
Discord_Initialize(settings->arrays.discord_app_id, &handlers, 0, NULL);
|
||||
Discord_Initialize(discord_app_id, &handlers, 0, NULL);
|
||||
|
||||
#ifdef _WIN32
|
||||
GetModuleFileNameA(NULL, full_path, sizeof(full_path));
|
||||
fill_pathname_application_path(full_path, sizeof(full_path));
|
||||
if (strstr(get_retroarch_launch_arguments(), full_path))
|
||||
strlcpy(command, get_retroarch_launch_arguments(), sizeof(command));
|
||||
else
|
||||
@@ -500,7 +502,7 @@ void discord_init(void)
|
||||
get_retroarch_launch_arguments());
|
||||
#endif
|
||||
RARCH_LOG("[discord] registering startup command: %s\n", command);
|
||||
Discord_Register(settings->arrays.discord_app_id, command);
|
||||
Discord_Register(discord_app_id, command);
|
||||
discord_ready = true;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -41,11 +41,11 @@ typedef struct discord_userdata
|
||||
enum discord_presence status;
|
||||
} discord_userdata_t;
|
||||
|
||||
void discord_init(void);
|
||||
void discord_init(const char *discord_app_id);
|
||||
|
||||
void discord_shutdown(void);
|
||||
|
||||
void discord_update(enum discord_presence presence);
|
||||
void discord_update(enum discord_presence presence, bool fuzzy_archive_match);
|
||||
|
||||
bool discord_is_ready(void);
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ struct retro_core_t
|
||||
bool symbols_inited;
|
||||
bool game_loaded;
|
||||
bool input_polled;
|
||||
bool has_set_subsystems;
|
||||
bool has_set_input_descriptors;
|
||||
uint64_t serialization_quirks_v;
|
||||
};
|
||||
|
||||
@@ -396,6 +396,8 @@ void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id);
|
||||
static void frontend_ctr_init(void* data)
|
||||
{
|
||||
#ifndef IS_SALAMANDER
|
||||
extern audio_driver_t audio_null;
|
||||
|
||||
(void)data;
|
||||
|
||||
verbosity_enable();
|
||||
@@ -483,7 +485,7 @@ static int frontend_ctr_parse_drive_list(void* data, bool load_content)
|
||||
file_list_t* list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content
|
||||
? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR
|
||||
: MSG_UNKNOWN;
|
||||
: MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
if (!list)
|
||||
return -1;
|
||||
|
||||
@@ -734,7 +734,7 @@ static int frontend_darwin_parse_drive_list(void *data, bool load_content)
|
||||
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
bundle_url = CFBundleCopyBundleURL(bundle);
|
||||
bundle_path = CFURLCopyPath(bundle_url);
|
||||
|
||||
@@ -49,22 +49,8 @@
|
||||
void RWebAudioRecalibrateTime(void);
|
||||
void dummyErrnoCodes(void);
|
||||
|
||||
static unsigned emscripten_fullscreen_reinit;
|
||||
static unsigned emscripten_frame_count = 0;
|
||||
|
||||
static EM_BOOL emscripten_fullscreenchange_cb(int event_type,
|
||||
const EmscriptenFullscreenChangeEvent *fullscreen_change_event,
|
||||
void *user_data)
|
||||
{
|
||||
(void)event_type;
|
||||
(void)fullscreen_change_event;
|
||||
(void)user_data;
|
||||
|
||||
emscripten_fullscreen_reinit = 5;
|
||||
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
static void emscripten_mainloop(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -92,12 +78,6 @@ static void emscripten_mainloop(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (emscripten_fullscreen_reinit != 0)
|
||||
{
|
||||
if (--emscripten_fullscreen_reinit == 0)
|
||||
command_event(CMD_EVENT_REINIT, NULL);
|
||||
}
|
||||
|
||||
ret = runloop_iterate();
|
||||
|
||||
task_queue_check();
|
||||
@@ -221,8 +201,6 @@ static void frontend_emscripten_get_env(int *argc, char *argv[],
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
EMSCRIPTEN_RESULT r;
|
||||
|
||||
dummyErrnoCodes();
|
||||
|
||||
emscripten_set_canvas_element_size("#canvas", 800, 600);
|
||||
@@ -230,14 +208,6 @@ int main(int argc, char *argv[])
|
||||
emscripten_set_main_loop(emscripten_mainloop, 0, 0);
|
||||
rarch_main(argc, argv, NULL);
|
||||
|
||||
r = emscripten_set_fullscreenchange_callback("#document", NULL, false,
|
||||
emscripten_fullscreenchange_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/CTX] failed to create fullscreen callback: %d\n", r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@ static int frontend_gx_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
#ifdef HW_RVL
|
||||
menu_entries_append_enum(list,
|
||||
"sd:/",
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* * You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../frontend_driver.h"
|
||||
|
||||
frontend_ctx_driver_t frontend_ctx_null = {
|
||||
NULL, /* environment_get */
|
||||
NULL, /* init */
|
||||
NULL, /* deinit */
|
||||
NULL, /* exitspawn */
|
||||
NULL, /* process_args */
|
||||
NULL, /* exec */
|
||||
NULL, /* set_fork */
|
||||
NULL, /* shutdown */
|
||||
NULL, /* get_name */
|
||||
NULL, /* get_os */
|
||||
NULL, /* get_rating */
|
||||
NULL, /* load_content */
|
||||
NULL, /* get_architecture */
|
||||
NULL, /* get_powerstate */
|
||||
NULL, /* parse_drive_list */
|
||||
NULL, /* get_mem_total */
|
||||
NULL, /* get_mem_free */
|
||||
NULL, /* install_signal_handler */
|
||||
NULL, /* get_sighandler_state */
|
||||
NULL, /* set_sighandler_state */
|
||||
NULL, /* destroy_sighandler_state */
|
||||
NULL, /* attach_console */
|
||||
NULL, /* detach_console */
|
||||
#ifdef HAVE_LAKKA
|
||||
NULL, /* get_lakka_version */
|
||||
#endif
|
||||
NULL, /* watch_path_for_changes */
|
||||
NULL, /* check_for_path_changes */
|
||||
NULL, /* set_sustained_performance_mode */
|
||||
NULL, /* get_cpu_model_name */
|
||||
NULL, /* get_user_language */
|
||||
"null",
|
||||
};
|
||||
@@ -329,7 +329,7 @@ static int frontend_orbis_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
menu_entries_append_enum(list,
|
||||
"host0:app",
|
||||
|
||||
@@ -341,7 +341,7 @@ static int frontend_ps2_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
menu_entries_append_enum(list,
|
||||
rootDevicePath(BOOT_DEVICE_MC0),
|
||||
|
||||
@@ -528,7 +528,7 @@ static int frontend_ps3_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
menu_entries_append_enum(list,
|
||||
"/app_home/",
|
||||
|
||||
@@ -449,7 +449,7 @@ static int frontend_psp_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
#ifdef VITA
|
||||
menu_entries_append_enum(list,
|
||||
|
||||
@@ -691,7 +691,7 @@ static void frontend_switch_init(void *data)
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
nifmInitialize();
|
||||
nifmInitialize(NifmServiceType_User);
|
||||
|
||||
if(hosversionBefore(8, 0, 0))
|
||||
pcvInitialize();
|
||||
@@ -801,7 +801,7 @@ static int frontend_switch_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t *)data;
|
||||
enum msg_hash_enums enum_idx = load_content
|
||||
? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR
|
||||
: MSG_UNKNOWN;
|
||||
: MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
if (!list)
|
||||
return -1;
|
||||
|
||||
@@ -1923,7 +1923,7 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
#ifdef ANDROID
|
||||
if (!string_is_empty(internal_storage_path))
|
||||
|
||||
@@ -277,7 +277,7 @@ static int frontend_uwp_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
char drive[] = " :\\";
|
||||
char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
bool have_any_drives = false;
|
||||
|
||||
@@ -173,7 +173,7 @@ static int frontend_wiiu_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t *)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
if (!list)
|
||||
return -1;
|
||||
|
||||
@@ -475,7 +475,7 @@ static int frontend_win32_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
size_t i = 0;
|
||||
unsigned drives = GetLogicalDrives();
|
||||
char drive[] = " :\\";
|
||||
|
||||
@@ -368,7 +368,7 @@ static int frontend_xdk_parse_drive_list(void *data, bool load_content)
|
||||
file_list_t *list = (file_list_t*)data;
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY;
|
||||
|
||||
#if defined(_XBOX1)
|
||||
menu_entries_append_enum(list,
|
||||
|
||||
@@ -36,6 +36,42 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static frontend_ctx_driver_t frontend_ctx_null = {
|
||||
NULL, /* environment_get */
|
||||
NULL, /* init */
|
||||
NULL, /* deinit */
|
||||
NULL, /* exitspawn */
|
||||
NULL, /* process_args */
|
||||
NULL, /* exec */
|
||||
NULL, /* set_fork */
|
||||
NULL, /* shutdown */
|
||||
NULL, /* get_name */
|
||||
NULL, /* get_os */
|
||||
NULL, /* get_rating */
|
||||
NULL, /* load_content */
|
||||
NULL, /* get_architecture */
|
||||
NULL, /* get_powerstate */
|
||||
NULL, /* parse_drive_list */
|
||||
NULL, /* get_mem_total */
|
||||
NULL, /* get_mem_free */
|
||||
NULL, /* install_signal_handler */
|
||||
NULL, /* get_sighandler_state */
|
||||
NULL, /* set_sighandler_state */
|
||||
NULL, /* destroy_sighandler_state */
|
||||
NULL, /* attach_console */
|
||||
NULL, /* detach_console */
|
||||
#ifdef HAVE_LAKKA
|
||||
NULL, /* get_lakka_version */
|
||||
#endif
|
||||
NULL, /* watch_path_for_changes */
|
||||
NULL, /* check_for_path_changes */
|
||||
NULL, /* set_sustained_performance_mode */
|
||||
NULL, /* get_cpu_model_name */
|
||||
NULL, /* get_user_language */
|
||||
"null",
|
||||
NULL, /* get_video_driver */
|
||||
};
|
||||
|
||||
static frontend_ctx_driver_t *frontend_ctx_drivers[] = {
|
||||
#if defined(EMSCRIPTEN)
|
||||
&frontend_ctx_emscripten,
|
||||
|
||||
@@ -134,7 +134,6 @@ extern frontend_ctx_driver_t frontend_ctx_emscripten;
|
||||
extern frontend_ctx_driver_t frontend_ctx_dos;
|
||||
extern frontend_ctx_driver_t frontend_ctx_switch;
|
||||
extern frontend_ctx_driver_t frontend_ctx_orbis;
|
||||
extern frontend_ctx_driver_t frontend_ctx_null;
|
||||
|
||||
/**
|
||||
* frontend_ctx_find_driver:
|
||||
|
||||
+22
-54
@@ -30,7 +30,6 @@
|
||||
#include "../../verbosity.h"
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
|
||||
|
||||
/* Normal DirectX 11 backend */
|
||||
const EGLint backendD3D11[] =
|
||||
{
|
||||
@@ -87,21 +86,27 @@ const char* backendNamesList[] = {
|
||||
/* Try initializing EGL with the backend specified in display_attr. */
|
||||
static bool angle_try_initialize(egl_ctx_data_t* egl,
|
||||
void* display_data, const EGLint* display_attr,
|
||||
EGLint* major, EGLint* minor) {
|
||||
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
EGLint* major, EGLint* minor)
|
||||
{
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
if (!egl_init_dll())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT =
|
||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)egl_get_proc_address("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (ptr_eglGetPlatformDisplayEXT == NULL)
|
||||
if (!ptr_eglGetPlatformDisplayEXT)
|
||||
return false;
|
||||
|
||||
dpy = ptr_eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, display_data, display_attr);
|
||||
if (dpy == EGL_NO_DISPLAY) return false;
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
return false;
|
||||
|
||||
if (!eglInitialize(dpy, major, minor)) {
|
||||
eglTerminate(egl->dpy);
|
||||
if (!egl_initialize(dpy, major, minor))
|
||||
{
|
||||
egl_terminate(egl->dpy);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -117,60 +122,23 @@ bool angle_init_context(egl_ctx_data_t *egl,
|
||||
EGLint *count, const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb)
|
||||
{
|
||||
EGLint i; int j;
|
||||
EGLConfig *configs = NULL;
|
||||
EGLint matched = 0;
|
||||
int config_index = -1;
|
||||
int j;
|
||||
bool success = false;
|
||||
|
||||
for (j = 0; backendNamesList[j] != NULL; j++) {
|
||||
for (j = 0; backendNamesList[j] != NULL; j++)
|
||||
{
|
||||
RARCH_LOG("[ANGLE] Trying %s...\n", backendNamesList[j]);
|
||||
if (angle_try_initialize(egl, display_data, backendList[j], major, minor)) {
|
||||
if (angle_try_initialize(egl, display_data, backendList[j], major, minor))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) return false;
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
RARCH_LOG("[EGL]: EGL version: %d.%d\n", *major, *minor);
|
||||
|
||||
if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No configs to choose from.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
configs = (EGLConfig*)malloc(*count * sizeof(*configs));
|
||||
if (!configs)
|
||||
return false;
|
||||
|
||||
if (!eglChooseConfig(egl->dpy, attrib_ptr,
|
||||
configs, *count, &matched) || !matched)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No EGL configs with appropriate attributes.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < *count; i++)
|
||||
{
|
||||
if (!cb || cb(display_data, egl->dpy, configs[i]))
|
||||
{
|
||||
egl->config = configs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(configs);
|
||||
|
||||
if (i == *count)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No EGL config found which satifies requirements.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
egl->major = g_egl_major;
|
||||
egl->minor = g_egl_minor;
|
||||
|
||||
return true;
|
||||
return egl_init_context_common(egl, count, attrib_ptr, cb, display_data);
|
||||
}
|
||||
@@ -43,8 +43,9 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
bool angle_init_context(egl_ctx_data_t* egl, void* display_data, EGLint* major, EGLint* minor,
|
||||
EGLint* count, const EGLint* attrib_ptr, egl_accept_config_cb_t cb);
|
||||
bool angle_init_context(egl_ctx_data_t* egl,
|
||||
void* display_data, EGLint* major, EGLint* minor,
|
||||
EGLint* count, const EGLint* attrib_ptr, egl_accept_config_cb_t cb);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
||||
+240
-63
@@ -38,9 +38,149 @@ bool g_egl_inited = false;
|
||||
unsigned g_egl_major = 0;
|
||||
unsigned g_egl_minor = 0;
|
||||
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
typedef EGLBoolean(* PFN_EGL_QUERY_SURFACE)(
|
||||
EGLDisplay dpy,
|
||||
EGLSurface surface,
|
||||
EGLint attribute,
|
||||
EGLint *value);
|
||||
typedef void *(* PFN_EGL_GET_PROC_ADDRESS)(const char *procname);
|
||||
typedef EGLSurface(*PFN_EGL_CREATE_WINDOW_SURFACE) (EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLNativeWindowType win,
|
||||
const EGLint * attrib_list);
|
||||
typedef EGLContext(*PFN_EGL_CREATE_CONTEXT)(EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_context,
|
||||
const EGLint * attrib_list);
|
||||
typedef EGLBoolean(*PFN_EGL_GET_CONFIGS) (EGLDisplay dpy, EGLConfig * configs,
|
||||
EGLint config_size, EGLint * num_config);
|
||||
typedef EGLint(*PFN_EGL_GET_ERROR) (void);
|
||||
typedef EGLDisplay(*PFN_EGL_GET_DISPLAY) (EGLNativeDisplayType display_id);
|
||||
typedef EGLBoolean(*PFN_EGL_CHOOSE_CONFIG) (EGLDisplay dpy,
|
||||
const EGLint * attrib_list,
|
||||
EGLConfig * configs,
|
||||
EGLint config_size, EGLint * num_config);
|
||||
typedef EGLBoolean(*PFN_EGL_TERMINATE)(EGLDisplay dpy);
|
||||
typedef EGLBoolean(*PFN_EGL_INITIALIZE)(EGLDisplay dpy, EGLint * major,
|
||||
EGLint * minor);
|
||||
typedef EGLBoolean(*PFN_EGL_BIND_API) (EGLenum api);
|
||||
typedef EGLBoolean(*PFN_EGL_MAKE_CURRENT) (EGLDisplay dpy, EGLSurface draw,
|
||||
EGLSurface read, EGLContext ctx);
|
||||
typedef EGLBoolean(*PFN_EGL_DESTROY_SURFACE) (EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean(*PFN_EGL_DESTROY_CONTEXT) (EGLDisplay dpy, EGLContext ctx);
|
||||
typedef EGLContext(*PFN_EGL_GET_CURRENT_CONTEXT) (void);
|
||||
typedef const char *(*PFN_EGL_QUERY_STRING) (EGLDisplay dpy, EGLint name);
|
||||
typedef EGLBoolean(*PFN_EGL_GET_CONFIG_ATTRIB) (EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean(*PFN_EGL_SWAP_BUFFERS) (EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean(*PFN_EGL_SWAP_INTERVAL) (EGLDisplay dpy, EGLint interval);
|
||||
|
||||
static PFN_EGL_QUERY_SURFACE _egl_query_surface;
|
||||
static PFN_EGL_GET_PROC_ADDRESS _egl_get_proc_address;
|
||||
static PFN_EGL_CREATE_WINDOW_SURFACE _egl_create_window_surface;
|
||||
static PFN_EGL_CREATE_CONTEXT _egl_create_context;
|
||||
static PFN_EGL_GET_CONFIGS _egl_get_configs;
|
||||
static PFN_EGL_GET_ERROR _egl_get_error;
|
||||
static PFN_EGL_GET_DISPLAY _egl_get_display;
|
||||
static PFN_EGL_CHOOSE_CONFIG _egl_choose_config;
|
||||
static PFN_EGL_TERMINATE _egl_terminate;
|
||||
static PFN_EGL_INITIALIZE _egl_initialize;
|
||||
static PFN_EGL_BIND_API _egl_bind_api;
|
||||
static PFN_EGL_MAKE_CURRENT _egl_make_current;
|
||||
static PFN_EGL_DESTROY_SURFACE _egl_destroy_surface;
|
||||
static PFN_EGL_DESTROY_CONTEXT _egl_destroy_context;
|
||||
static PFN_EGL_GET_CURRENT_CONTEXT _egl_get_current_context;
|
||||
static PFN_EGL_QUERY_STRING _egl_query_string;
|
||||
static PFN_EGL_GET_CONFIG_ATTRIB _egl_get_config_attrib;
|
||||
static PFN_EGL_SWAP_BUFFERS _egl_swap_buffers;
|
||||
static PFN_EGL_SWAP_INTERVAL _egl_swap_interval;
|
||||
|
||||
#else
|
||||
#define _egl_query_surface(a, b, c, d) eglQuerySurface(a, b, c, d)
|
||||
#define _egl_get_proc_address(a) eglGetProcAddress(a)
|
||||
#define _egl_create_window_surface(a, b, c, d) eglCreateWindowSurface(a, b, c, d)
|
||||
#define _egl_create_context(a, b, c, d) eglCreateContext(a, b, c, d)
|
||||
#define _egl_get_configs(a, b, c, d) eglGetConfigs(a, b, c, d)
|
||||
#define _egl_get_display(a) eglGetDisplay(a)
|
||||
#define _egl_choose_config(a, b, c, d, e) eglChooseConfig(a, b, c, d, e)
|
||||
#define _egl_make_current(a, b, c, d) eglMakeCurrent(a, b, c, d)
|
||||
#define _egl_initialize(a, b, c) eglInitialize(a, b, c)
|
||||
#define _egl_destroy_surface(a, b) eglDestroySurface(a, b)
|
||||
#define _egl_destroy_context(a, b) eglDestroyContext(a, b)
|
||||
#define _egl_get_current_context() eglGetCurrentContext()
|
||||
#define _egl_get_error() eglGetError()
|
||||
#define _egl_terminate(dpy) eglTerminate(dpy)
|
||||
#define _egl_bind_api(a) eglBindAPI(a)
|
||||
#define _egl_query_string(a, b) eglQueryString(a, b)
|
||||
#define _egl_get_config_attrib(a, b, c, d) eglGetConfigAttrib(a, b, c, d)
|
||||
#define _egl_swap_buffers(a, b) eglSwapBuffers(a, b)
|
||||
#define _egl_swap_interval(a, b) eglSwapInterval(a, b)
|
||||
#endif
|
||||
|
||||
bool egl_init_dll(void)
|
||||
{
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
static dylib_t egl_dll;
|
||||
|
||||
if (!egl_dll)
|
||||
{
|
||||
egl_dll = dylib_load("libEGL.dll");
|
||||
if (egl_dll)
|
||||
{
|
||||
/* Setup function callbacks once */
|
||||
_egl_query_surface = (PFN_EGL_QUERY_SURFACE)dylib_proc(
|
||||
egl_dll, "eglQuerySurface");
|
||||
_egl_get_proc_address = (PFN_EGL_GET_PROC_ADDRESS)dylib_proc(
|
||||
egl_dll, "eglGetProcAddress");
|
||||
_egl_create_window_surface = (PFN_EGL_CREATE_WINDOW_SURFACE)dylib_proc(
|
||||
egl_dll, "eglCreateWindowSurface");
|
||||
_egl_create_context = (PFN_EGL_CREATE_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglCreateContext");
|
||||
_egl_get_configs = (PFN_EGL_GET_CONFIGS)dylib_proc(
|
||||
egl_dll, "eglGetConfigs");
|
||||
_egl_get_error = (PFN_EGL_GET_ERROR)dylib_proc(
|
||||
egl_dll, "eglGetError");
|
||||
_egl_get_display = (PFN_EGL_GET_DISPLAY)dylib_proc(
|
||||
egl_dll, "eglGetDisplay");
|
||||
_egl_choose_config = (PFN_EGL_CHOOSE_CONFIG)dylib_proc(
|
||||
egl_dll, "eglChooseConfig");
|
||||
_egl_terminate = (PFN_EGL_TERMINATE)dylib_proc(
|
||||
egl_dll, "eglTerminate");
|
||||
_egl_initialize = (PFN_EGL_INITIALIZE)dylib_proc(
|
||||
egl_dll, "eglInitialize");
|
||||
_egl_bind_api = (PFN_EGL_BIND_API)dylib_proc(
|
||||
egl_dll, "eglBindAPI");
|
||||
_egl_make_current = (PFN_EGL_MAKE_CURRENT)dylib_proc(
|
||||
egl_dll, "eglMakeCurrent");
|
||||
_egl_destroy_surface = (PFN_EGL_DESTROY_SURFACE)dylib_proc(
|
||||
egl_dll, "eglDestroySurface");
|
||||
_egl_destroy_context = (PFN_EGL_DESTROY_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglDestroyContext");
|
||||
_egl_get_current_context = (PFN_EGL_GET_CURRENT_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglGetCurrentContext");
|
||||
_egl_query_string = (PFN_EGL_QUERY_STRING)dylib_proc(
|
||||
egl_dll, "eglQueryString");
|
||||
_egl_get_config_attrib = (PFN_EGL_GET_CONFIG_ATTRIB)dylib_proc(
|
||||
egl_dll, "eglGetConfigAttrib");
|
||||
_egl_swap_buffers = (PFN_EGL_SWAP_BUFFERS)dylib_proc(
|
||||
egl_dll, "eglSwapBuffers");
|
||||
_egl_swap_interval = (PFN_EGL_SWAP_INTERVAL)dylib_proc(
|
||||
egl_dll, "eglSwapInterval");
|
||||
}
|
||||
}
|
||||
|
||||
if (egl_dll)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void egl_report_error(void)
|
||||
{
|
||||
EGLint error = eglGetError();
|
||||
EGLint error = _egl_get_error();
|
||||
const char *str = NULL;
|
||||
switch (error)
|
||||
{
|
||||
@@ -106,7 +246,28 @@ void egl_report_error(void)
|
||||
|
||||
gfx_ctx_proc_t egl_get_proc_address(const char *symbol)
|
||||
{
|
||||
return eglGetProcAddress(symbol);
|
||||
return _egl_get_proc_address(symbol);
|
||||
}
|
||||
|
||||
void egl_terminate(EGLDisplay dpy)
|
||||
{
|
||||
_egl_terminate(dpy);
|
||||
}
|
||||
|
||||
bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, EGLint attribute,
|
||||
EGLint *value)
|
||||
{
|
||||
return _egl_get_config_attrib(dpy, config, attribute, value);
|
||||
}
|
||||
|
||||
bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
{
|
||||
return _egl_initialize(dpy, major, minor);
|
||||
}
|
||||
|
||||
bool egl_bind_api(EGLenum egl_api)
|
||||
{
|
||||
return _egl_bind_api(egl_api);
|
||||
}
|
||||
|
||||
void egl_destroy(egl_ctx_data_t *egl)
|
||||
@@ -123,17 +284,17 @@ void egl_destroy(egl_ctx_data_t *egl)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
eglMakeCurrent(egl->dpy,
|
||||
_egl_make_current(egl->dpy,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (egl->ctx != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(egl->dpy, egl->ctx);
|
||||
_egl_destroy_context(egl->dpy, egl->ctx);
|
||||
|
||||
if (egl->hw_ctx != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(egl->dpy, egl->hw_ctx);
|
||||
_egl_destroy_context(egl->dpy, egl->hw_ctx);
|
||||
|
||||
if (egl->surf != EGL_NO_SURFACE)
|
||||
eglDestroySurface(egl->dpy, egl->surf);
|
||||
eglTerminate(egl->dpy);
|
||||
_egl_destroy_surface(egl->dpy, egl->surf);
|
||||
egl_terminate(egl->dpy);
|
||||
}
|
||||
|
||||
/* Be as careful as possible in deinit.
|
||||
@@ -159,7 +320,7 @@ void egl_bind_hw_render(egl_ctx_data_t *egl, bool enable)
|
||||
if (egl->surf == EGL_NO_SURFACE)
|
||||
return;
|
||||
|
||||
eglMakeCurrent(egl->dpy, egl->surf,
|
||||
_egl_make_current(egl->dpy, egl->surf,
|
||||
egl->surf,
|
||||
enable ? egl->hw_ctx : egl->ctx);
|
||||
}
|
||||
@@ -171,7 +332,7 @@ void egl_swap_buffers(void *data)
|
||||
egl->dpy != EGL_NO_DISPLAY &&
|
||||
egl->surf != EGL_NO_SURFACE
|
||||
)
|
||||
eglSwapBuffers(egl->dpy, egl->surf);
|
||||
_egl_swap_buffers(egl->dpy, egl->surf);
|
||||
}
|
||||
|
||||
void egl_set_swap_interval(egl_ctx_data_t *egl, int interval)
|
||||
@@ -184,11 +345,11 @@ void egl_set_swap_interval(egl_ctx_data_t *egl, int interval)
|
||||
|
||||
if (egl->dpy == EGL_NO_DISPLAY)
|
||||
return;
|
||||
if (!(eglGetCurrentContext()))
|
||||
if (!_egl_get_current_context())
|
||||
return;
|
||||
|
||||
RARCH_LOG("[EGL]: eglSwapInterval(%u)\n", interval);
|
||||
if (!eglSwapInterval(egl->dpy, interval))
|
||||
if (!_egl_swap_interval(egl->dpy, interval))
|
||||
{
|
||||
RARCH_ERR("[EGL]: eglSwapInterval() failed.\n");
|
||||
egl_report_error();
|
||||
@@ -204,8 +365,8 @@ void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height)
|
||||
{
|
||||
EGLint gl_width, gl_height;
|
||||
|
||||
eglQuerySurface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width);
|
||||
eglQuerySurface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height);
|
||||
_egl_query_surface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width);
|
||||
_egl_query_surface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height);
|
||||
*width = gl_width;
|
||||
*height = gl_height;
|
||||
}
|
||||
@@ -215,7 +376,7 @@ bool check_egl_version(int minMajorVersion, int minMinorVersion)
|
||||
{
|
||||
int count;
|
||||
int major, minor;
|
||||
const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
|
||||
const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_VERSION);
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
@@ -239,7 +400,7 @@ bool check_egl_version(int minMajorVersion, int minMinorVersion)
|
||||
bool check_egl_client_extension(const char *name)
|
||||
{
|
||||
size_t nameLen;
|
||||
const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
|
||||
/* The EGL implementation doesn't support client extensions at all. */
|
||||
if (!str)
|
||||
@@ -277,8 +438,9 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native)
|
||||
|
||||
RARCH_LOG("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n");
|
||||
ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay)
|
||||
eglGetProcAddress("eglGetPlatformDisplay");
|
||||
if (ptr_eglGetPlatformDisplay != NULL)
|
||||
egl_get_proc_address("eglGetPlatformDisplay");
|
||||
|
||||
if (ptr_eglGetPlatformDisplay)
|
||||
{
|
||||
EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL);
|
||||
if (dpy != EGL_NO_DISPLAY)
|
||||
@@ -294,8 +456,9 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native)
|
||||
|
||||
RARCH_LOG("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n");
|
||||
ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
if (ptr_eglGetPlatformDisplayEXT != NULL)
|
||||
egl_get_proc_address("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (ptr_eglGetPlatformDisplayEXT)
|
||||
{
|
||||
EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL);
|
||||
if (dpy != EGL_NO_DISPLAY)
|
||||
@@ -309,18 +472,30 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native)
|
||||
* implementation doesn't support eglGetPlatformDisplay. In this case, try
|
||||
* eglGetDisplay and hope for the best. */
|
||||
RARCH_LOG("[EGL] Falling back to eglGetDisplay\n");
|
||||
return eglGetDisplay((EGLNativeDisplayType) native);
|
||||
return _egl_get_display((EGLNativeDisplayType) native);
|
||||
}
|
||||
|
||||
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value)
|
||||
{
|
||||
if (!egl_get_config_attrib(egl->dpy, egl->config,
|
||||
EGL_NATIVE_VISUAL_ID, value))
|
||||
{
|
||||
RARCH_ERR("[EGL]: egl_get_native_visual_id failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_default_accept_config_cb(void *display_data, EGLDisplay dpy, EGLConfig config)
|
||||
{
|
||||
/* Makes sure we have 8 bit color. */
|
||||
EGLint r, g, b;
|
||||
if (!eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r))
|
||||
if (!egl_get_config_attrib(dpy, config, EGL_RED_SIZE, &r))
|
||||
return false;
|
||||
if (!eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g))
|
||||
if (!egl_get_config_attrib(dpy, config, EGL_GREEN_SIZE, &g))
|
||||
return false;
|
||||
if (!eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b))
|
||||
if (!egl_get_config_attrib(dpy, config, EGL_BLUE_SIZE, &b))
|
||||
return false;
|
||||
|
||||
if (r != 8 || g != 8 || b != 8)
|
||||
@@ -329,33 +504,19 @@ bool egl_default_accept_config_cb(void *display_data, EGLDisplay dpy, EGLConfig
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_init_context(egl_ctx_data_t *egl,
|
||||
EGLenum platform,
|
||||
void *display_data,
|
||||
EGLint *major, EGLint *minor,
|
||||
EGLint *count, const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb)
|
||||
bool egl_init_context_common(
|
||||
egl_ctx_data_t *egl, EGLint *count,
|
||||
const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb,
|
||||
void *display_data)
|
||||
{
|
||||
EGLint i;
|
||||
EGLConfig *configs = NULL;
|
||||
EGLint matched = 0;
|
||||
int config_index = -1;
|
||||
EGLDisplay dpy = get_egl_display(platform, display_data);
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
RARCH_ERR("[EGL]: Couldn't get EGL display.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
egl->dpy = dpy;
|
||||
|
||||
if (!eglInitialize(egl->dpy, major, minor))
|
||||
EGLConfig *configs = NULL;
|
||||
if (!egl)
|
||||
return false;
|
||||
|
||||
RARCH_LOG("[EGL]: EGL version: %d.%d\n", *major, *minor);
|
||||
|
||||
if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1)
|
||||
if (!_egl_get_configs(egl->dpy, NULL, 0, count) || *count < 1)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No configs to choose from.\n");
|
||||
return false;
|
||||
@@ -365,7 +526,7 @@ bool egl_init_context(egl_ctx_data_t *egl,
|
||||
if (!configs)
|
||||
return false;
|
||||
|
||||
if (!eglChooseConfig(egl->dpy, attrib_ptr,
|
||||
if (!_egl_choose_config(egl->dpy, attrib_ptr,
|
||||
configs, *count, &matched) || !matched)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No EGL configs with appropriate attributes.\n");
|
||||
@@ -395,9 +556,37 @@ bool egl_init_context(egl_ctx_data_t *egl,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool egl_init_context(egl_ctx_data_t *egl,
|
||||
EGLenum platform,
|
||||
void *display_data,
|
||||
EGLint *major, EGLint *minor,
|
||||
EGLint *count, const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb)
|
||||
{
|
||||
int config_index = -1;
|
||||
EGLDisplay dpy = get_egl_display(platform, display_data);
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
RARCH_ERR("[EGL]: Couldn't get EGL display.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
egl->dpy = dpy;
|
||||
|
||||
if (!egl_initialize(egl->dpy, major, minor))
|
||||
return false;
|
||||
|
||||
RARCH_LOG("[EGL]: EGL version: %d.%d\n", *major, *minor);
|
||||
|
||||
return egl_init_context_common(egl, count, attrib_ptr, cb,
|
||||
display_data);
|
||||
}
|
||||
|
||||
bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs)
|
||||
{
|
||||
EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT,
|
||||
EGLContext ctx = _egl_create_context(egl->dpy, egl->config, EGL_NO_CONTEXT,
|
||||
egl_attribs);
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
@@ -408,7 +597,7 @@ bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs)
|
||||
|
||||
if (egl->use_hw_ctx)
|
||||
{
|
||||
egl->hw_ctx = eglCreateContext(egl->dpy, egl->config, egl->ctx,
|
||||
egl->hw_ctx = _egl_create_context(egl->dpy, egl->config, egl->ctx,
|
||||
egl_attribs);
|
||||
RARCH_LOG("[EGL]: Created shared context: %p.\n", (void*)egl->hw_ctx);
|
||||
|
||||
@@ -426,28 +615,16 @@ bool egl_create_surface(egl_ctx_data_t *egl, void *native_window)
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs);
|
||||
egl->surf = _egl_create_window_surface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs);
|
||||
|
||||
if (egl->surf == EGL_NO_SURFACE)
|
||||
return false;
|
||||
|
||||
/* Connect the context to the surface. */
|
||||
if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx))
|
||||
if (!_egl_make_current(egl->dpy, egl->surf, egl->surf, egl->ctx))
|
||||
return false;
|
||||
|
||||
RARCH_LOG("[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value)
|
||||
{
|
||||
if (!eglGetConfigAttrib(egl->dpy, egl->config,
|
||||
EGL_NATIVE_VISUAL_ID, value))
|
||||
{
|
||||
RARCH_ERR("[EGL]: egl_get_native_visual_id failed.\n");
|
||||
return false;
|
||||
}
|
||||
RARCH_LOG("[EGL]: Current context: %p.\n", (void*)_egl_get_current_context());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,8 @@ void egl_destroy(egl_ctx_data_t *egl);
|
||||
|
||||
gfx_ctx_proc_t egl_get_proc_address(const char *symbol);
|
||||
|
||||
void egl_terminate(EGLDisplay dpy);
|
||||
|
||||
void egl_bind_hw_render(egl_ctx_data_t *egl, bool enable);
|
||||
|
||||
void egl_swap_buffers(void *data);
|
||||
@@ -91,6 +93,16 @@ void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height);
|
||||
typedef bool (*egl_accept_config_cb_t)(void *display_data, EGLDisplay dpy, EGLConfig config);
|
||||
bool egl_default_accept_config_cb(void *display_data, EGLDisplay dpy, EGLConfig config);
|
||||
|
||||
bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
|
||||
bool egl_init_dll(void);
|
||||
|
||||
bool egl_init_context_common(
|
||||
egl_ctx_data_t *egl, EGLint *count,
|
||||
const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb,
|
||||
void *display_data);
|
||||
|
||||
bool egl_init_context(egl_ctx_data_t *egl,
|
||||
EGLenum platform,
|
||||
void *display_data,
|
||||
@@ -100,12 +112,17 @@ bool egl_init_context(egl_ctx_data_t *egl,
|
||||
const EGLint *attrib_ptr,
|
||||
egl_accept_config_cb_t cb);
|
||||
|
||||
bool egl_bind_api(EGLenum egl_api);
|
||||
|
||||
bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs);
|
||||
|
||||
bool egl_create_surface(egl_ctx_data_t *egl, void *native_window);
|
||||
|
||||
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value);
|
||||
|
||||
bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
bool egl_has_config(egl_ctx_data_t *egl);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
@@ -321,7 +321,7 @@
|
||||
if (osd_params)
|
||||
{
|
||||
[rce pushDebugGroup:@"video stats"];
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text, osd_params);
|
||||
font_driver_render_msg(data, video_info, video_info->stat_text, osd_params, NULL);
|
||||
[rce popDebugGroup];
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,7 @@
|
||||
[_context drawQuadX:x y:y w:width h:height r:r g:g b:b a:a];
|
||||
}
|
||||
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(NULL, video_info, msg, NULL, NULL);
|
||||
}
|
||||
|
||||
- (void)_beginFrame
|
||||
|
||||
+73
-102
@@ -138,7 +138,8 @@ void vulkan_emulated_mailbox_deinit(struct vulkan_emulated_mailbox *mailbox)
|
||||
memset(mailbox, 0, sizeof(*mailbox));
|
||||
}
|
||||
|
||||
VkResult vulkan_emulated_mailbox_acquire_next_image(struct vulkan_emulated_mailbox *mailbox,
|
||||
VkResult vulkan_emulated_mailbox_acquire_next_image(
|
||||
struct vulkan_emulated_mailbox *mailbox,
|
||||
unsigned *index)
|
||||
{
|
||||
VkResult res;
|
||||
@@ -250,21 +251,22 @@ static void vulkan_emulated_mailbox_loop(void *userdata)
|
||||
vkDestroyFence(mailbox->device, fence, NULL);
|
||||
}
|
||||
|
||||
bool vulkan_emulated_mailbox_init(struct vulkan_emulated_mailbox *mailbox,
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain)
|
||||
bool vulkan_emulated_mailbox_init(
|
||||
struct vulkan_emulated_mailbox *mailbox,
|
||||
VkDevice device,
|
||||
VkSwapchainKHR swapchain)
|
||||
{
|
||||
memset(mailbox, 0, sizeof(*mailbox));
|
||||
mailbox->device = device;
|
||||
mailbox->device = device;
|
||||
mailbox->swapchain = swapchain;
|
||||
|
||||
mailbox->cond = scond_new();
|
||||
mailbox->cond = scond_new();
|
||||
if (!mailbox->cond)
|
||||
return false;
|
||||
mailbox->lock = slock_new();
|
||||
mailbox->lock = slock_new();
|
||||
if (!mailbox->lock)
|
||||
return false;
|
||||
mailbox->thread = sthread_create(vulkan_emulated_mailbox_loop, mailbox);
|
||||
mailbox->thread = sthread_create(vulkan_emulated_mailbox_loop, mailbox);
|
||||
if (!mailbox->thread)
|
||||
return false;
|
||||
return true;
|
||||
@@ -334,14 +336,6 @@ void vulkan_transfer_image_ownership(VkCommandBuffer cmd,
|
||||
false, 0, NULL, 0, NULL, 1, &barrier);
|
||||
}
|
||||
|
||||
void vulkan_map_persistent_texture(
|
||||
VkDevice device,
|
||||
struct vk_texture *texture)
|
||||
{
|
||||
vkMapMemory(device, texture->memory, texture->offset,
|
||||
texture->size, 0, &texture->mapped);
|
||||
}
|
||||
|
||||
void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd,
|
||||
struct vk_texture *dynamic,
|
||||
struct vk_texture *staging)
|
||||
@@ -453,7 +447,7 @@ void vulkan_sync_texture_to_cpu(vk_t *vk, const struct vk_texture *tex)
|
||||
|
||||
range.memory = tex->memory;
|
||||
range.offset = 0;
|
||||
range.size = VK_WHOLE_SIZE;
|
||||
range.size = VK_WHOLE_SIZE;
|
||||
vkInvalidateMappedMemoryRanges(vk->context->device, 1, &range);
|
||||
}
|
||||
|
||||
@@ -977,32 +971,25 @@ void vulkan_transition_texture(vk_t *vk, VkCommandBuffer cmd, struct vk_texture
|
||||
texture->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
static void vulkan_check_dynamic_state(
|
||||
vk_t *vk)
|
||||
static void vulkan_check_dynamic_state(vk_t *vk)
|
||||
{
|
||||
VkRect2D sci;
|
||||
|
||||
if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||
if (vk->tracker.use_scissor)
|
||||
sci = vk->tracker.scissor;
|
||||
else
|
||||
{
|
||||
VkRect2D sci;
|
||||
|
||||
if (vk->tracker.use_scissor)
|
||||
{
|
||||
sci = vk->tracker.scissor;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
||||
@@ -1020,7 +1007,8 @@ void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
vulkan_check_dynamic_state(vk);
|
||||
if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||
vulkan_check_dynamic_state(vk);
|
||||
|
||||
/* Upload descriptors */
|
||||
{
|
||||
@@ -1078,7 +1066,8 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
vulkan_check_dynamic_state(vk);
|
||||
if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||
vulkan_check_dynamic_state(vk);
|
||||
|
||||
/* Upload descriptors */
|
||||
{
|
||||
@@ -1306,12 +1295,6 @@ VkDescriptorSet vulkan_descriptor_manager_alloc(
|
||||
return manager->current->sets[manager->count++];
|
||||
}
|
||||
|
||||
void vulkan_descriptor_manager_restart(struct vk_descriptor_manager *manager)
|
||||
{
|
||||
manager->current = manager->head;
|
||||
manager->count = 0;
|
||||
}
|
||||
|
||||
struct vk_descriptor_manager vulkan_create_descriptor_manager(
|
||||
VkDevice device,
|
||||
const VkDescriptorPoolSize *sizes,
|
||||
@@ -1406,12 +1389,6 @@ struct vk_buffer_chain vulkan_buffer_chain_init(
|
||||
return chain;
|
||||
}
|
||||
|
||||
void vulkan_buffer_chain_discard(struct vk_buffer_chain *chain)
|
||||
{
|
||||
chain->current = chain->head;
|
||||
chain->offset = 0;
|
||||
}
|
||||
|
||||
bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
|
||||
struct vk_buffer_chain *chain,
|
||||
size_t size, struct vk_buffer_range *range)
|
||||
@@ -2128,7 +2105,7 @@ static bool vulkan_update_display_mode(
|
||||
const VkDisplayModePropertiesKHR *mode,
|
||||
const struct vulkan_display_surface_info *info)
|
||||
{
|
||||
unsigned visible_width = mode->parameters.visibleRegion.width;
|
||||
unsigned visible_width = mode->parameters.visibleRegion.width;
|
||||
unsigned visible_height = mode->parameters.visibleRegion.height;
|
||||
|
||||
if (!info->width || !info->height)
|
||||
@@ -2137,54 +2114,53 @@ static bool vulkan_update_display_mode(
|
||||
unsigned area = visible_width * visible_height;
|
||||
if (area > (*width) * (*height))
|
||||
{
|
||||
*width = visible_width;
|
||||
*height = visible_height;
|
||||
*width = visible_width;
|
||||
*height = visible_height;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For particular resolutions, find the closest. */
|
||||
int delta_x = (int)info->width - (int)visible_width;
|
||||
int delta_y = (int)info->height - (int)visible_height;
|
||||
int delta_x = (int)info->width - (int)visible_width;
|
||||
int delta_y = (int)info->height - (int)visible_height;
|
||||
int old_delta_x = (int)info->width - (int)*width;
|
||||
int old_delta_y = (int)info->height - (int)*height;
|
||||
|
||||
int dist = delta_x * delta_x + delta_y * delta_y;
|
||||
int old_dist = old_delta_x * old_delta_x + old_delta_y * old_delta_y;
|
||||
int dist = delta_x * delta_x + delta_y * delta_y;
|
||||
int old_dist = old_delta_x * old_delta_x + old_delta_y * old_delta_y;
|
||||
|
||||
if (dist < old_dist)
|
||||
{
|
||||
*width = visible_width;
|
||||
*height = visible_height;
|
||||
*width = visible_width;
|
||||
*height = visible_height;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool vulkan_create_display_surface(gfx_ctx_vulkan_data_t *vk,
|
||||
unsigned *width, unsigned *height,
|
||||
const struct vulkan_display_surface_info *info)
|
||||
{
|
||||
bool ret = true;
|
||||
uint32_t display_count = 0;
|
||||
uint32_t plane_count = 0;
|
||||
VkDisplayPropertiesKHR *displays = NULL;
|
||||
VkDisplayPlanePropertiesKHR *planes = NULL;
|
||||
uint32_t mode_count = 0;
|
||||
VkDisplayModePropertiesKHR *modes = NULL;
|
||||
bool ret = true;
|
||||
uint32_t display_count = 0;
|
||||
uint32_t plane_count = 0;
|
||||
VkDisplayPropertiesKHR *displays = NULL;
|
||||
VkDisplayPlanePropertiesKHR *planes = NULL;
|
||||
uint32_t mode_count = 0;
|
||||
VkDisplayModePropertiesKHR *modes = NULL;
|
||||
unsigned dpy, i, j;
|
||||
uint32_t best_plane = UINT32_MAX;
|
||||
uint32_t best_plane = UINT32_MAX;
|
||||
VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
|
||||
VkDisplaySurfaceCreateInfoKHR create_info = { VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR };
|
||||
VkDisplayModeKHR best_mode = VK_NULL_HANDLE;
|
||||
VkDisplayModeKHR best_mode = VK_NULL_HANDLE;
|
||||
/* Monitor index starts on 1, 0 is auto. */
|
||||
unsigned monitor_index = info->monitor_index;
|
||||
unsigned saved_width = *width;
|
||||
unsigned saved_height = *height;
|
||||
unsigned monitor_index = info->monitor_index;
|
||||
unsigned saved_width = *width;
|
||||
unsigned saved_height = *height;
|
||||
|
||||
/* We need to decide on GPU here to be able to query support. */
|
||||
if (!vulkan_context_init_gpu(vk))
|
||||
@@ -2728,7 +2704,7 @@ static void vulkan_acquire_wait_fences(gfx_ctx_vulkan_data_t *vk)
|
||||
VkFenceCreateInfo fence_info =
|
||||
{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
||||
|
||||
unsigned index = vk->context.current_swapchain_index;
|
||||
unsigned index = vk->context.current_swapchain_index;
|
||||
VkFence *next_fence = &vk->context.swapchain_fences[index];
|
||||
|
||||
if (*next_fence != VK_NULL_HANDLE)
|
||||
@@ -2751,10 +2727,8 @@ static void vulkan_create_wait_fences(gfx_ctx_vulkan_data_t *vk)
|
||||
for (i = 0; i < vk->context.num_swapchain_images; i++)
|
||||
{
|
||||
if (!vk->context.swapchain_fences[i])
|
||||
{
|
||||
vkCreateFence(vk->context.device, &fence_info, NULL,
|
||||
&vk->context.swapchain_fences[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2763,12 +2737,11 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk)
|
||||
unsigned index;
|
||||
VkResult err;
|
||||
VkFence fence;
|
||||
VkFenceCreateInfo fence_info =
|
||||
VkFenceCreateInfo fence_info =
|
||||
{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
||||
VkSemaphoreCreateInfo sem_info =
|
||||
{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||
|
||||
bool is_retrying = false;
|
||||
bool is_retrying = false;
|
||||
|
||||
retry:
|
||||
if (vk->swapchain == VK_NULL_HANDLE)
|
||||
@@ -2799,7 +2772,8 @@ retry:
|
||||
/* Non-blocking acquire. If we don't get a swapchain frame right away,
|
||||
* just skip rendering to the swapchain this frame, similar to what
|
||||
* MAILBOX would do. */
|
||||
err = vulkan_emulated_mailbox_acquire_next_image(&vk->mailbox, &vk->context.current_swapchain_index);
|
||||
err = vulkan_emulated_mailbox_acquire_next_image(
|
||||
&vk->mailbox, &vk->context.current_swapchain_index);
|
||||
fence = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
@@ -2809,8 +2783,10 @@ retry:
|
||||
vk->swapchain, UINT64_MAX,
|
||||
VK_NULL_HANDLE, fence, &vk->context.current_swapchain_index);
|
||||
|
||||
/* VK_SUBOPTIMAL_KHR can be returned on Android 10 when prerotate is not dealt with.
|
||||
* This is not an error we need to care about, and we'll treat it as SUCCESS. */
|
||||
/* VK_SUBOPTIMAL_KHR can be returned on Android 10
|
||||
* when prerotate is not dealt with.
|
||||
* This is not an error we need to care about, and
|
||||
* we'll treat it as SUCCESS. */
|
||||
if (err == VK_SUBOPTIMAL_KHR)
|
||||
err = VK_SUCCESS;
|
||||
}
|
||||
@@ -2903,13 +2879,14 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
|
||||
if (swap_interval == 0 && vk->emulate_mailbox)
|
||||
{
|
||||
swap_interval = 1;
|
||||
vk->emulating_mailbox = true;
|
||||
swap_interval = 1;
|
||||
vk->emulating_mailbox = true;
|
||||
}
|
||||
else
|
||||
vk->emulating_mailbox = false;
|
||||
vk->emulating_mailbox = false;
|
||||
|
||||
vk->created_new_swapchain = true;
|
||||
|
||||
if (vk->swapchain != VK_NULL_HANDLE &&
|
||||
!vk->context.invalid_swapchain &&
|
||||
vk->context.swapchain_width == width &&
|
||||
@@ -2931,11 +2908,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
/* We are tearing down, and entering a state where we are supposed to have
|
||||
* acquired an image, so block until we have acquired. */
|
||||
if (!vk->context.has_acquired_swapchain)
|
||||
{
|
||||
res = vulkan_emulated_mailbox_acquire_next_image_blocking(
|
||||
&vk->mailbox,
|
||||
&vk->context.current_swapchain_index);
|
||||
}
|
||||
else
|
||||
res = VK_SUCCESS;
|
||||
|
||||
@@ -2944,14 +2919,12 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
if (res == VK_SUCCESS)
|
||||
{
|
||||
vk->context.has_acquired_swapchain = true;
|
||||
vk->created_new_swapchain = false;
|
||||
vk->created_new_swapchain = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
vk->context.has_acquired_swapchain = false;
|
||||
/* We failed for some reason, so create a new swapchain. */
|
||||
}
|
||||
|
||||
/* We failed for some reason, so create a new swapchain. */
|
||||
vk->context.has_acquired_swapchain = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3033,9 +3006,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
|
||||
formats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
|
||||
formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32)
|
||||
{
|
||||
format = formats[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (format.format == VK_FORMAT_UNDEFINED)
|
||||
@@ -3075,7 +3046,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
/* Cannot create swapchain yet, try again later. */
|
||||
if (vk->swapchain != VK_NULL_HANDLE)
|
||||
vkDestroySwapchainKHR(vk->context.device, vk->swapchain, NULL);
|
||||
vk->swapchain = VK_NULL_HANDLE;
|
||||
vk->swapchain = VK_NULL_HANDLE;
|
||||
vk->context.swapchain_width = width;
|
||||
vk->context.swapchain_height = height;
|
||||
vk->context.num_swapchain_images = 1;
|
||||
@@ -3195,7 +3166,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
vk->context.num_swapchain_images);
|
||||
|
||||
/* Force driver to reset swapchain image handles. */
|
||||
vk->context.invalid_swapchain = true;
|
||||
vk->context.invalid_swapchain = true;
|
||||
vk->context.has_acquired_swapchain = false;
|
||||
vulkan_create_wait_fences(vk);
|
||||
|
||||
|
||||
@@ -250,7 +250,11 @@ struct vk_buffer_chain vulkan_buffer_chain_init(
|
||||
VkDeviceSize alignment,
|
||||
VkBufferUsageFlags usage);
|
||||
|
||||
void vulkan_buffer_chain_discard(struct vk_buffer_chain *chain);
|
||||
#define VK_BUFFER_CHAIN_DISCARD(chain) \
|
||||
{ \
|
||||
chain->current = chain->head; \
|
||||
chain->offset = 0; \
|
||||
}
|
||||
|
||||
bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
|
||||
struct vk_buffer_chain *chain, size_t size,
|
||||
@@ -462,10 +466,6 @@ void vulkan_transfer_image_ownership(VkCommandBuffer cmd,
|
||||
uint32_t src_queue_family,
|
||||
uint32_t dst_queue_family);
|
||||
|
||||
void vulkan_map_persistent_texture(
|
||||
VkDevice device,
|
||||
struct vk_texture *texture);
|
||||
|
||||
void vulkan_destroy_texture(
|
||||
VkDevice device,
|
||||
struct vk_texture *tex);
|
||||
@@ -552,8 +552,16 @@ VkDescriptorSet vulkan_descriptor_manager_alloc(
|
||||
VkDevice device,
|
||||
struct vk_descriptor_manager *manager);
|
||||
|
||||
void vulkan_descriptor_manager_restart(
|
||||
struct vk_descriptor_manager *manager);
|
||||
#define VK_DESCRIPTOR_MANAGER_RESTART(manager) \
|
||||
{ \
|
||||
manager->current = manager->head; \
|
||||
manager->count = 0; \
|
||||
}
|
||||
|
||||
#define VK_MAP_PERSISTENT_TEXTURE(device, texture) \
|
||||
{ \
|
||||
vkMapMemory(device, texture->memory, texture->offset, texture->size, 0, &texture->mapped); \
|
||||
}
|
||||
|
||||
struct vk_descriptor_manager vulkan_create_descriptor_manager(
|
||||
VkDevice device,
|
||||
|
||||
@@ -1087,7 +1087,7 @@ static bool win32_monitor_set_fullscreen(
|
||||
#endif
|
||||
}
|
||||
|
||||
void win32_show_cursor(bool state)
|
||||
void win32_show_cursor(void *data, bool state)
|
||||
{
|
||||
#if !defined(_XBOX)
|
||||
if (state)
|
||||
@@ -1291,7 +1291,7 @@ void win32_set_window(unsigned *width, unsigned *height,
|
||||
window->set_focused(&main_window);
|
||||
}
|
||||
|
||||
win32_show_cursor(!fullscreen);
|
||||
win32_show_cursor(NULL, !fullscreen);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1373,7 +1373,7 @@ BOOL IsIconic(HWND hwnd)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool win32_has_focus(void)
|
||||
bool win32_has_focus(void *data)
|
||||
{
|
||||
if (g_win32_inited)
|
||||
if (GetForegroundWindow() == main_window.hwnd)
|
||||
|
||||
@@ -92,11 +92,11 @@ bool win32_suppress_screensaver(void *data, bool enable);
|
||||
bool win32_get_metrics(void *data,
|
||||
enum display_metric_types type, float *value);
|
||||
|
||||
void win32_show_cursor(bool state);
|
||||
void win32_show_cursor(void *data, bool state);
|
||||
|
||||
HWND win32_get_window(void);
|
||||
|
||||
bool win32_has_focus(void);
|
||||
bool win32_has_focus(void *data);
|
||||
|
||||
void win32_check_window(bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* 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-
|
||||
* 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 <stddef.h>
|
||||
#include "../video_display_server.h"
|
||||
|
||||
static void* null_display_server_init(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void null_display_server_destroy(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static bool null_display_server_set_window_opacity(void *data, unsigned opacity)
|
||||
{
|
||||
(void)data;
|
||||
(void)opacity;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_display_server_set_window_progress(void *data, int progress, bool finished)
|
||||
{
|
||||
(void)data;
|
||||
(void)progress;
|
||||
(void)finished;
|
||||
return true;
|
||||
}
|
||||
|
||||
const video_display_server_t dispserv_null = {
|
||||
null_display_server_init,
|
||||
null_display_server_destroy,
|
||||
null_display_server_set_window_opacity,
|
||||
null_display_server_set_window_progress,
|
||||
NULL, /* set_window_decorations */
|
||||
NULL, /* set_resolution */
|
||||
NULL, /* get_resolution_list */
|
||||
NULL, /* get_output_options */
|
||||
NULL, /* set_screen_orientation */
|
||||
NULL, /* get_screen_orientation */
|
||||
NULL, /* get_flags */
|
||||
"null"
|
||||
};
|
||||
+2
-10
@@ -160,7 +160,7 @@ static bool caca_gfx_frame(void *data, const void *frame,
|
||||
#endif
|
||||
|
||||
if (msg)
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(data, video_info, msg, NULL, NULL);
|
||||
|
||||
if (draw)
|
||||
{
|
||||
@@ -281,14 +281,6 @@ static void caca_set_texture_frame(void *data,
|
||||
memcpy(caca_menu_frame, frame, pitch * height);
|
||||
}
|
||||
|
||||
static void caca_set_osd_msg(void *data,
|
||||
video_frame_info_t *video_info,
|
||||
const char *msg,
|
||||
const void *params, void *font)
|
||||
{
|
||||
font_driver_render_msg(video_info, font, msg, (const struct font_params*)params);
|
||||
}
|
||||
|
||||
static const video_poke_interface_t caca_poke_interface = {
|
||||
NULL, /* get_flags */
|
||||
NULL,
|
||||
@@ -305,7 +297,7 @@ static const video_poke_interface_t caca_poke_interface = {
|
||||
NULL,
|
||||
caca_set_texture_frame,
|
||||
NULL,
|
||||
caca_set_osd_msg,
|
||||
font_driver_render_msg,
|
||||
NULL, /* show_mouse */
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
|
||||
@@ -861,18 +861,14 @@ static bool ctr_frame(void* data, const void* frame,
|
||||
|
||||
if (osd_params)
|
||||
{
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
font_driver_render_msg(ctr, video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (msg)
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
|
||||
#if 0
|
||||
font_driver_render_msg(video_info, NULL, "TEST: 123 ABC àüî", NULL);
|
||||
#endif
|
||||
font_driver_render_msg(ctr, video_info, msg, NULL, NULL);
|
||||
|
||||
GPU_FinishDrawing();
|
||||
GPU_Finalize();
|
||||
@@ -1192,7 +1188,7 @@ static void ctr_set_osd_msg(void *data,
|
||||
ctr_video_t* ctr = (ctr_video_t*)data;
|
||||
|
||||
if (ctr && ctr->msg_rendering_enabled)
|
||||
font_driver_render_msg(video_info, font, msg, params);
|
||||
font_driver_render_msg(data, video_info, msg, params, font);
|
||||
}
|
||||
|
||||
static uint32_t ctr_get_flags(void *data)
|
||||
|
||||
+9
-12
@@ -212,7 +212,7 @@ static void d3d10_overlay_enable(void* data, bool state)
|
||||
return;
|
||||
|
||||
d3d10->overlays.enabled = state;
|
||||
win32_show_cursor(state);
|
||||
win32_show_cursor(d3d10, state);
|
||||
}
|
||||
|
||||
static void d3d10_overlay_full_screen(void* data, bool enable)
|
||||
@@ -970,6 +970,7 @@ static void *d3d10_gfx_init(const video_info_t* video,
|
||||
|
||||
{
|
||||
d3d10_fake_context.get_flags = d3d10_get_flags;
|
||||
d3d10_fake_context.get_metrics = win32_get_metrics;
|
||||
video_context_driver_set(&d3d10_fake_context);
|
||||
#ifdef HAVE_SLANG
|
||||
const char *shader_preset = retroarch_get_shader_preset();
|
||||
@@ -1472,9 +1473,9 @@ static bool d3d10_gfx_frame(
|
||||
D3D10SetViewports(context, 1, &d3d10->viewport);
|
||||
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
D3D10SetVertexBuffer(context, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0);
|
||||
font_driver_render_msg(
|
||||
video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
font_driver_render_msg(d3d10,
|
||||
video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1511,7 +1512,7 @@ static bool d3d10_gfx_frame(
|
||||
D3D10SetViewports(d3d10->device, 1, &d3d10->viewport);
|
||||
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
D3D10SetVertexBuffer(d3d10->device, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0);
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(d3d10, video_info, msg, NULL, NULL);
|
||||
dxgi_update_title(video_info);
|
||||
}
|
||||
d3d10->sprites.enabled = false;
|
||||
@@ -1545,8 +1546,6 @@ static bool d3d10_gfx_alive(void* data)
|
||||
return !quit;
|
||||
}
|
||||
|
||||
static bool d3d10_gfx_focus(void* data) { return win32_has_focus(); }
|
||||
|
||||
static bool d3d10_gfx_suppress_screensaver(void* data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
@@ -1640,14 +1639,12 @@ static void d3d10_gfx_set_osd_msg(
|
||||
if (d3d10)
|
||||
{
|
||||
if (d3d10->sprites.enabled)
|
||||
font_driver_render_msg(video_info, font, msg, (const struct font_params*)params);
|
||||
font_driver_render_msg(d3d10, video_info, msg, (const struct font_params*)params, font);
|
||||
else
|
||||
printf("OSD msg: %s\n", msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d10_gfx_show_mouse(void* data, bool state) { win32_show_cursor(state); }
|
||||
|
||||
static uintptr_t d3d10_gfx_load_texture(
|
||||
void* video_data, void* data, bool threaded, enum texture_filter_type filter_type)
|
||||
{
|
||||
@@ -1749,7 +1746,7 @@ static const video_poke_interface_t d3d10_poke_interface = {
|
||||
d3d10_set_menu_texture_frame,
|
||||
d3d10_set_menu_texture_enable,
|
||||
d3d10_gfx_set_osd_msg,
|
||||
d3d10_gfx_show_mouse,
|
||||
win32_show_cursor,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
d3d10_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
@@ -1778,7 +1775,7 @@ video_driver_t video_d3d10 = {
|
||||
d3d10_gfx_frame,
|
||||
d3d10_gfx_set_nonblock_state,
|
||||
d3d10_gfx_alive,
|
||||
d3d10_gfx_focus,
|
||||
win32_has_focus,
|
||||
d3d10_gfx_suppress_screensaver,
|
||||
d3d10_gfx_has_windowed,
|
||||
d3d10_gfx_set_shader,
|
||||
|
||||
+21
-14
@@ -230,7 +230,7 @@ static void d3d11_overlay_enable(void* data, bool state)
|
||||
return;
|
||||
|
||||
d3d11->overlays.enabled = state;
|
||||
win32_show_cursor(state);
|
||||
win32_show_cursor(d3d11, state);
|
||||
}
|
||||
|
||||
static void d3d11_overlay_full_screen(void* data, bool enable)
|
||||
@@ -674,8 +674,7 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
{
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
#ifdef __WINRT__
|
||||
/* UWP requires the use of newer version of the factory which requires newer version of this struct */
|
||||
@@ -1046,6 +1045,7 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
|
||||
{
|
||||
d3d11_fake_context.get_flags = d3d11_get_flags;
|
||||
d3d11_fake_context.get_metrics = win32_get_metrics;
|
||||
video_context_driver_set(&d3d11_fake_context);
|
||||
const char *shader_preset = retroarch_get_shader_preset();
|
||||
enum rarch_shader_type type = video_shader_parse_type(shader_preset);
|
||||
@@ -1131,6 +1131,17 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
|
||||
error:
|
||||
d3d11_gfx_free(d3d11);
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
retroarch_force_video_driver_fallback("gl");
|
||||
#elif !defined(__WINRT__)
|
||||
#ifdef HAVE_OPENGL1
|
||||
retroarch_force_video_driver_fallback("gl1");
|
||||
#else
|
||||
retroarch_force_video_driver_fallback("gdi");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1538,9 +1549,9 @@ static bool d3d11_gfx_frame(
|
||||
D3D11SetViewports(context, 1, &d3d11->viewport);
|
||||
D3D11SetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
D3D11SetVertexBuffer(context, 0, d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0);
|
||||
font_driver_render_msg(
|
||||
video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
font_driver_render_msg(d3d11,
|
||||
video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1577,7 +1588,7 @@ static bool d3d11_gfx_frame(
|
||||
D3D11SetViewports(context, 1, &d3d11->viewport);
|
||||
D3D11SetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
D3D11SetVertexBuffer(context, 0, d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0);
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(d3d11, video_info, msg, NULL, NULL);
|
||||
dxgi_update_title(video_info);
|
||||
}
|
||||
d3d11->sprites.enabled = false;
|
||||
@@ -1613,8 +1624,6 @@ static bool d3d11_gfx_alive(void* data)
|
||||
return !quit;
|
||||
}
|
||||
|
||||
static bool d3d11_gfx_focus(void* data) { return win32_has_focus(); }
|
||||
|
||||
static bool d3d11_gfx_suppress_screensaver(void* data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
@@ -1709,14 +1718,12 @@ static void d3d11_gfx_set_osd_msg(
|
||||
if (d3d11)
|
||||
{
|
||||
if (d3d11->sprites.enabled)
|
||||
font_driver_render_msg(video_info, font, msg, (const struct font_params*)params);
|
||||
font_driver_render_msg(d3d11, video_info, msg, (const struct font_params*)params, font);
|
||||
else
|
||||
printf("OSD msg: %s\n", msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d11_gfx_show_mouse(void* data, bool state) { win32_show_cursor(state); }
|
||||
|
||||
static uintptr_t d3d11_gfx_load_texture(
|
||||
void* video_data, void* data, bool threaded, enum texture_filter_type filter_type)
|
||||
{
|
||||
@@ -1815,7 +1822,7 @@ static const video_poke_interface_t d3d11_poke_interface = {
|
||||
d3d11_set_menu_texture_frame,
|
||||
d3d11_set_menu_texture_enable,
|
||||
d3d11_gfx_set_osd_msg,
|
||||
d3d11_gfx_show_mouse,
|
||||
win32_show_cursor,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
d3d11_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
@@ -1840,7 +1847,7 @@ video_driver_t video_d3d11 = {
|
||||
d3d11_gfx_frame,
|
||||
d3d11_gfx_set_nonblock_state,
|
||||
d3d11_gfx_alive,
|
||||
d3d11_gfx_focus,
|
||||
win32_has_focus,
|
||||
d3d11_gfx_suppress_screensaver,
|
||||
d3d11_gfx_has_windowed,
|
||||
d3d11_gfx_set_shader,
|
||||
|
||||
+9
-15
@@ -200,7 +200,7 @@ static void d3d12_overlay_enable(void* data, bool state)
|
||||
return;
|
||||
|
||||
d3d12->overlays.enabled = state;
|
||||
win32_show_cursor(state);
|
||||
win32_show_cursor(d3d12, state);
|
||||
}
|
||||
|
||||
static void d3d12_overlay_full_screen(void* data, bool enable)
|
||||
@@ -1009,6 +1009,7 @@ static void *d3d12_gfx_init(const video_info_t* video,
|
||||
|
||||
{
|
||||
d3d12_fake_context.get_flags = d3d12_get_flags;
|
||||
d3d12_fake_context.get_metrics = win32_get_metrics;
|
||||
video_context_driver_set(&d3d12_fake_context);
|
||||
const char *shader_preset = retroarch_get_shader_preset();
|
||||
enum rarch_shader_type type = video_shader_parse_type(shader_preset);
|
||||
@@ -1516,8 +1517,8 @@ static bool d3d12_gfx_frame(
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
font_driver_render_msg(d3d12, video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_OVERLAY
|
||||
@@ -1570,7 +1571,7 @@ static bool d3d12_gfx_frame(
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(d3d12, video_info, msg, NULL, NULL);
|
||||
dxgi_update_title(video_info);
|
||||
}
|
||||
d3d12->sprites.enabled = false;
|
||||
@@ -1613,8 +1614,6 @@ static bool d3d12_gfx_alive(void* data)
|
||||
return !quit;
|
||||
}
|
||||
|
||||
static bool d3d12_gfx_focus(void* data) { return win32_has_focus(); }
|
||||
|
||||
static bool d3d12_gfx_suppress_screensaver(void* data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
@@ -1701,11 +1700,6 @@ static void d3d12_set_menu_texture_enable(void* data,
|
||||
d3d12->menu.fullscreen = full_screen;
|
||||
}
|
||||
|
||||
static void d3d12_gfx_show_mouse(void* data, bool state)
|
||||
{
|
||||
win32_show_cursor(state);
|
||||
}
|
||||
|
||||
static void d3d12_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
@@ -1734,8 +1728,8 @@ static void d3d12_gfx_set_osd_msg(
|
||||
if (!d3d12 || !d3d12->sprites.enabled)
|
||||
return;
|
||||
|
||||
font_driver_render_msg(video_info, font, msg,
|
||||
(const struct font_params*)params);
|
||||
font_driver_render_msg(d3d12, video_info, msg,
|
||||
(const struct font_params*)params, font);
|
||||
}
|
||||
|
||||
static uintptr_t d3d12_gfx_load_texture(
|
||||
@@ -1829,7 +1823,7 @@ static const video_poke_interface_t d3d12_poke_interface = {
|
||||
d3d12_set_menu_texture_frame,
|
||||
d3d12_set_menu_texture_enable,
|
||||
d3d12_gfx_set_osd_msg,
|
||||
d3d12_gfx_show_mouse,
|
||||
win32_show_cursor,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
d3d12_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
@@ -1854,7 +1848,7 @@ video_driver_t video_d3d12 = {
|
||||
d3d12_gfx_frame,
|
||||
d3d12_gfx_set_nonblock_state,
|
||||
d3d12_gfx_alive,
|
||||
d3d12_gfx_focus,
|
||||
win32_has_focus,
|
||||
d3d12_gfx_suppress_screensaver,
|
||||
d3d12_gfx_has_windowed,
|
||||
d3d12_gfx_set_shader,
|
||||
|
||||
+9
-16
@@ -1100,7 +1100,7 @@ static void d3d8_set_osd_msg(void *data,
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
|
||||
d3d8_begin_scene(d3d->dev);
|
||||
font_driver_render_msg(video_info, font, msg, params);
|
||||
font_driver_render_msg(d3d, video_info, msg, params, font);
|
||||
d3d8_end_scene(d3d->dev);
|
||||
}
|
||||
|
||||
@@ -1208,13 +1208,6 @@ static void d3d8_set_rotation(void *data, unsigned rot)
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
static void d3d8_show_mouse(void *data, bool state)
|
||||
{
|
||||
#ifndef _XBOX
|
||||
win32_show_cursor(state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *d3d8_init(const video_info_t *info,
|
||||
input_driver_t **input, void **input_data)
|
||||
{
|
||||
@@ -1422,7 +1415,9 @@ static void d3d8_overlay_enable(void *data, bool state)
|
||||
for (i = 0; i < d3d->overlays_size; i++)
|
||||
d3d->overlays_enabled = state;
|
||||
|
||||
d3d8_show_mouse(d3d, state);
|
||||
#ifndef _XBOX
|
||||
win32_show_cursor(d3d, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void d3d8_overlay_full_screen(void *data, bool enable)
|
||||
@@ -1561,10 +1556,8 @@ static bool d3d8_frame(void *data, const void *frame,
|
||||
&video_info->osd_stat_params;
|
||||
|
||||
if (osd_params)
|
||||
{
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
}
|
||||
font_driver_render_msg(d3d, video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1581,7 +1574,7 @@ static bool d3d8_frame(void *data, const void *frame,
|
||||
{
|
||||
d3d8_set_viewports(d3d->dev, &screen_vp);
|
||||
d3d8_begin_scene(d3d->dev);
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(d3d, video_info, msg, NULL, NULL);
|
||||
d3d8_end_scene(d3d->dev);
|
||||
}
|
||||
|
||||
@@ -1781,7 +1774,7 @@ static void d3d8_set_video_mode(void *data,
|
||||
bool fullscreen)
|
||||
{
|
||||
#ifndef _XBOX
|
||||
win32_show_cursor(!fullscreen);
|
||||
win32_show_cursor(data, !fullscreen);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1818,7 +1811,7 @@ static const video_poke_interface_t d3d_poke_interface = {
|
||||
d3d8_set_menu_texture_enable,
|
||||
d3d8_set_osd_msg,
|
||||
|
||||
d3d8_show_mouse,
|
||||
win32_show_cursor,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
|
||||
+13
-15
@@ -1121,8 +1121,8 @@ static void d3d9_set_osd_msg(void *data,
|
||||
|
||||
d3d9_set_font_rect(d3d, d3d_font_params);
|
||||
d3d9_begin_scene(dev);
|
||||
font_driver_render_msg(video_info, font,
|
||||
msg, d3d_font_params);
|
||||
font_driver_render_msg(d3d, video_info,
|
||||
msg, d3d_font_params, font);
|
||||
d3d9_end_scene(dev);
|
||||
}
|
||||
|
||||
@@ -1216,6 +1216,9 @@ static bool d3d9_init_internal(d3d9_video_t *d3d,
|
||||
{
|
||||
|
||||
d3d9_fake_context.get_flags = d3d9_get_flags;
|
||||
#ifndef _XBOX_
|
||||
d3d9_fake_context.get_metrics = win32_get_metrics;
|
||||
#endif
|
||||
video_context_driver_set(&d3d9_fake_context);
|
||||
#if defined(HAVE_CG) || defined(HAVE_HLSL)
|
||||
{
|
||||
@@ -1262,13 +1265,6 @@ static void d3d9_set_rotation(void *data, unsigned rot)
|
||||
d3d->dev_rotation = rot;
|
||||
}
|
||||
|
||||
static void d3d9_show_mouse(void *data, bool state)
|
||||
{
|
||||
#ifndef XBOX
|
||||
win32_show_cursor(state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *d3d9_init(const video_info_t *info,
|
||||
input_driver_t **input, void **input_data)
|
||||
{
|
||||
@@ -1472,7 +1468,9 @@ static void d3d9_overlay_enable(void *data, bool state)
|
||||
for (i = 0; i < d3d->overlays_size; i++)
|
||||
d3d->overlays_enabled = state;
|
||||
|
||||
d3d9_show_mouse(d3d, state);
|
||||
#ifndef XBOX
|
||||
win32_show_cursor(d3d, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void d3d9_overlay_full_screen(void *data, bool enable)
|
||||
@@ -1619,8 +1617,8 @@ static bool d3d9_frame(void *data, const void *frame,
|
||||
{
|
||||
d3d9_set_viewports(d3d->dev, &screen_vp);
|
||||
d3d9_begin_scene(d3d->dev);
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
font_driver_render_msg(d3d, video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
d3d9_end_scene(d3d->dev);
|
||||
}
|
||||
}
|
||||
@@ -1646,7 +1644,7 @@ static bool d3d9_frame(void *data, const void *frame,
|
||||
{
|
||||
d3d9_set_viewports(d3d->dev, &screen_vp);
|
||||
d3d9_begin_scene(d3d->dev);
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(d3d, video_info, msg, NULL, NULL);
|
||||
d3d9_end_scene(d3d->dev);
|
||||
}
|
||||
|
||||
@@ -1956,7 +1954,7 @@ static void d3d9_set_video_mode(void *data,
|
||||
bool fullscreen)
|
||||
{
|
||||
#ifndef _XBOX
|
||||
win32_show_cursor(!fullscreen);
|
||||
win32_show_cursor(data, !fullscreen);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1998,7 +1996,7 @@ static const video_poke_interface_t d3d9_poke_interface = {
|
||||
d3d9_set_menu_texture_enable,
|
||||
d3d9_set_osd_msg,
|
||||
|
||||
d3d9_show_mouse,
|
||||
win32_show_cursor,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
|
||||
@@ -1329,10 +1329,8 @@ static bool exynos_gfx_frame(void *data, const void *frame, unsigned width,
|
||||
(struct font_params*)&video_info->osd_stat_params : NULL;
|
||||
|
||||
if (osd_params)
|
||||
{
|
||||
font_driver_render_msg(video_info, NULL, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params);
|
||||
}
|
||||
font_driver_render_msg(vid, video_info, video_info->stat_text,
|
||||
(const struct font_params*)&video_info->osd_stat_params, NULL);
|
||||
}
|
||||
|
||||
if (msg)
|
||||
|
||||
@@ -335,7 +335,7 @@ static bool fpga_gfx_frame(void *data, const void *frame,
|
||||
}
|
||||
|
||||
if (msg)
|
||||
font_driver_render_msg(video_info, NULL, msg, NULL);
|
||||
font_driver_render_msg(fpga, video_info, msg, NULL, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -479,7 +479,7 @@ static void fpga_set_osd_msg(void *data,
|
||||
const char *msg,
|
||||
const void *params, void *font)
|
||||
{
|
||||
font_driver_render_msg(video_info, font, msg, params);
|
||||
font_driver_render_msg(data, video_info, msg, params, font);
|
||||
}
|
||||
|
||||
static void fpga_get_video_output_size(void *data,
|
||||
|
||||
Loaded 100 of 309 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user