Compare commits

...

676 Commits

Author SHA1 Message Date
yuzubot
dc529a89ae Android 278 2024-03-04 00:57:21 +00:00
yuzubot
1869349dce Merge yuzu-emu#13177 2024-03-04 00:57:21 +00:00
yuzubot
70711ddb39 Merge yuzu-emu#13174 2024-03-04 00:57:21 +00:00
yuzubot
adc597a799 Merge yuzu-emu#13018 2024-03-04 00:57:21 +00:00
yuzubot
276ceb26d0 Merge yuzu-emu#12461 2024-03-04 00:57:21 +00:00
Narr the Reg
15e6e48bef
Merge pull request #13198 from zhaobot/tx-update-20240301020652
Update translations (2024-03-01)
2024-03-01 01:57:00 -06:00
Pengfei Zhu
2f57c5a0e9
Revert arbaic translation 2024-03-01 15:20:53 +08:00
Pengfei Zhu
338e088b9d
Remove trailing whitespaces 2024-03-01 14:19:02 +08:00
The yuzu Community
56c9107d08 Update translations (2024-03-01) 2024-03-01 03:12:19 +00:00
liamwhite
dc94882c90
Merge pull request #13135 from german77/hid-interface
service: hid: Migrate HidServer to new IPC
2024-02-27 12:26:26 -05:00
liamwhite
30567a5909
Merge pull request #13175 from liamwhite/asan
general: fix asan errors
2024-02-27 09:42:59 -05:00
liamwhite
f1b1530249
Merge pull request #13171 from liamwhite/fake-address
texture_cache: do not track invalid addresses
2024-02-27 09:42:46 -05:00
liamwhite
6948ac8c16
general: workarounds for SMMU syncing issues (#12749) 2024-02-27 15:42:15 +01:00
liamwhite
b2e129eaa5
vk_rasterizer: flip scissor y on lower left origin mode (#13122) 2024-02-27 15:40:33 +01:00
liamwhite
1de37306a5
buffer_cache: avoid overflow in usage tracker (#13166) 2024-02-27 15:39:11 +01:00
liamwhite
9bc85dda5f
texture_cache: use two-pass collection for costly load resources (#13096) 2024-02-27 15:38:14 +01:00
Liam
c7174d5f61 general: fix asan errors 2024-02-26 19:28:49 -05:00
Narr the Reg
1bec420695
Merge pull request #13172 from liamwhite/gl-streams
renderer_opengl: declare geometry stream support in profile
2024-02-26 11:51:25 -06:00
liamwhite
79edad2533
Merge pull request #13159 from liamwhite/web-error
core: enable error applet, add stubs for web applet
2024-02-26 12:44:55 -05:00
liamwhite
ce62fa6f7b
Merge pull request #13149 from liamwhite/per-channel-program
video_core: make gpu context aware of rendering program
2024-02-26 12:44:46 -05:00
Liam
a0e254e7c4 renderer_opengl: declare geometry stream support in profile 2024-02-26 11:18:30 -05:00
Liam
25c3bbba0e settings: remove global override for smash on amdvlk 2024-02-26 11:16:18 -05:00
Liam
d66ca8b731 video_core: make gpu context aware of rendering program 2024-02-26 11:16:14 -05:00
Liam
fd9ed54f27 texture_cache: do not track invalid addresses 2024-02-26 10:26:27 -05:00
liamwhite
f9bfdb1555
Merge pull request #13164 from merryhime/reset-submodules
tools: Add reset submodules script
2024-02-25 14:01:11 -05:00
liamwhite
15831b19a3
Merge pull request #13163 from german77/ring
core: hid: hid_core doesn't have access to LIBUSB
2024-02-25 14:01:05 -05:00
liamwhite
8416d1c028
Merge pull request #13154 from german77/vibration-filter
core: hid: Reintroduce vibration filter
2024-02-25 14:00:59 -05:00
Merry
4d5d37ae61 tools: Add reset submodules script 2024-02-25 17:17:01 +00:00
german77
e62cea20d1 core: hid: hid_core doesn't have access to LIBUSB 2024-02-25 10:06:43 -06:00
Narr the Reg
9e27dbb53b
Merge pull request #13160 from liamwhite/time
glue: load initial year setting as s32
2024-02-25 08:47:16 -06:00
Liam
dc50b95a47 settings: enable error applet 2024-02-24 22:56:08 -05:00
Liam
4050242cf3 ldn: return no connection from GetStateForMonitor 2024-02-24 22:56:08 -05:00
Liam
fd718f350c ssl: add cert store 2024-02-24 22:56:05 -05:00
Liam
0d6fd12231 glue: load initial year setting as s32 2024-02-24 22:49:38 -05:00
Liam
f297e98a9e acc: add account manager for acc:u1 2024-02-24 22:25:34 -05:00
Liam
637c54e205 fs: add stubs for online web applet 2024-02-24 22:25:34 -05:00
Liam
f045fa576b erpt: stub report creation 2024-02-24 22:25:34 -05:00
Liam
692ba0fa7d set: add GetPlatformRegion 2024-02-24 22:25:34 -05:00
liamwhite
a93d249ac1
Merge pull request #13155 from german77/GetSettingsItemValue
service: set: Fix GetSettingsItemValue
2024-02-24 16:24:01 -05:00
german77
9fccccedee service: set: Fix GetSettingsItemValue 2024-02-24 14:44:21 -06:00
german77
ca7f949ee8 core: hid: Reintroduce vibration filter 2024-02-24 12:19:51 -06:00
liamwhite
05f94dc5fc
Merge pull request #13153 from german77/defaultset
service: set: Enable nfc and others by default and bump version
2024-02-24 12:48:31 -05:00
liamwhite
dcf7698924
Merge pull request #13081 from FearlessTobi/aoc-ipc
aoc: Migrate to use cmif serialization
2024-02-24 12:48:26 -05:00
Narr the Reg
7b68d7d467
Merge pull request #13150 from liamwhite/region
set: fix region code for system settings
2024-02-24 11:40:31 -06:00
german77
4741e50047 service: set: Enable nfc and others by default and bump version 2024-02-24 11:19:51 -06:00
Liam
7836c0867d set: fix region code for system settings 2024-02-24 00:48:44 -05:00
liamwhite
d1e0039bc8
Merge pull request #13142 from t895/vibration-queue
android: Play vibrations asynchronously
2024-02-24 00:38:13 -05:00
liamwhite
7a51eaa727
Merge pull request #13146 from wheremyfoodat/patch-1
common/ring_buffer: Include <limits> header
2024-02-23 20:32:40 -05:00
liamwhite
6c40d75e47
Merge pull request #13140 from german77/yet-more-qlaunch
service: Stub multiple function for qlaunch
2024-02-23 20:32:32 -05:00
Narr the Reg
0a0c257206 service: audio: Add missing logging properties of SetHeadphoneOutputLevelMode 2024-02-23 18:58:51 -06:00
Narr the Reg
7019023cbc service: btdrv: Add EnableRadio for Qlaunch 2024-02-23 18:58:51 -06:00
Narr the Reg
c48c182fe0 service: friend: Add GetFriendCount, GetNewlyFriendCount, GetReceivedFriendRequestCount, GetPlayHistoryStatistics, GetReceivedFriendInvitationCountCache for QLaunch 2024-02-23 18:58:51 -06:00
Narr the Reg
98be02898b service: hid: Add IsAnyCustomButtonConfigEnabled for QLaunch 2024-02-23 18:58:51 -06:00
Narr the Reg
e1bdeb2942 service: lbl: Add SaveCurrentSetting, LoadCurrentSetting and IsAutoBrightnessControlSupported for QLaunch 2024-02-23 18:58:50 -06:00
Narr the Reg
015d666a4d service: nfc: Implement SetNfcEnabled 2024-02-23 18:58:50 -06:00
Narr the Reg
624c90a439 service: npns: Add ListenTo and GetReceiveEvent for QLaunch 2024-02-23 18:58:39 -06:00
Narr the Reg
0fb26acccc service: set: Add default eula setting 2024-02-23 18:58:19 -06:00
wheremyfoodat
ed315fb8a5
common/ring_buffer: Include <limits> header 2024-02-24 02:34:09 +02:00
Narr the Reg
fc6a87bba1 service: hid: Migrate HidServer to new IPC 2024-02-23 17:49:02 -06:00
Narr the Reg
d08f201e0c service: hid: Move and migrate AppletResource and ActiveVibrationDevice 2024-02-23 17:49:02 -06:00
t895
0369c65870 android: Play vibrations asynchronously 2024-02-23 16:41:59 -05:00
liamwhite
975d6f1ec4
Merge pull request #13141 from liamwhite/swap
fs: fix argument order
2024-02-23 15:23:06 -05:00
liamwhite
7c9e2255be
Merge pull request #13137 from liamwhite/mac-ci
ci: fix mac build
2024-02-23 15:21:18 -05:00
liamwhite
9f6818a6e5
Merge pull request #13136 from liamwhite/fs-launch
fs: add ISaveDataTransferProhibiter, stub FindSaveDataWithFilter
2024-02-23 15:21:12 -05:00
Liam
f1c16b487a fs: fix argument order 2024-02-23 15:10:35 -05:00
Liam
6512f39061 ci: fix mac build 2024-02-23 13:25:48 -05:00
Liam
22b91afa69 fs: add ISaveDataTransferProhibiter, stub FindSaveDataWithFilter 2024-02-23 12:17:24 -05:00
liamwhite
77107ba124
Merge pull request #13133 from liamwhite/libstdcxx-issue
vi: workaround conductor includes
2024-02-23 11:34:34 -05:00
liamwhite
fa4dec9fe9
Merge pull request #13115 from liamwhite/olsc-pctl
olsc, pctl: move to new ipc
2024-02-23 11:34:29 -05:00
liamwhite
215e887be0
Merge pull request #13100 from liamwhite/audio-ipc
audio: move to new ipc
2024-02-23 11:34:21 -05:00
liamwhite
0da6704fc2
Merge pull request #13073 from FearlessTobi/fsp-srv-ipc
fsp: Migrate remaining interfaces to cmif serialization
2024-02-23 11:34:06 -05:00
Liam
812754edec vi: workaround conductor includes 2024-02-23 10:34:49 -05:00
Liam
964e19ab56 oboe_sink: handle temporary stream creation failure 2024-02-23 10:30:52 -05:00
liamwhite
9dc624f5dc
Merge pull request #13121 from german77/clean-shortcut
yuzu: Fix shortcut error message
2024-02-22 23:04:28 -05:00
liamwhite
dad9ea3e07
Merge pull request #13117 from liamwhite/ovln
psc: stub overlay notification channel
2024-02-22 20:26:03 -05:00
Liam
2c00599a53 audio: fix released buffer bounds check 2024-02-22 20:20:31 -05:00
FearlessTobi
2786d34dd7 aoc: Rename AOC_U to IAddOnContentManager 2024-02-23 01:19:18 +01:00
Narr the Reg
864b046500 yuzu: Fix shortcut error message 2024-02-22 17:52:30 -06:00
liamwhite
d12d9dad40
Merge pull request #12982 from FearlessTobi/fs-rewrite-part0
fs: Add FileSystemAccessor and use cmif serialization
2024-02-22 12:34:47 -05:00
Narr the Reg
2b3f1d3fc5
Merge pull request #13000 from liamwhite/skip-null-memory
device_memory_manager: skip unregistered interfaces on invalidate
2024-02-22 11:34:23 -06:00
Narr the Reg
984396a21a
Merge pull request #13001 from liamwhite/scaled-availability
vulkan_device: don't use fixed cap for memory limits
2024-02-22 11:31:17 -06:00
Narr the Reg
4f95ee5209
Merge pull request #13075 from liamwhite/mali-having-a-bad-time
shader_recompiler: throw on missing geometry streams in geometry shaders
2024-02-22 11:30:26 -06:00
Liam
c04567fad4 audio: add NotifyHeadphoneVolumeWarningDisplayedEvent 2024-02-21 23:54:10 -05:00
Liam
89c2fd3d28 pctl: rewrite IParentalControlService 2024-02-21 23:42:33 -05:00
Liam
5ab49c833d pctl: rewrite IParentalControlServiceFactory 2024-02-21 23:00:01 -05:00
Liam
0e74204aad pctl: move IParentalControlServiceFactory 2024-02-21 23:00:01 -05:00
Liam
a37bd0b9a7 pctl: move IParentalControlService 2024-02-21 23:00:01 -05:00
Liam
01d89acd13 pctl: move types and results 2024-02-21 22:58:20 -05:00
Liam
e85466c1ae psc: stub overlay notification channel 2024-02-21 22:54:05 -05:00
Liam
352297d361 psc: rewrite IPmService 2024-02-21 22:26:32 -05:00
Liam
6c2d6cff19 psc: move IPmControl, IPmModule, IPmService 2024-02-21 22:26:12 -05:00
Liam
e540757279 olsc: rewrite IOlscServiceForSystemService 2024-02-21 20:02:00 -05:00
Liam
a8bca24292 olsc: add IRemoteStorageController 2024-02-21 19:47:54 -05:00
Liam
5f3c03d6a8 olsc: add IDaemonController 2024-02-21 19:05:19 -05:00
Liam
6b956a6951 olsc: rewrite ITransferTaskListController 2024-02-21 18:36:17 -05:00
Liam
8689370830 olsc: rewrite INativeHandleHolder 2024-02-21 18:19:48 -05:00
Liam
8ffa27b311 olsc: rewrite IOlscServiceForApplication 2024-02-21 18:19:12 -05:00
Liam
6334616b44 olsc: move INativeHandleHolder, IOlscServiceForApplication, IOlscServiceForSystemService, ITransferTaskListController 2024-02-21 16:13:01 -05:00
liamwhite
8bbc209950
Merge pull request #13105 from t895/connection-fix
android: Misc controller fixes
2024-02-21 10:43:46 -05:00
liamwhite
9e1a67b950
fs: add missing mutex header for member (#13106) 2024-02-21 16:43:05 +01:00
t895
de5422b1fd android: Connect controllers with supported styles
If you tried to connect a controller that was previously configured with an unsupported style for your game, when you try to connect that controller, it will immediately disconnect. This ensures that the controller that is being connected will be changed to the first supported style index before being connected.
2024-02-21 08:37:55 -05:00
t895
45f450fca5 android: Add additional check for hasMapping
Controls can have no mapping if they are either "[empty]" or and empty string. This was causing an issue if you reset mapping on all controllers and then tried to play a game. The check to determine whether auto mapping was required would fail and leave you will no mapped controllers. This feels a bit like user error but it smooths things out if you forget so I see it as necessary.
2024-02-21 08:17:30 -05:00
t895
9a3fd76b25 android: Enable all controller styles on emulation shutdown 2024-02-21 08:13:54 -05:00
Charles Lombardo
60fc6df407
Merge pull request #13099 from t895/default-fix
android: Fix extra stick setting default values
2024-02-21 07:02:58 -05:00
Liam
2e4a6b7f92 audio: format 2024-02-20 22:51:39 -05:00
Liam
5f90bd88da audio: rewrite IHardwareOpusDecoder 2024-02-20 22:15:38 -05:00
Liam
c575a85233 audio: rewrite IAudioDevice 2024-02-20 22:15:38 -05:00
Liam
ea4703cb31 audio: rewrite IHardwareOpusDecoderManager 2024-02-20 22:15:38 -05:00
Liam
0471e54e5a audio: rewrite IAudioRenderer 2024-02-20 22:15:38 -05:00
Liam
6012c9fe3a audio: rewrite IAudioRendererManager 2024-02-20 22:15:37 -05:00
Liam
f65539504f audio: split IHardwarweOpusDecoder, move IHardwareOpusDecoderManager 2024-02-20 22:15:37 -05:00
Liam
62083fcafd audio: split IAudioDevice, IAudioRenderer, move IAudioRendererManager 2024-02-20 22:15:37 -05:00
Liam
2e5a9cf119 audio: move IFinalOutputRecorderManager{,ForApplet} 2024-02-20 22:15:37 -05:00
Liam
a45b8bc9bc audio: rewrite IAudioOutManager 2024-02-20 22:15:37 -05:00
Liam
a05bd3c47e audio: rewrite IAudioOut 2024-02-20 22:15:37 -05:00
Liam
2a2c92f181 audio: rewrite IAudioInManager 2024-02-20 22:15:37 -05:00
Liam
f54277364c audio: rewrite IAudioIn 2024-02-20 22:15:37 -05:00
t895
de2d496e71 android: Fix extra stick setting default values
The default value was accidentally hardcoded for all extra stick settings
2024-02-20 22:13:59 -05:00
liamwhite
7b5bdd076d
Merge pull request #13095 from liamwhite/ns-oops
ns: fix alignment of uid type
2024-02-20 21:19:35 -05:00
Matías Locatti
e0c17a2113
Merge pull request #10529 from liamwhite/critical-spacing
caches: make critical reclamation less eager and possible in more cases
2024-02-20 23:19:27 -03:00
Liam
b107435a3f ns: fix alignment of uid type 2024-02-20 18:43:44 -05:00
liamwhite
4e1fcd4a63
Merge pull request #13091 from t895/device-renaming
android: Expose device name setting
2024-02-20 18:30:54 -05:00
liamwhite
ea4a96b45e
Merge pull request #13079 from liamwhite/vi3
vi: misc fixes
2024-02-20 18:30:47 -05:00
t895
6a90db8c19 android: Expose device name setting 2024-02-20 08:16:38 -05:00
t895
0e5972b0b5 android: Add StringInputSetting settings item 2024-02-20 08:06:56 -05:00
Liam
5f7608a7c6 vi: ignore shared buffer destruction failure on termination 2024-02-20 00:02:56 -05:00
Liam
668ff0db3a vi: remove superfluous locking in shared buffer manager 2024-02-19 23:59:35 -05:00
Liam
9f159dd62c nvnflinger/vi: don't recreate buffer queue on open/close 2024-02-19 23:59:35 -05:00
Andrew Pilley
d1eaeeed8c
Import keys from filesystem. (#13056)
* Import keys, re-initialize KeyManager, re-scan vfs, re-populate game list.

* <.< spelling.

* Update based on feedback on #13047 and this PR

* Based on feedback: Don't delete existing files. There's legitimate reasons that someone may want to keep their retail keys and title key handling is resilient to mismatches.

* Update src/yuzu/main.cpp

Co-authored-by: Tobias <thm.frey@gmail.com>

* Remove translation of literal filename/filter format.

* clang-format.

---------

Co-authored-by: Tobias <thm.frey@gmail.com>
2024-02-19 19:18:13 -05:00
liamwhite
10e27a2902
Merge pull request #13086 from t895/clear-button-fix
android: Fix broken clear button check
2024-02-19 19:18:05 -05:00
Charles Lombardo
f567a41f53
android: Have input overlay follow player 1 style index (#13085) 2024-02-19 22:47:21 +01:00
t895
704c62ca01 android: Fix broken clear button check 2024-02-19 15:54:52 -05:00
liamwhite
8d5473e67c
Merge pull request #13031 from german77/btm-interfcae
service: btm: Migrate service to new IPC
2024-02-19 14:49:42 -05:00
Charles Lombardo
3b1b98c645
android: Fix overlay visibility reset (#13083) 2024-02-19 19:44:42 +01:00
Charles Lombardo
daf350f5d3
android: Show done button when configuring input overlay (#13082) 2024-02-19 19:26:18 +01:00
FearlessTobi
ef50277124 Address review comments pt. 2 2024-02-19 19:22:51 +01:00
FearlessTobi
ba70dc4c13 Address review comments 2024-02-19 19:20:46 +01:00
FearlessTobi
934e420e36 fs: Refactor to use cmif serialization 2024-02-19 19:20:46 +01:00
FearlessTobi
d5e4617ab5 fs: Add FileSystemAccessor classes 2024-02-19 19:20:40 +01:00
FearlessTobi
b5a17b501b Address review comments 2024-02-19 19:11:07 +01:00
FearlessTobi
2b18957365 fs: Add and use fs_save_data_types.h 2024-02-19 19:06:31 +01:00
FearlessTobi
4c71bf3d90 fsp: Migrate remaining interfaces to cmif serialization 2024-02-19 19:06:31 +01:00
FearlessTobi
fdf4a5bc90 fsp-srv: Migrate to use cmif serialization 2024-02-19 19:06:31 +01:00
FearlessTobi
b7d9eba72b fsp: Move IMultiCommitManager to a seperate file 2024-02-19 19:06:31 +01:00
FearlessTobi
380475af32 fsp: Move ISaveDataInfoReader to a seperate file 2024-02-19 19:06:31 +01:00
FearlessTobi
a2a0be4246 aoc: Migrate to use cmif serialization 2024-02-19 17:20:02 +01:00
liamwhite
c9ef2e26ca
Merge pull request #13080 from FearlessTobi/scope-exit
scope_exit: Make constexpr
2024-02-19 10:50:45 -05:00
FearlessTobi
aa6532cf34 core/aoc: Move IPurchaseEventManager to separate file 2024-02-19 16:36:24 +01:00
FearlessTobi
310c1f50be scope_exit: Make constexpr
Allows the use of the macro in constexpr-contexts.
Also avoids some potential problems when nesting braces inside it.
2024-02-19 16:00:46 +01:00
FearlessTobi
665fce871f core/CMakeLists: Sort alphabetically 2024-02-19 15:51:02 +01:00
Narr the Reg
58c7e846cb
Merge pull request #13006 from liamwhite/a-hat-in-vram
buffer_cache: use mapped range with large vertex buffer size
2024-02-18 23:37:49 -06:00
Narr the Reg
8b0fb98a11
Merge pull request #13026 from liamwhite/scale-this-mf
shader_recompiler: fix non-const offset for arrayed image types
2024-02-18 23:37:25 -06:00
Narr the Reg
8615509c40
Merge pull request #13035 from liamwhite/vi2
vi: manage resources independently of nvnflinger and refactor
2024-02-18 23:36:53 -06:00
Narr the Reg
d0af52f28e
Merge pull request #13048 from liamwhite/new-shell
ns: rewrite for new IPC
2024-02-18 23:36:29 -06:00
Liam
f46dc31683 shader_recompiler: throw on missing geometry streams in geometry shaders 2024-02-19 00:34:00 -05:00
liamwhite
ef89b79d7e
Merge pull request #13070 from liamwhite/offset
am: account for offset in transfer memory storage
2024-02-18 19:03:56 -05:00
liamwhite
3e41f9a673
Merge pull request #13030 from german77/audio-controller
service: audio: Rewrite IAudioController to new IPC
2024-02-18 19:03:49 -05:00
Liam
d45a12826c ns: address review comments 2024-02-18 19:02:00 -05:00
Liam
56810541f0 vulkan_device: don't use fixed cap for memory limits 2024-02-18 18:59:13 -05:00
Liam
911ee8fd1f am: account for offset in transfer memory storage 2024-02-18 14:56:48 -05:00
Charles Lombardo
5361027ef0
Merge pull request #13068 from german77/no_errors
core: hid: Remove driver errors from log
2024-02-18 13:30:54 -05:00
german77
56721517ea core: hid: Remove driver errors from log 2024-02-18 10:54:56 -06:00
Liam
940a71422e nvnflinger: check for layers before compose 2024-02-18 11:25:52 -05:00
liamwhite
da225d4aa1
Merge pull request #13067 from t895/xbox-automap-invert
android: Flip AB/XY for xbox controllers during auto-mapping
2024-02-18 10:48:54 -05:00
t895
8d74c107f5 android: Flip AB/XY for xbox controllers during auto-mapping 2024-02-18 10:40:33 -05:00
liamwhite
1fc86b1e3a
Merge pull request #13032 from german77/qlauncher
service: Implement functions needed by Qlaunch
2024-02-18 10:37:52 -05:00
Liam
4cdf18095d ns: rewrite IQueryService 2024-02-18 10:35:39 -05:00
Liam
2d43831d1f ns: rewrite IServiceGetterInterface 2024-02-18 10:35:39 -05:00
Liam
2e96921f9c ns: rewrite IApplicationManagerInterface 2024-02-18 10:35:39 -05:00
Liam
cf0de18982 ns: move IDevelopInterface 2024-02-18 10:35:37 -05:00
Liam
ae83ee28a3 ns: rewrite ISystemUpdateInterface 2024-02-18 10:32:21 -05:00
Liam
306ed4984b ns: move ISystemUpdateControl 2024-02-18 10:32:21 -05:00
Liam
626f2e65b1 ns: rewrite IVulnerabilityManagerInterface 2024-02-18 10:32:21 -05:00
Liam
2eded86b4b ns: rewrite IReadOnlyApplicationControlDataInterface 2024-02-18 10:32:21 -05:00
Liam
786fc512e2 ns: rewrite IReadOnlyApplicationRecordInterface 2024-02-18 10:32:21 -05:00
Liam
c31ac45332 ns: add IDynamicRightsInterface 2024-02-18 10:32:21 -05:00
Liam
db172ba249 ns: rewrite IDownloadTaskInterface 2024-02-18 10:32:21 -05:00
Liam
bb59940b03 ns: rewrite IDocumentInterface 2024-02-18 10:32:21 -05:00
Liam
04887953ff ns: rewrite IContentManagementInterface 2024-02-18 10:32:21 -05:00
Liam
8ea72cc99d ns: move IFactoryResetInterface 2024-02-18 10:32:21 -05:00
Liam
44d2e90217 ns: move IECommerceInterface 2024-02-18 10:32:21 -05:00
Liam
12926eb5db ns: move IApplicationVersionInterface 2024-02-18 10:32:21 -05:00
Liam
ae114d2fa1 ns: move IAccountProxyInterface 2024-02-18 10:32:21 -05:00
Liam
270d07be2f ns: rewrite IPlatformServiceManager 2024-02-18 10:32:21 -05:00
Liam
947cdbe4b1 ns: rename results header 2024-02-18 10:32:21 -05:00
liamwhite
5583957616
Merge pull request #13064 from t895/auto-map-fail
android: Only do first startup automapping if nothing has been mapped
2024-02-18 10:27:49 -05:00
liamwhite
6d731e1aa1
Merge pull request #13049 from Leystryku/master
Fix Just Dance 2023 not booting
2024-02-18 10:25:18 -05:00
liamwhite
839ded7d59
Merge pull request #13065 from t895/cancel-button-fail
android: Show cancel button for the content install notice
2024-02-18 10:25:04 -05:00
liamwhite
f57281ebc1
Merge pull request #13066 from t895/touch-fix
android: Map touches to touchscreen
2024-02-18 10:24:58 -05:00
t895
0a3bc6c0cf android: Map touches to touchscreen
I neglected to map touches to the touchscreen when refactoring in the input mapping PR. This fixes that regression.
2024-02-18 10:00:37 -05:00
t895
55a7815064 android: Show cancel button for the content install notice 2024-02-18 09:23:46 -05:00
t895
a1c4f53c8c android: Only do first startup automapping if nothing has been mapped 2024-02-18 09:18:54 -05:00
Leystryku
8bbb44a74e service: Change unique_ptr to make_unique in GetCacheStorageMax 2024-02-18 07:03:50 +01:00
Leystryku
bc5ae04ea0 file_sys: Formatting changes and use unique_ptr in GetCacheStorageMax 2024-02-18 06:17:35 +01:00
Leystryku
4f387b0b74 file_sys: Fix nacp field cache_storage_max_index datatype 2024-02-18 06:00:42 +01:00
liamwhite
bdf8aca750
Merge pull request #13047 from anpilley/import-firmware
Import firmware from folder of loose NCA files
2024-02-17 23:18:00 -05:00
liamwhite
acfc4d6dfb
Merge pull request #13054 from t895/lifecycle-utils
android: Create lifecycle utility to simplify common StateFlow operations
2024-02-17 23:17:49 -05:00
t895
35a3c7226a android: Create lifecycle utility to simplify common StateFlow operations 2024-02-17 23:09:09 -05:00
Leystryku
d93fdc8a6c service: Add proper GetCacheStorageMax implementation to IApplicationFunctions 2024-02-18 05:02:35 +01:00
liamwhite
5d3c7433b8
Merge pull request #13050 from t895/marquee-helper
android: Use extension functions for view visibility and text marquee
2024-02-17 22:48:36 -05:00
t895
0010d42f82 android: Use extension functions for view visibility and text marquee 2024-02-17 22:45:33 -05:00
liamwhite
316089c39f
Merge pull request #13052 from t895/serializable-stuff
android: Move CoreErrorDialogFragment to its own file
2024-02-17 22:22:46 -05:00
liamwhite
5024df1925
Merge pull request #13051 from german77/cheatmiss
dmnt: cheats: Fix valid address range
2024-02-17 22:22:14 -05:00
liamwhite
e7146309de
Merge pull request #13034 from t895/map-all-the-inputs
android: Input mapping
2024-02-17 22:22:06 -05:00
t895
c327d2a62c android: Move CoreErrorDialogFragment to its own file 2024-02-17 21:58:25 -05:00
Andrew Pilley
cb2e312f13 Add check for corrupted firmware files after install. 2024-02-18 12:31:14 +11:00
german77
366bb52ec8 dmnt: cheats: Fix valid address range 2024-02-17 19:10:17 -06:00
Leystryku
82949085c0 fsp: Add FlushAccessLogOnSdCard stub 2024-02-18 00:52:22 +01:00
Leystryku
90c43aa2e7 service: Add GetCacheStorageMax stub to IApplicationFunctions 2024-02-18 00:49:41 +01:00
german77
a07f0883b9 service: vi: Implement ListDisplayMode 2024-02-17 18:08:41 -05:00
Liam
812f23d05c vi: manage resources independently of nvnflinger and refactor 2024-02-17 18:08:38 -05:00
Liam
dcce9837d2 vi: move shared buffer management from nvnflinger 2024-02-17 18:01:41 -05:00
Liam
ee8eccc5fa nvnflinger: convert to process 2024-02-17 18:01:41 -05:00
Liam
7b79cddacd am: unify display layer management 2024-02-17 18:00:28 -05:00
Narr the Reg
53f8383354
Merge pull request #13017 from liamwhite/suspension
kernel: add and enable system suspend type
2024-02-17 17:00:07 -06:00
liamwhite
36108ce2be
Merge pull request #13040 from Kelebek1/timezone_shutdown
Close reference to TimeZoneBinary on game close
2024-02-17 17:53:53 -05:00
Narr the Reg
4cbafc1ef6 service: audio: Rewrite IAudioController to new IPC 2024-02-17 15:05:13 -06:00
Andrew Pilley
e31c926bf0 >.> spelling 2024-02-18 07:58:41 +11:00
Andrew Pilley
59ede32f8e cleanup by clang-format. 2024-02-18 07:41:24 +11:00
Andrew Pilley
9eba64adce Improve behavior when one or more firmware files can't be deleted. 2024-02-18 07:38:47 +11:00
Narr the Reg
110969e207 service: btm: Implement function needed by QLaunch 2024-02-17 12:39:36 -06:00
t895
50ecad547e android: Input mapping 2024-02-17 12:32:33 -05:00
Kelebek1
34fb14ec9a Close reference to TimeZoneBinary on game close 2024-02-17 16:00:14 +00:00
Andrew Pilley
e2e0916100
Merge branch 'yuzu-emu:master' into import-firmware 2024-02-17 23:36:43 +11:00
Andrew Pilley
501e3ae05a Implement In-app firmware installation. 2024-02-17 23:33:55 +11:00
t895
ac33847b30 hid_core: Prevent crash if we try to iterate through empty color devices list 2024-02-16 21:11:47 -05:00
t895
18494b0ad6 hid_core: Use dedicated "port" for android's input overlay 2024-02-16 21:09:42 -05:00
t895
dc2c302a84 config: Reset per-game profile name on load if empty 2024-02-16 21:07:03 -05:00
t895
a251f77556 android: Allow SettingsItems to use String or StringRes 2024-02-16 21:04:26 -05:00
Narr the Reg
ec02a1cfe5 service: erpt: Implement SubmitContext 2024-02-16 12:22:09 -06:00
Narr the Reg
39b958ab86 service: caps: Implement GetAlbumFIleList 2024-02-16 12:15:37 -06:00
Narr the Reg
9c0724b270 service: btm: Migrate service to new IPC 2024-02-16 12:15:06 -06:00
Narr the Reg
dbcc447f43 service: am: Fix GetMainAppletAvailableUsers for user creation 2024-02-16 12:13:10 -06:00
Narr the Reg
2954c01b47 service: am: Add QLaunch launcher 2024-02-16 12:13:10 -06:00
liamwhite
c7588c042b
Merge pull request #13016 from german77/set-interface2
service: set: Migrate ISystemSettingsServer to new IPC
2024-02-16 13:11:36 -05:00
Narr the Reg
6e2678a42c
Merge pull request #13011 from liamwhite/vi-ipc
vi: rewrite for new IPC
2024-02-16 12:11:02 -06:00
Liam
462ea921e3 shader_recompiler: fix non-const offset for arrayed image types 2024-02-15 18:49:23 -05:00
Liam
cb29aa0473 Revert "shader_recompiler: use only ConstOffset for OpImageFetch"
This reverts commit f296a9ce9a1a144d322d54d4628dba6f8a800cb7.
2024-02-15 18:38:56 -05:00
Liam
af42482565 kernel: add and enable system suspend type 2024-02-14 17:03:50 -05:00
Narr the Reg
caf16982d9 service: set: Migrate ISystemSettingsServer to new IPC 2024-02-14 12:40:10 -06:00
Liam
1842df1da5 vi: rewrite IApplicationDisplayService 2024-02-14 12:03:32 -05:00
Liam
8863940bf5 vi: rewrite ISystemDisplayService 2024-02-14 12:03:32 -05:00
Liam
b1c71f976c vi: rewrite IManagerDisplayService 2024-02-14 12:03:32 -05:00
Liam
59011a04a1 vi: rewrite IHOSBinderDriver 2024-02-14 12:03:32 -05:00
Liam
c448001d47 vi: rewrite IApplicationRootService, IManagerRootService, ISystemRootService 2024-02-14 12:03:32 -05:00
Liam
2e8c0e9247 vi: split into implementation files 2024-02-14 12:03:32 -05:00
Liam
db871677b0 vi: extract types 2024-02-14 12:03:31 -05:00
liamwhite
a40adbc142
Merge pull request #12996 from german77/settings-ipc
service: set: Migrate ISettingsServer to new interface
2024-02-14 12:02:46 -05:00
Narr the Reg
1e8554b01f
Merge pull request #12993 from liamwhite/am-rewrite-part1
am: rewrite part 1
2024-02-14 11:02:38 -06:00
german77
75bfbadb23 service: set: Migrate ISettingsServer to new interface 2024-02-13 17:21:52 -06:00
liamwhite
ad4ae39903
Merge pull request #13009 from t895/message-dialog-fix
android: Message dialog tweaks
2024-02-13 14:46:56 -05:00
liamwhite
fefdba05ca
Merge pull request #13007 from t895/screen-bias
android: Expose FSR slider and add vertical alignment setting
2024-02-13 14:46:48 -05:00
t895
f813dc78b2 android: Prevent user from dismissing mod/cheat notice
Makes sure that a user can't miss this dialog by touching outside the window. They must press "OK" or "Close" to continue.
2024-02-13 13:46:14 -05:00
t895
10ba318807 android: Show cancel option for delete addons dialog 2024-02-13 13:45:17 -05:00
t895
86fc1e5b32 android: Swap ok and close default strings for MessageDialogFragment 2024-02-13 13:44:35 -05:00
t895
3c823254ff android: Add screen vertical alignment setting
It's a bit of a hack since I'm moving the view instead of telling the Vulkan surface to bias itself to the top/bottom/center but it works fine for now.
2024-02-13 10:10:59 -05:00
t895
a0513bc45b android: Expose FSR sharpness slider 2024-02-13 10:04:59 -05:00
Liam
3067bfd126 buffer_cache: use mapped range with large vertex buffer size 2024-02-13 08:27:33 -05:00
liamwhite
95d96cfe66
Merge pull request #12974 from german77/ldn-interface
service: ldn: Migrate and refractor service to new IPC
2024-02-13 08:18:31 -05:00
liamwhite
f75fceb3c0
Merge pull request #12975 from FernandoS27/keep-your-own-vodoo-doll-away-from-gf
Texture Cache: Fix untracking on GPU remap
2024-02-13 08:17:59 -05:00
liamwhite
3511d5552a
Merge pull request #12989 from german77/hotcake
yuzu: Allow non npad hotkeys and disable controller navigation requirement
2024-02-13 08:17:50 -05:00
liamwhite
f27bdce70f
Merge pull request #12998 from t895/swap-clear-actions
android: Swap confirmation buttons for delete save data dialog
2024-02-13 08:17:39 -05:00
liamwhite
85fd2bcb82
Merge pull request #12941 from FearlessTobi/setting-tooltips
shared_translation: Add tooltips for yuzu settings
2024-02-13 08:17:32 -05:00
Liam
461eaca7e8 device_memory_manager: skip unregistered interfaces on invalidate 2024-02-12 20:02:59 -05:00
t895
836592c447 android: Swap confirmation buttons for delete save data dialog 2024-02-12 16:54:46 -05:00
t895
fbc1b61bff android: Extend MessageDialogFragment to support a negative action and button titles 2024-02-12 16:54:19 -05:00
Liam
bca698a17a am: move out omm interfaces to new module 2024-02-12 09:18:29 -05:00
Liam
a65fb85b6d am: rewrite IApplicationCreator 2024-02-12 09:18:27 -05:00
Liam
bbb1ff6574 am: add IApplicationAccessor 2024-02-12 09:17:25 -05:00
Liam
927fa532e5 am: rewrite ILockAccessor 2024-02-12 09:17:25 -05:00
Liam
87b740df46 am: rewrite IWindowController 2024-02-12 09:17:25 -05:00
Liam
203d213529 am: rewrite IStorage 2024-02-12 09:17:25 -05:00
Liam
2e614ce08f am: rewrite IStorageAccessor, ITransferStorageAccessor 2024-02-12 09:17:25 -05:00
Liam
9e271f2017 am: rewrite ISelfController 2024-02-12 09:17:21 -05:00
Liam
79f225bd59 am: rewrite IProcessWindingController 2024-02-12 09:16:03 -05:00
Liam
c7e94e2175 am: rewrite ILibraryAppletSelfAccessor 2024-02-12 09:16:02 -05:00
Liam
1c797a8048 am: rewrite ILibraryAppletCreator 2024-02-12 09:16:02 -05:00
Liam
f9bba8007d am: rewrite ILibraryAppletAccessor 2024-02-12 09:16:02 -05:00
Liam
2c49ebbeea am: rewrite IHomeMenuFunctions 2024-02-12 09:16:02 -05:00
Liam
17460def8e am: rewrite IGlobalStateController, add ICradleFirmwareUpdater 2024-02-12 09:16:02 -05:00
Liam
77b7e1e682 am: rewrite IDisplayController 2024-02-12 09:16:02 -05:00
Liam
eafaa5511d am: move IDebugFunctions 2024-02-12 09:16:02 -05:00
Liam
96fea99af9 am: rewrite ICommonStateGetter 2024-02-12 09:16:02 -05:00
Liam
44e7e85f23 am: rewrite IApplicationFunctions 2024-02-12 09:16:00 -05:00
Liam
af35057212 am: rewrite IAppletCommonFunctions 2024-02-11 21:59:33 -05:00
Liam
590e86792c am: rewrite IAudioController 2024-02-11 21:59:33 -05:00
Liam
6fd6c65fd4 am: rewrite ISystemAppletProxy 2024-02-11 21:59:33 -05:00
Liam
c809f7193a am: rewrite ILibraryAppletProxy 2024-02-11 21:59:33 -05:00
Liam
c7e97b22fb am: rewrite IApplicationProxy 2024-02-11 21:59:33 -05:00
Liam
b2e140b032 am: rewrite appletAE, appletOE 2024-02-11 21:59:33 -05:00
Narr the Reg
2ff45cd0da
Merge pull request #12756 from liamwhite/applet-multiprocess-hwc
general: applet multiprocess
2024-02-11 20:58:28 -06:00
liamwhite
b6b56f48b7
Merge pull request #12991 from german77/news2
service: news: Stub remaining functions
2024-02-11 21:44:23 -05:00
german77
04a9d14f35 service: news: Stub remaining functions 2024-02-11 17:56:26 -06:00
german77
26e028808a yuzu: Allow non npad hotkeys and disable controller navigation requirement 2024-02-11 16:29:31 -06:00
Narr the Reg
2053ff96fc service: ldn: Migrate and refractor service to new IPC 2024-02-11 13:11:11 -06:00
Liam
368bf2211f texture_cache: tweak iteration tracking change 2024-02-11 13:41:13 -05:00
Liam
de8a623932 texture_cache: avoid overestimation of ASTC texture sizes 2024-02-11 13:41:13 -05:00
Liam
865a0186b6 caches: make critical reclamation less eager and possible in more cases 2024-02-11 13:41:13 -05:00
liamwhite
98db796fde
Merge pull request #12986 from t895/input-config-clear-fix
config: Always delete control settings in ClearControlPlayerValues
2024-02-11 12:24:18 -05:00
t895
adebc96a9c config: Always delete control settings in ClearControlPlayerValues 2024-02-11 07:35:54 -05:00
liamwhite
564a65a82e
Merge pull request #12981 from lat9nq/tzdb-asan-custom
tzdb_to_nx: Update to latest
2024-02-10 22:42:47 -05:00
liamwhite
501ff2eda5
Merge pull request #12980 from merryhime/race-me
dynarmic: Fix invalidation race
2024-02-10 22:42:42 -05:00
Charles Lombardo
999ec5739d
Merge pull request #12978 from liamwhite/ffs-qcom
host_shaders: add vendor workaround for adreno drivers
2024-02-10 22:42:25 -05:00
lat9nq
68b2db21b1 tzdb_to_nx: Update to latest
Includes memory leak fix.

Includes option to specify a custom zoneinfo dir.
2024-02-10 17:45:18 -05:00
liamwhite
2337397a15
Merge pull request #12969 from german77/bcat-interface
service: bcat: Migrate and refractor service to new IPC
2024-02-10 16:00:43 -05:00
liamwhite
7c56ecca3f
Merge pull request #12949 from liamwhite/multi-wait
service: add os types and multi wait API
2024-02-10 16:00:34 -05:00
Merry
211544fbc8 externals: Update dynarmic to 6.6.3 2024-02-10 19:40:47 +00:00
Liam
4677fd3f64 am: use applet program loading for tested versions 2024-02-10 12:38:19 -05:00
Liam
4eeac731ff host_shaders: add vendor workaround for adreno drivers 2024-02-10 12:02:37 -05:00
Fernando Sahmkow
9ce43ee677 Texture Cache: Fix untracking on GPU remap 2024-02-10 14:49:49 +01:00
Narr the Reg
816d03f7d9 service: bcat: Address review issues 2024-02-10 00:23:23 -06:00
Narr the Reg
909f7eb3d2 service: bcat: Implement news interfaces 2024-02-10 00:23:22 -06:00
Narr the Reg
7c2e9a6596 service: bcat: Migrate and refractor service to new IPC 2024-02-10 00:23:22 -06:00
Kevnkkm
fe6934593f
Fix multiplayer player count color in dark themes | Temp fix until #12744: Add green color for counts > 0 and < max_players - 1 (#12930)
* fix intended player count color in dark themes

* Refactor

* Change to green color for white and dark themes

* Add const to the colors and extra name for green color
2024-02-09 18:45:11 -06:00
Narr the Reg
52c8adc7ed
Merge pull request #12951 from liamwhite/more-ipc
ipc: additional fixes
2024-02-09 10:51:03 -06:00
liamwhite
7ec7ff0f30
Merge pull request #12920 from t895/jni-common
android: Move JNI setup and helpers to common
2024-02-09 11:49:25 -05:00
liamwhite
a133eadf06
Merge pull request #12927 from german77/cheat-pause
dmnt: cheat: Add pause and resume support
2024-02-09 11:47:34 -05:00
liamwhite
89dd0fa932
Merge pull request #12968 from t895/thermal-status
android: Thermal throttling indicator
2024-02-09 11:47:17 -05:00
liamwhite
a9dcfe2a42
Merge pull request #12964 from t895/foreground-service-test
android: Remove foreground service
2024-02-09 11:47:11 -05:00
liamwhite
2ad8d614b5
Merge pull request #12966 from german77/free_npad
service: hid: Free npad applet resource
2024-02-09 11:47:05 -05:00
Liam
b206ea5cfe am: fix focus states and display of indirect keyboard 2024-02-09 09:20:53 -05:00
Liam
70590f79f8 am: stub SetMediaPlaybackState for self controller 2024-02-09 09:20:53 -05:00
Liam
fa12384350 general: add default configurations for applet mode 2024-02-09 09:20:53 -05:00
Liam
78aac6b403 gpu: dependency-inject scaling/antialiasing filter state for capture layers 2024-02-09 09:20:53 -05:00
Liam
0cb413c3d3 nvnflinger/gpu: implement applet capture 2024-02-09 09:20:53 -05:00
Liam
962c82540c nvnflinger/gpu: implement blending 2024-02-09 09:20:53 -05:00
Liam
06fd7f2012 nvservices: unmap only on last container free 2024-02-09 09:20:53 -05:00
Liam
0cbb555e9a video_core: defensively program around unmapped device pointers 2024-02-09 09:20:53 -05:00
Liam
2e8c21ad2d core: fix multiprocess with nce 2024-02-09 09:20:53 -05:00
t895
f44183db9e android: Use utility function for applying view margins 2024-02-09 07:07:06 -05:00
t895
5fa9bc192c android: Add thermal throttling overlay 2024-02-09 07:07:05 -05:00
liamwhite
f9a559d2b7
Merge pull request #12967 from german77/let_me_out
service: Fix OutLargeData attributes
2024-02-08 21:33:22 -05:00
t895
af87365672 android: Remove foreground service 2024-02-08 21:04:14 -05:00
Narr the Reg
03a23c037a service: Fix OutLargeData attributes 2024-02-08 19:40:06 -06:00
Narr the Reg
0ac777460d service: hid: Free npad applet resource 2024-02-08 18:50:54 -06:00
liamwhite
71e59bdcd8
Merge pull request #12963 from t895/versioning-fix
android: Fix regex for git version
2024-02-08 17:03:32 -05:00
t895
0a1283f94f android: Fix regex for git version 2024-02-08 14:24:15 -05:00
t895
2600ac65c8 android: Run OnEmulationStarted frontend callback in another thread
The JVM has problems with attaching to a Fiber so we start a new thread and wait for the result here.
2024-02-08 14:13:46 -05:00
t895
c8e8c614a0 common: fs: Expand android macros 2024-02-08 14:13:46 -05:00
t895
e7c4c8b993 android: Move JNI setup and helpers to common 2024-02-08 13:45:26 -05:00
FearlessTobi
7cfb51e5e7 shared_translation: Add tooltips for general settings 2024-02-08 18:13:22 +01:00
Fernando S
f049453dd6
Merge pull request #12903 from liamwhite/const-offset
shader_recompiler: use only ConstOffset for OpImageFetch
2024-02-08 17:00:45 +01:00
liamwhite
cac37a6f6e
Merge pull request #12954 from german77/hidbus-interface
service: hid: Migrate hidbus to new interface
2024-02-08 11:00:11 -05:00
liamwhite
263dfa95e4
Merge pull request #12914 from FernandoS27/vc-refactor
VideoCore Refactor Part 1.
2024-02-08 10:59:59 -05:00
liamwhite
bc9711cb1e
Merge pull request #12953 from FernandoS27/zero-fps-mah-ass
SMMU: Ensure the backing address range matches the current
2024-02-08 10:59:52 -05:00
Narr the Reg
b4d88a7bb4 service: hid: Migrate hidbus to new interface 2024-02-07 18:07:32 -06:00
Fernando Sahmkow
ae833aa9c0 SMMU: Ensure the backing address range matches the current 2024-02-07 23:47:42 +01:00
liamwhite
4463ded603
Merge pull request #12939 from german77/wonder
dmnt: cheat: Invalidate cache on memory writes
2024-02-07 15:33:44 -05:00
liamwhite
159dec01ee
Merge pull request #12932 from german77/any-key-is-good
yuzu: Make controller keys easier to assign
2024-02-07 15:33:39 -05:00
liamwhite
6319bafafa
Merge pull request #12912 from FearlessTobi/ports-feb-24
Port some small changes from Citra (web_backend and translations)
2024-02-07 15:33:28 -05:00
Charles Lombardo
c000a5ff09
Merge pull request #12909 from t895/play-store-automation
ci: android: Play store publishing setup
2024-02-07 15:32:42 -05:00
Liam
fee263c59c ipc: additional fixes 2024-02-07 15:06:15 -05:00
Liam
5a64a77df3 glue: use multi wait API 2024-02-07 12:15:01 -05:00
Liam
6810929f6a server_manager: use multi wait API 2024-02-07 12:15:01 -05:00
Liam
9404633bfd service: add os types and multi wait API 2024-02-07 12:14:46 -05:00
german77
12f86f89fc yuzu: Make controller keys easier to assign 2024-02-06 16:51:39 -06:00
Narr the Reg
9858ea79fb dmnt: cheat: Invalidate cache on memory writes 2024-02-06 13:49:48 -06:00
FearlessTobi
2c357c929c shared_translation: Add tooltips for advanced graphics and system settings 2024-02-06 16:42:57 +01:00
FearlessTobi
482e203d5c shared_translation: Add tooltips for core and graphics settings 2024-02-06 16:29:13 +01:00
liamwhite
c10e720ba9
Merge pull request #12883 from FernandoS27/memory_manager_mem
MemoryManager: Reduce the page table size based on last big page address.
2024-02-06 10:25:03 -05:00
liamwhite
5016de3626
Merge pull request #12928 from german77/motion-mp
service: hid: Add multiprocess support to six axis input
2024-02-06 10:24:46 -05:00
liamwhite
d5fb9fd12c
Merge pull request #12933 from german77/irs-interface
service: irs: Migrate service to new interface
2024-02-06 10:24:30 -05:00
liamwhite
c79b3af610
Merge pull request #12934 from german77/hid_debug_interface
service: hid: Migrate hid debug service to new interface
2024-02-06 10:24:20 -05:00
FearlessTobi
c0a383d960 web_backend: Fix compilation 2024-02-06 15:48:04 +01:00
german77
b6106604c4 service: hid: Migrate hid debug service to new interface 2024-02-06 00:38:46 -06:00
german77
12b6162852 service: irs: Migrate service to new interface 2024-02-06 00:14:16 -06:00
german77
8f192b494a service: hid: Add multiprocess support to six axis input 2024-02-05 17:19:31 -06:00
german77
372897aac4 service: hid: Ensure aruid data is initialized 2024-02-05 17:17:21 -06:00
Fernando Sahmkow
fa47ac1c9f Common: Rename SplitRangeSet to OverlapRangeSet 2024-02-05 23:01:17 +01:00
german77
c52d7cc694 dmnt: cheat: Add pause and resume support 2024-02-05 14:38:26 -06:00
Charles Lombardo
a2f23746c2
Merge pull request #12905 from liamwhite/hwc-release
nvnflinger: release buffers before presentation sleep
2024-02-05 13:43:22 -05:00
Charles Lombardo
215b13f2a2
Merge pull request #12924 from liamwhite/pedantic-unsigned
typed_address: test values are unsigned
2024-02-05 13:43:06 -05:00
liamwhite
35ed9425d7
Merge pull request #12925 from german77/linux-tab
yuzu: Fully hide linux tab
2024-02-05 13:41:31 -05:00
liamwhite
74cc8721c7
Merge pull request #12915 from german77/cheat
dmnt: cheats: Update cheat vm to latest version
2024-02-05 13:41:21 -05:00
liamwhite
8ef1db78b0
Merge pull request #12916 from liamwhite/float-fix
gdb: fix load/save of fp values in a32
2024-02-05 13:41:15 -05:00
Charles Lombardo
18c8f10ff2
Merge pull request #12922 from FearlessTobi/lang-mappins
.tx/config: Use language mappings for android "tx pull"
2024-02-05 13:40:53 -05:00
german77
96d881f087 yuzu: Fully hide linux tab 2024-02-05 11:58:20 -06:00
Liam
0e950baf41 typed_address: test values are unsigned 2024-02-05 12:47:10 -05:00
german77
8113f55f4b dmnt: cheats: Silence memory errors 2024-02-05 11:08:24 -06:00
Liam
f296a9ce9a shader_recompiler: use only ConstOffset for OpImageFetch 2024-02-05 12:01:09 -05:00
FearlessTobi
ddbefc71cb .tx/config: Use language mappings for android "tx pull"
The language names we are using in the android resources differ from those on Transifex.

We need to manually specify mappings for them, so Transifex is able to place the files in the correct folders.
2024-02-05 15:57:13 +01:00
Fernando Sahmkow
0d5a3abeae Buffer Cache: Refactor to use Range sets instead 2024-02-05 11:06:52 +01:00
Liam
85143e8376 gdb: fix load/save of fp values in a32 2024-02-04 20:28:43 -05:00
german77
504abbd6e0 dmnt: cheats: Update cheat vm to latest version 2024-02-04 17:46:20 -06:00
Fernando Sahmkow
accccc0cbf NVDRV: Refactor HeapMapper to use RangeSets 2024-02-04 20:01:50 +01:00
Fernando Sahmkow
01ba6cf610 Common: Introduce Range Sets 2024-02-04 20:01:50 +01:00
Fernando Sahmkow
4841dc0b74 VideoCore: Move Slot Vector to Common 2024-02-04 20:01:47 +01:00
Tobias
185125e4e4 citra_qt/configure_ui: Show country of language in the combobox
This prevents an issue where we had seperate versions of the same language for different regions and they were not distinguishable (e.g. "Chinese (China)" and "Chinese (Taiwan)").

Also makes it so we do not need to hardcode specific languages anymore.
2024-02-04 17:06:44 +01:00
t895
99ea31faa8 ci: android: Play store publishing setup 2024-02-04 10:54:18 -05:00
FearlessTobi
9ade941de1 web_backend: Sync with Citra implementation
While porting https://github.com/citra-emu/citra/pull/7347, I noticed the code of yuzu was not up-to-date with the implementation from Citra.
2024-02-04 16:51:52 +01:00
liamwhite
4cccbe7989
Merge pull request #12892 from liamwhite/serialization-stuff
cmif_serialization: enforce const for references
2024-02-04 09:48:33 -05:00
Liam
5eb5c96750 nvnflinger: release buffers before presentation sleep 2024-02-03 17:14:43 -05:00
liamwhite
5da55cbac9
Merge pull request #12901 from Kelebek1/timezone_firmware_fix
Fix firmware timezone boot load check.
2024-02-03 11:10:30 -05:00
liamwhite
81cc4df1f9
Merge pull request #12895 from german77/files
service: fs: Skip non user id folders
2024-02-03 11:10:24 -05:00
liamwhite
25f3d358b1
Merge pull request #12877 from german77/npad-fixed
service: hid: Multiple fixes
2024-02-03 11:10:14 -05:00
liamwhite
a3c8bb251d
Merge pull request #12852 from Calinou/multiplayer-color-player-counts
Color player counts in the multiplayer public lobby list
2024-02-03 11:10:00 -05:00
liamwhite
327533be1f
Merge pull request #12851 from Calinou/multiplayer-persist-filters
Persist filters in multiplayer public lobby list
2024-02-03 11:09:51 -05:00
liamwhite
61ea2115c7
Merge pull request #12850 from Calinou/multiplayer-add-hotkeys
Add hotkeys for multiplayer actions
2024-02-03 11:09:41 -05:00
Kelebek1
108a72ea8a Fix firmware timezone boot load check. 2024-02-03 15:21:10 +00:00
Narr the Reg
fb3ef957bb service: fs: Skip non user id folders 2024-02-02 13:25:38 -06:00
Liam
78f72b3bf5 cmif_serialization: enforce const for references 2024-02-02 09:32:10 -05:00
Fernando S
6baf965777
Merge pull request #12857 from liamwhite/const
service: use const references for input raw data
2024-02-02 15:10:46 +01:00
Fernando S
3f86b339f3
Merge pull request #12845 from liamwhite/notif
notif: rewrite for new IPC
2024-02-02 15:09:57 +01:00
liamwhite
32d38a5df6
Merge pull request #12887 from abouvier/cmake-vulkan-headers
cmake: use vulkan-headers config file
2024-02-02 09:09:02 -05:00
liamwhite
3ac46aeced
Merge pull request #12885 from Moonlacer/eclipse-fix
structured_control_flow: Add Samsung Proprietary Driver ID to Reorder Pass
2024-02-02 09:08:54 -05:00
Fernando S
58cf2ee1f9
Merge pull request #12761 from liamwhite/mp-composite
video_core: rewrite presentation for layer composition
2024-02-02 15:08:06 +01:00
Alexandre Bouvier
c74b5f9ee6 cmake: use vulkan-headers config file 2024-02-02 04:38:56 +01:00
Moonlacer
11a8ef6640 Clang Fix 2024-02-01 18:15:21 -06:00
Moonlacer
b51b47e707 Add Samsung Proprietary Driver ID to Reorder Pass
For RDNA-based Samsung Xclipse GPUs
2024-02-01 17:53:26 -06:00
Liam
35e3c68028 service: use const references for input raw data 2024-02-01 12:57:54 -05:00
Narr the Reg
818721d12d service: hid: Multiple fixes 2024-02-01 10:37:44 -06:00
liamwhite
3212bf5294
Merge pull request #12878 from zhaobot/tx-update-20240201020554
Update translations (2024-02-01)
2024-02-01 11:34:21 -05:00
liamwhite
d49275f0e7
Merge pull request #12875 from FernandoS27/sw-blitter
SwBlitter: Fix Pitch linear reading/writting
2024-02-01 11:34:06 -05:00
liamwhite
c9ff4b9de4
Merge pull request #12848 from german77/caps-interface
service: capsrv: Migrate to new IPC
2024-02-01 11:33:55 -05:00
liamwhite
21138b6a86
Merge pull request #12780 from german77/touch_resource5
service: hid: Fully implement touch resource
2024-02-01 11:33:44 -05:00
Fernando Sahmkow
f740d8b9be MemoryManager: Reduce the page table size based on last big page address. 2024-02-01 13:00:36 +01:00
The yuzu Community
d4ac84d50d Update translations (2024-02-01) 2024-02-01 02:06:09 +00:00
Fernando Sahmkow
5cb9fe7819 SwBlitter: Fix Pitch linear reading/writting 2024-01-31 23:02:10 +01:00
liamwhite
c98d0e185f
Merge pull request #12870 from liamwhite/mac-ci
ci: bump mac to macos-14
2024-01-31 11:52:27 -05:00
Liam
2c421a7046 hardware_composer: implement speed limit extensions 2024-01-31 11:27:21 -05:00
Liam
a595e9e8a7 nvnflinger/gpu: implement layer stack composition 2024-01-31 11:27:21 -05:00
Liam
10cf058518 renderer_opengl: implement layer stack composition 2024-01-31 11:27:21 -05:00
Liam
9bdf09bd76 renderer_vulkan: implement layer stack composition 2024-01-31 11:27:21 -05:00
Liam
d4de04584f renderer_opengl: split up blit screen resources into antialias and window adapt passes 2024-01-31 11:27:21 -05:00
Liam
dd2918efd8 renderer_opengl: move out ownership of FSR resources 2024-01-31 11:27:21 -05:00
Liam
2ed9586130 renderer_vulkan: convert FSR to graphics pipeline 2024-01-31 11:27:21 -05:00
Liam
b78900e956 renderer_opengl: move out FSR shader source construction 2024-01-31 11:27:20 -05:00
Liam
60ee29aac3 renderer_opengl: split out FXAA 2024-01-31 11:27:20 -05:00
Liam
b90eff4bc6 renderer_opengl: split out SMAA 2024-01-31 11:27:20 -05:00
Liam
0c2e5b64c9 renderer_vulkan: split up blit screen resources into separate antialias and window adapt passes 2024-01-31 11:27:20 -05:00
Liam
9568b310be renderer_vulkan: isolate FXAA from blit screen 2024-01-31 11:27:20 -05:00
Liam
2b1dd3bef5 renderer_opengl: isolate core presentation code 2024-01-31 11:27:20 -05:00
Liam
453091f611 video_core: consistently account for resolution scaling when rendering 2024-01-31 11:27:20 -05:00
Liam
80de01a5b4 video_core: simplify accelerated surface fetch and crop handling between APIs 2024-01-31 11:27:20 -05:00
Narr the Reg
7cc7d027f7
Merge pull request #12760 from liamwhite/mp-am
am: rewrite for multiprocess support
2024-01-31 10:25:28 -06:00
Narr the Reg
12e5293c73
Merge pull request #12858 from liamwhite/non-blocking
internal_network: only poll for accept on blocking sockets
2024-01-31 10:24:30 -06:00
liamwhite
22492b68b7
Merge pull request #12869 from FernandoS27/smmu-fixes
SMMU: A set of different fixes.
2024-01-31 11:22:29 -05:00
liamwhite
a12a26e19b
Merge pull request #12864 from Kelebek1/small_time_fixes
Small time fixes
2024-01-31 11:22:16 -05:00
liamwhite
2a2a1d98b3
Merge pull request #12868 from t895/engine-per-game
settings: Allow audio sink, input, and output to be set per game
2024-01-31 11:22:04 -05:00
liamwhite
6e92a7a149
aoc: fix DLC listing (#12867) 2024-01-31 17:21:34 +01:00
Liam
4dfe9dd038 ci: bump mac to macos-14 2024-01-31 11:17:09 -05:00
Fernando Sahmkow
d57165df45 Device Memory Manager: ensure raster protection only within mapped device addresses. 2024-01-31 16:38:51 +01:00
Fernando Sahmkow
738e9a79a0 DeviceMemory: Make counter types configurable 2024-01-31 16:38:51 +01:00
Fernando Sahmkow
aaab11e36f NVDRV: Join the heaper optimization blocks 2024-01-31 16:38:51 +01:00
Liam
8f848f43e9 smmu: use new range mutex construction for protecting counters 2024-01-31 16:38:51 +01:00
Fernando Sahmkow
a7c1306e2d Texture Cache: make sparse texture table per channel 2024-01-31 16:38:51 +01:00
t895
e8be665f11 settings: Allow audio sink, input, and output to be set per game 2024-01-31 09:31:19 -05:00
Kelebek1
9ed82a280e Remove a few hacks for clock setups, which seem to no longer be needed, but fix network clock to local clock on every boot. Also fix some logging strings. 2024-01-31 01:41:59 +00:00
Liam
817d916233 am: push storage from error applet with non-zero size 2024-01-30 20:13:48 -05:00
liamwhite
ffe3984353
Merge pull request #12860 from liamwhite/serialization2
cmif_serialization: fix LargeData types
2024-01-30 14:29:41 -05:00
liamwhite
ec734cb06c
Merge pull request #12859 from german77/led
service: hid: Implement GetPlayerLedPattern accurately
2024-01-30 14:29:33 -05:00
Liam
8292ba7ad6 cmif_serialization: fix LargeData types 2024-01-30 12:26:32 -05:00
liamwhite
2e65616761
Merge pull request #12856 from liamwhite/serialization
cmif_serialization: fix out layout calculation
2024-01-30 11:59:00 -05:00
liamwhite
07aa1a99fa
Merge pull request #12849 from LotP1/patch-1
Add support for the CONNREFUSED socket error
2024-01-30 11:58:55 -05:00
liamwhite
6524f20de4
Merge pull request #12847 from abouvier/cmake-oaknut
cmake: prefer system oaknut library
2024-01-30 11:58:48 -05:00
Narr the Reg
a0f7f2b309 service: hid: Implement GetPlayerLedPattern accurately 2024-01-30 10:57:03 -06:00
Hugo Locurcio
442aad9b27
Persist filters in multiplayer public lobby list
After connecting to a room, the chosen filter text, "Games I Own",
"Hide Empty Rooms" and "Hide Full Rooms" values are persisted
to configuration so they are preserved across restarts.

This makes it easier to rejoin a room if you regularly play the same
game, or after a crash.
2024-01-30 17:40:29 +01:00
Hugo Locurcio
8e0f97ac96
Color player counts in the multiplayer public lobby list
- Full lobbies have their player count displayed in red.
- Lobbies with one slot left have their player count displayed in orange.
- Empty lobbies have their player count grayed out.
2024-01-30 17:38:21 +01:00
Liam
5510b31972 internal_network: only poll for accept on blocking sockets 2024-01-30 10:29:05 -05:00
LotP1
ecea5ef757
Update sockets.h
forgot to realign the enum
2024-01-30 12:24:47 +01:00
LotP1
a1ce45b0b1
Update src/core/hle/service/sockets/sockets.h
Co-authored-by: liamwhite <liamwhite@users.noreply.github.com>
2024-01-30 11:01:04 +01:00
Liam
9ba9780a96 cmif_serialization: fix out layout calculation 2024-01-30 02:22:45 -05:00
Narr the Reg
4afca6bf5d service: capsrv: Migrate to new IPC 2024-01-29 20:35:45 -06:00
Alexandre Bouvier
73e7a259fd cmake: prefer system oaknut library 2024-01-30 02:57:50 +01:00
Liam
8e0a40434c am: stop emulation when all applets are closed 2024-01-29 20:17:33 -05:00
Liam
68303ed601 core: support offline web applet 2024-01-29 20:17:33 -05:00
Liam
8a146469c0 am: return AppletDataBroker and use for frontend applets 2024-01-29 20:17:33 -05:00
Liam
b1c2f791af am: rework IStorage for transfer storage 2024-01-29 20:17:33 -05:00
Liam
182137a9a4 am: migrate global state to per-applet state structure 2024-01-29 20:17:33 -05:00
Liam
3155f4e96d am: retrieve main applet creation info from frontend 2024-01-29 20:17:09 -05:00
Hugo Locurcio
345d691328
Add hotkeys for multiplayer actions
Default shortcuts were chosen as to be intuitive (use the first letter
of the action, or the second word's first letter) and work on all
types of keyboards. The hotkeys can be used while playing a game too,
as they are application-wide.
2024-01-30 01:32:14 +01:00
Liam
dfb9fa0144 am: re-namespace frontend applets to frontend directory 2024-01-29 18:43:45 -05:00
Liam
a7e9d7842d am: add new datatypes for per-applet state 2024-01-29 18:43:45 -05:00
Liam
7de6b41030 service: split am into components 2024-01-29 18:43:45 -05:00
LotP1
2cc5c517cf
Update sockets_translate.cpp
Align the error case with it's index in the Errno enum
2024-01-30 00:34:07 +01:00
LotP1
c0775e74ec
Update sockets.h
Add the CONNREFUSED error to the Service::Sockets::Errno enum
2024-01-30 00:27:11 +01:00
LotP1
3acf35bb98
Update sockets_translate.cpp
Add support for the CONNREFUSED Errno.
Without this Connect() will return SUCCESS when a connection is refused, instead of an error code. This causes code, that relies on the result of Connect() being SUCCESS, to execute when it shouldn't.
2024-01-30 00:23:43 +01:00
liamwhite
8ddfecfbae
Merge pull request #12846 from german77/mii_const
service: mii: Set arguments as const
2024-01-29 15:27:12 -05:00
liamwhite
51f5a6f1f8
Merge pull request #12830 from merryhime/dynamic-dual_code_block
externals/dynarmic: Update to 6.6.1
2024-01-29 15:27:04 -05:00
Narr the Reg
64fca24b32 service: mii: Set arguments as const 2024-01-29 11:22:44 -06:00
Liam
41149d061d notif: rewrite for new IPC 2024-01-29 11:56:32 -05:00
liamwhite
ba4cee1812
Merge pull request #12843 from t895/system-driver-whoops
android: Don't show delete button for system driver
2024-01-29 09:09:38 -05:00
liamwhite
06abf3205a
Merge pull request #12837 from german77/cat
service: am: Focus state changed goes last
2024-01-29 09:09:00 -05:00
liamwhite
adfdc9520a
Merge pull request #12836 from german77/im_home
service: hid: Implement home, capture and sleep buttons
2024-01-29 09:08:52 -05:00
liamwhite
90cb852908
Merge pull request #12814 from Kelebek1/time_new_ipc
Move time services to new IPC and add debug printing
2024-01-29 09:08:46 -05:00
liamwhite
278dd589ec
Merge pull request #12439 from FireBurn/vkresult
Simplify VkResult lookup
2024-01-29 09:08:32 -05:00
t895
15e8791f9d android: Don't show delete button for system driver 2024-01-29 06:59:34 -05:00
Narr the Reg
498c9bd96a
Merge pull request #12840 from amazingfate/fix-gcc11
fix build for gcc 11
2024-01-29 04:36:57 -06:00
amazingfate
6c8df6af44 fix build for gcc 11 2024-01-29 14:00:56 +08:00
german77
8e93537266 service: am: Focus state changed goes last 2024-01-28 22:02:01 -06:00
german77
b8f16f3538 service: hid: Implement home, capture and sleep buttons 2024-01-28 19:28:37 -06:00
german77
87e26de0fc service: hid: Restore active aruid 2024-01-28 18:27:25 -06:00
Narr the Reg
575183d6dc service: hid: Fully implement touch resource 2024-01-28 18:27:25 -06:00
liamwhite
6a2532fe17
Merge pull request #12555 from flodavid/fix-gamemode-setting
Save gamemode configuration and add per-game config
2024-01-28 15:02:34 -05:00
liamwhite
3655115105
Merge pull request #12821 from merryhime/atomic_ops
atomic_ops: Reduce code duplication with templates
2024-01-28 15:02:28 -05:00
liamwhite
5561a08d59
Merge pull request #12831 from Kelebek1/audren_multi
Use the input process handle to get the correct application's memory
2024-01-28 15:02:22 -05:00
liamwhite
e687ca8735
Merge pull request #12833 from merryhime/vsync-crash
configure_graphics: Avoid crash when vsync_mode_combobox is empty
2024-01-28 15:02:15 -05:00
Merry
0bf46cb1ee configure_graphics: Avoid crash when vsync_mode_combobox is empty (occurs when renderer backend is Null) 2024-01-28 19:14:38 +00:00
Kelebek1
19a2f12692 Use the input process handle to get the correct application's memory 2024-01-28 18:51:43 +00:00
Merry
6cc82fd430 externals/dynarmic: Update to 6.6.1 2024-01-28 17:04:01 +00:00
liamwhite
72c897c49d
Merge pull request #12826 from t895/system-driver-version
android: Show system driver information
2024-01-28 11:57:58 -05:00
liamwhite
077a50a547
Merge pull request #12825 from liamwhite/why
kernel: clear pinned waiter list on unpin
2024-01-28 11:57:53 -05:00
liamwhite
820f1c8a16
Merge pull request #12823 from german77/set-audio
service: set: Implement more Qlaunch Settings
2024-01-28 11:57:47 -05:00
liamwhite
b163757e1f
Merge pull request #12802 from german77/mii_interface
service: mii: Migrate service to new interface
2024-01-28 11:57:40 -05:00
Merry
2bc0132d0c externals/oaknut: Update to 2.0.1 2024-01-28 16:50:14 +00:00
german77
b75401a2cb service: set: Increase settings version 2024-01-28 09:32:54 -06:00
german77
12e7ee2357 service: set: Implement more Qlaunch Settings 2024-01-28 09:32:46 -06:00
Charles Lombardo
3ec41503e3
Merge pull request #12827 from t895/focus-color
android: Disable focus on loading card
2024-01-28 08:52:57 -05:00
t895
c770af9b12 android: Disable focus on loading card
Additionally de-emphasize the ripple that I can't disable
2024-01-28 00:25:07 -05:00
t895
2d8f80b65e android: Show system driver information 2024-01-27 23:59:02 -05:00
Liam
6c4eb2733d kernel: clear pinned waiter list on unpin 2024-01-27 22:53:49 -05:00
liamwhite
d5e8c9d04f
Merge pull request #12824 from t895/multi-boot
android: Multi-program app switching
2024-01-27 21:48:54 -05:00
t895
3f1290cee3 android: Multi-program app switching 2024-01-27 20:05:51 -05:00
Merry
5a20d07c21 atomic_ops: Fix MSVC 2024-01-27 21:42:16 +00:00
Merry
9f91d310c6 atomic_ops: Remove volatile qualifier 2024-01-27 21:36:39 +00:00
Merry
6527c0d2fc atomic_ops: Reduce code duplication with templates
Also fixes builds on unusual toolchains where:
- u32 is unsigned int
- u64 is unsigned long long
- uintptr_t is unsigned long
2024-01-27 21:12:12 +00:00
liamwhite
ce2eb6e8ee
Merge pull request #12818 from K900/small-fixes
A few small fixes
2024-01-27 12:13:46 -05:00
K900
8b47465586 input: add a missing null pointer check
There's a few other places where the result of GetAruidData is accessed without a null check,
but I couldn't find a code path that hits those.
2024-01-27 17:32:49 +03:00
K900
3065ab0fd8 nx_tzdb: add another safety assertion 2024-01-27 17:28:04 +03:00
K900
a2407a2964 nx_tzdb: check for unpacked directory
Otherwise things get funny if the archive is downloaded, but the unpacking was interrupted.
2024-01-27 17:25:52 +03:00
liamwhite
16b79df836
Merge pull request #12815 from t895/visual-driver-silly
android: Reload global settings on closing emulation
2024-01-27 01:36:26 -05:00
t895
6a4b25699d android: Reload global settings on closing emulation
UI like the driver manager expects the global settings to be loaded when in the MainActivity so we reload global config to properly reset state on exit.
2024-01-26 23:05:02 -05:00
Kelebek1
da410506a4 Move time services to new IPC.
Add some fixes/improvements to usage with the new IPC
2024-01-27 03:30:09 +00:00
Narr the Reg
c5e88c654e service: mii: Migrate service to new interface 2024-01-26 10:43:34 -06:00
liamwhite
bd8635e26a
Merge pull request #12808 from t895/uri-moment
vfs: Fix getting URI filename
2024-01-26 10:23:08 -05:00
liamwhite
4349cdba07
Merge pull request #12769 from german77/no-log
core: hid: Reduce controller requests
2024-01-26 09:57:40 -05:00
t895
f2fb761bac vfs: Fix getting URI filename 2024-01-26 09:57:22 -05:00
liamwhite
59aee2b461
Merge pull request #12809 from t895/error-message
android: Add cancel condition to installed content check
2024-01-26 09:56:01 -05:00
liamwhite
4d206d849e
Merge pull request #12765 from german77/sys-hid
service: set: Implement more settings functions for Qlaunch
2024-01-26 09:55:47 -05:00
liamwhite
744c0173d1
Merge pull request #12801 from german77/vibration-fix
service: hid: Don't try to vibrate if device isn't initialized
2024-01-26 09:55:37 -05:00
liamwhite
55482ab5dc
Merge pull request #12707 from FearlessTobi/fs-housekeeping
fs: Various cleanups & add path class for later use
2024-01-26 09:55:25 -05:00
t895
e56b44dee6 android: Add cancel condition to installed content check 2024-01-26 09:29:51 -05:00
Narr the Reg
f2012e5aff service: hid: Don't try to vibrate if device isn't initialized 2024-01-25 23:46:46 -06:00
liamwhite
4526fdaf64
Merge pull request #12796 from t895/controller-optimizations
android: Controller focus optimizations
2024-01-25 23:01:44 -05:00
liamwhite
bc22b4e782
Merge pull request #12798 from liamwhite/cmif-fixes
cmif_serialization: fixes
2024-01-25 23:01:10 -05:00
liamwhite
f70821ce0d
Merge pull request #12794 from abouvier/cmake-simpleini-module
cmake: support simpleini config and pc file
2024-01-25 23:01:04 -05:00
Liam
a774ff935c cmif_serialization: support non-domain sessions on domain servers 2024-01-25 22:18:42 -05:00
Liam
431df5ae93 cmif_types: improve ergonomics of types 2024-01-25 22:18:37 -05:00
t895
677c2c2cd2 android: Disable default focus highlight on views that shouldn't be selected 2024-01-25 20:49:57 -05:00
t895
ee540c712c android: Allow controller to focus on toolbar menu items
Workaround for this
https://issuetracker.google.com/issues/256948272
2024-01-25 20:48:58 -05:00
t895
d23c4393fd android: Add 600dp layout for GameInfoFragment 2024-01-25 20:46:03 -05:00
t895
b24a111136 android: Fix button click listener for build version name
Was set to the text instead of the parent view by mistake
2024-01-25 20:43:12 -05:00
t895
91636deaaf android: Disable focus for the root of cards that contain buttons 2024-01-25 20:42:23 -05:00
t895
68cbf67f4c android: Focus on the in game menu when opened 2024-01-25 20:39:52 -05:00
Alexandre Bouvier
645961613f cmake: support simpleini cmake config and pc file 2024-01-26 01:13:47 +01:00
Narr the Reg
53b321c945 service: set: Implement more settings functions for Qlaunch 2024-01-25 17:14:18 -06:00
FearlessTobi
975deb7528 Address review comments and fix compilation problems 2024-01-25 16:43:53 -05:00
FearlessTobi
2c049ae06d fs: Add path class 2024-01-25 16:42:06 -05:00
FearlessTobi
54372fdff5 result: Make fully constexpr, add ON_RESULT_INCLUDED 2024-01-25 16:42:06 -05:00
FearlessTobi
c60ab6bbf6 fs/errors: Unify naming of result codes 2024-01-25 16:42:06 -05:00
FearlessTobi
cc09c265e1 fs: Replace Mode enum by OpenMode enum 2024-01-25 16:42:05 -05:00
FearlessTobi
0f9288e38d vfs: Move vfs files to their own directory 2024-01-25 16:40:42 -05:00
FearlessTobi
06fb7f90da fs: Move fsp_srv subclasses to separate files
fs: Move additional files to the fsp directory
2024-01-25 16:40:42 -05:00
liamwhite
e04368ad7c
Merge pull request #12759 from liamwhite/mp-misc
core: miscellaneous fixes
2024-01-25 16:21:38 -05:00
liamwhite
3e2d3548f2
Merge pull request #12777 from t895/firmware-warning
android: Add key warning
2024-01-25 16:21:29 -05:00
liamwhite
eb9036d75b
Merge pull request #12783 from liamwhite/cmif-generation
service: add template serializer for method calls
2024-01-25 15:40:09 -05:00
Liam
01a2d978eb service: add template serializer for method calls 2024-01-25 14:35:51 -05:00
liamwhite
6e67b25af9
Merge pull request #12787 from t895/game-list-refresh
android: Only compare game contents for GameAdapter
2024-01-25 14:19:32 -05:00
liamwhite
e91667ba75
Merge pull request #12786 from t895/driver-overlay
android: Show driver vendor in FPS overlay
2024-01-25 14:19:25 -05:00
liamwhite
d45561ace0
Merge pull request #12499 from Kelebek1/time
Rework time services
2024-01-25 14:19:01 -05:00
t895
0fdd6e8934 android: Fix waiting for driver install on startup 2024-01-25 13:04:04 -05:00
t895
35794f4f18 android: Add current driver vendor to FPS overlay 2024-01-25 13:04:03 -05:00
t895
b8be8dff69 android: Add key check 2024-01-25 12:58:19 -05:00
t895
bc317a9807 android: Add option to make MessageDialogFragments non-dismissible
Additionally fixes an issue where its viewmodel could hold onto a stale positive action
2024-01-25 12:53:49 -05:00
t895
97ca160b08 frontend_common: Consistently use references
Was swapping between references and pointers for no reason. Just unify them here since each of these utility functions will need their parameters to be alive.
2024-01-25 12:53:49 -05:00
t895
1a3fc3724a frontend_common: Remove key rederivation and keep key check 2024-01-25 12:53:48 -05:00
t895
7b01454d5f android: Only compare game contents for GameAdapter 2024-01-25 08:04:59 -05:00
Matías Locatti
f3749394ac
Merge pull request #12781 from goldenx86/dozen
Demote dozen to the bottom of the device list
2024-01-25 03:58:09 -03:00
Matías Locatti
807f421752 Demote Mesa dozen to the bottom of the device list 2024-01-24 23:36:14 -03:00
Kelebek1
e4915fb7d2 Rework time service to fix time passing offline. 2024-01-24 04:26:55 +00:00
liamwhite
a76f6a2775
Merge pull request #12763 from liamwhite/fix-hbl-again
loader: also register fs process for raw exefs partition
2024-01-23 13:31:41 -05:00
liamwhite
ba518f6899
Merge pull request #12768 from german77/wrong_conversion
service: properly convert buffers to strings
2024-01-23 13:31:27 -05:00
Narr the Reg
ad4622da2c core: hid: Skip duplicated vibrations 2024-01-23 11:33:08 -06:00
Narr the Reg
3b1c2896d9 core: hid: Only set polling mode if needed 2024-01-23 11:11:09 -06:00
Narr the Reg
fc5d76e6e2 service: properly convert buffers to strings 2024-01-23 10:24:05 -06:00
Liam
5f9a45ada9 loader: also register fs process for raw exefs partition 2024-01-23 00:01:38 -05:00
Liam
a120f8ff4d nvservices: close map handles on session close 2024-01-22 21:18:52 -05:00
Liam
96833cd809 kernel: target invalidate to given process 2024-01-22 21:18:52 -05:00
Charles Lombardo
8649a80071
Merge pull request #12753 from liamwhite/why
device_memory_manager: fix ScratchBuffer indexing
2024-01-22 14:55:07 -05:00
Liam
550cadbee4 device_memory_manager: fix ScratchBuffer indexing 2024-01-22 14:07:33 -05:00
liamwhite
8bd10473d6
Merge pull request #12579 from FernandoS27/smmu
Core: Implement Device Mapping & GPU SMMU
2024-01-22 10:55:39 -05:00
liamwhite
8d708b0c79
Merge pull request #12747 from t895/homescreen-widget
android: Add to launcher button
2024-01-22 10:55:25 -05:00
t895
beaab10c8f android: Add to launcher button 2024-01-22 08:19:20 -05:00
Charles Lombardo
889c5d2705
Merge pull request #12739 from t895/debug-keystore
android: Provide debug.keystore for debug and relWithDebInfo builds
2024-01-22 04:34:17 -05:00
Charles Lombardo
17b0aac809
Merge pull request #12738 from t895/lock-drawer
android: Port "Lock drawer" feature from Citra
2024-01-22 04:34:08 -05:00
Charles Lombardo
399220ddbc
Merge pull request #12736 from t895/verify-contents
android: Add verify contents buttons
2024-01-22 04:33:56 -05:00
Mike Lothian
23e074ff14 Simplify VkResult lookup 2024-01-22 03:10:43 +00:00
t895
59080a3d1d android: Provide debug.keystore for debug and relWithDebInfo builds
Allows devs to share debug builds with testers without uninstalling the previous build
2024-01-21 22:08:07 -05:00
t895
3a25a217e6 android: Port "Lock drawer" feature from Citra 2024-01-21 20:47:28 -05:00
Mike Lothian
f854ffd015 Add Vulkan-Utility-Libraries dependency 2024-01-22 01:30:44 +00:00
t895
961b5586a5 frontend_common: Remove default value for installer callbacks
We never used these without callbacks and these will break without them in their current state. I could write the default value to return false always but that's unnecessary for now.
2024-01-21 19:31:26 -05:00
liamwhite
57ff934f0d
Merge pull request #12734 from german77/enable-applet
service: hid: Implement EnableAppletForInput
2024-01-21 19:15:53 -05:00
liamwhite
92ce9273ee
Merge pull request #12735 from german77/disable-vibration
core: hid: Allow to disable vibration
2024-01-21 19:15:46 -05:00
t895
dd36d43ea1 android: Add options to verify installed content 2024-01-21 19:15:11 -05:00
Narr the Reg
a7a7720752 core: hid: Allow to disable vibration 2024-01-21 16:44:31 -06:00
t895
c725f3c86c frontend_common: Move integrity verification to content_manager 2024-01-21 16:36:37 -05:00
Narr the Reg
1b984738ab service: hid: Implement EnableAppletForInput 2024-01-21 14:05:18 -06:00
Charles Lombardo
a3199401f4
Merge pull request #12733 from german77/settings_services
service: set: Don't allow invalid mii author id
2024-01-21 14:08:58 -05:00
german77
a7620a29be service: set: Don't allow invalid mii author id 2024-01-21 12:18:18 -06:00
Charles Lombardo
5ac1297fa5
Merge pull request #12728 from t895/sync-translations
android: Sync translations
2024-01-21 00:38:49 -05:00
t895
fe69105f71 android: Sync translations 2024-01-20 23:26:47 -05:00
liamwhite
93a3342841
Merge pull request #12720 from t895/return-to-global
android: Change "Clear" to "Use global setting" for per-game settings
2024-01-20 13:56:31 -05:00
t895
7b3e26acc9 android: Change "Clear" to "Use global setting" for per-game settings 2024-01-20 13:37:47 -05:00
liamwhite
444e86d191
Merge pull request #12688 from liamwhite/wl-present-fix
renderer_vulkan: recreate swapchain when frame size changes
2024-01-20 13:36:18 -05:00
liamwhite
61ce0088ae
Merge pull request #12724 from merryhime/fs-u8str-overloads
fs/file: Explicitly convert std::u8string to std::filesystem::path
2024-01-20 13:35:41 -05:00
liamwhite
b3aa3633c7
Merge pull request #12721 from t895/card-elevation
android: Use elevated card style for home setting card
2024-01-20 13:35:30 -05:00
liamwhite
627ba271ad
Merge pull request #12719 from t895/sort-search
android: Sort recently added/played games by time
2024-01-20 13:35:14 -05:00
liamwhite
2faa631676
Merge pull request #12715 from t895/remove-addons
android: Add uninstall addon button
2024-01-20 13:35:03 -05:00
liamwhite
5838779162
Merge pull request #12660 from german77/better-vibration
service: hid: Fully implement abstract vibration
2024-01-20 13:34:54 -05:00
liamwhite
23fd1041c1
Merge pull request #12701 from liamwhite/flinger-layer-issues
vi: check layer state before opening or closing
2024-01-20 13:34:32 -05:00
Merry
5c398ede6f fs/file: Explicitly convert std::u8string to std::filesystem::path 2024-01-20 17:46:30 +00:00
t895
378e4752a6 android: Use elevated card style for home setting card 2024-01-20 03:55:48 -05:00
t895
dad48f16b7 android: Sort recently added/played games by time 2024-01-20 03:18:48 -05:00
t895
a363fa78ef frontend_common: Add documentation for content_mananger 2024-01-19 20:54:50 -05:00
t895
03fa91ba3c android: Add addon delete button
Required some refactoring of retrieving patches in order for the frontend to pass the right information to ContentManager for deletion.
2024-01-19 20:54:50 -05:00
t895
d79d4d5986 android: Use callback to update progress bar dialogs 2024-01-19 17:09:36 -05:00
t895
ccd3dd842f frontend_common: Add content manager utility functions
Creates utility functions to remove/install DLC, updates, and base game content
2024-01-19 17:09:35 -05:00
liamwhite
b4a8e1ef8a
Merge pull request #12713 from shinra-electric/mvk-127
macOS: Bump MoltenVK to v1.2.7
2024-01-19 13:07:14 -05:00
shinra-electric
5ea8f05ec6
Bump MoltenVK to v1.2.7 2024-01-19 17:28:53 +01:00
liamwhite
10535e0016
Merge pull request #12687 from german77/amiibo-lock
core: hid: Disable special features before disconnecting the controllers
2024-01-19 09:33:31 -05:00
liamwhite
a8c552e261
Merge pull request #12695 from anpilley/user-arguments-v2
Allow -u to accept a username string in addition to index
2024-01-19 09:33:25 -05:00
liamwhite
932bd98824
Merge pull request #12709 from german77/npad-disc
service: hid: Clear controller status when aruid is no longer used
2024-01-19 09:33:16 -05:00
Narr the Reg
9f376cd901 service: hid: Clear controller status when aruid is no longer used 2024-01-19 00:09:49 -06:00
liamwhite
a560b9f5a2
Merge pull request #12678 from german77/settings_impl
service: set: Implement stubbed functions
2024-01-18 21:18:37 -05:00
liamwhite
4f04bd3697
Merge pull request #12683 from german77/amiibo-dump
service: nfc: Create backup when none exist
2024-01-18 21:18:27 -05:00
liamwhite
97c8b49444
Merge pull request #12644 from liamwhite/vkspec-image-offset
shader_recompiler: fix Offset operand usage for non-OpImage*Gather
2024-01-18 21:18:19 -05:00
Liam
748465f5a5 device_memory_manager: use unique_lock for update 2024-01-18 21:12:30 -05:00
Liam
04867e2456 nvhost_vic: use map erase by key 2024-01-18 21:12:30 -05:00
Liam
32f623e029 nvdrv: clean up preallocation 2024-01-18 21:12:30 -05:00
Liam
b6c6534c30 nvdrv: use correct names for interface factory 2024-01-18 21:12:30 -05:00
Liam
beb438bb0b nvdrv: use static typing for SessionId, smmu Asid types 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
4b963ca8a5 Core: Invert guest memory depandancy 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
648ed55fe6 Core: Make sure GPU Dirty Managers ae shared by all processes. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
23430e6772 Core: Eliminate core/memory dependancies. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
0672847330 SMMU: Fix Right Shift UB. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
a874ab0133 SMMU: Fix 8Gb layout. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
590d9b7e1d Core: Clang format and other small issues. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
b0bca0f8b0 SMMU: Fix software rendering and cleanup 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
d8f1ce2f76 SMMU: Add continuity tracking optimization. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
9b11b9dce5 SMMU: Simplify and remove old code. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
303cd31162 SMMU: Add Android compatibility 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
0adc09e0af GPU-SMMU: Estimate game leak and preallocate device region. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
96fd1348ae GPU SMMU: Expand to 34 bits 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
bad705f245 SMMU: Fix Unregister on MultiAddress 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
34a8d0cc8e SMMU: Implement physical memory mirroring 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
0a2536a0df SMMU: Initial adaptation to video_core. 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
c85d7ccd79 SMMU: Implement backing CPU page protect/unprotect 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
7a9d1ad2f8 NVDRV: Implement sessions and initial implementation of SMMU 2024-01-18 21:12:30 -05:00
Fernando Sahmkow
2f0418c101 Core: Initial implementation of device memory mapping 2024-01-18 21:12:30 -05:00
Charles Lombardo
3092855d5a
Merge pull request #12702 from german77/android-input
input_common: Add android input engine
2024-01-18 09:16:58 -05:00
Narr the Reg
72f803c366 input_common: Add android input engine 2024-01-17 22:47:56 -06:00
liamwhite
c87b96435d
Merge pull request #12699 from t895/overlay-saving
android: Save overlay data while using emulation fragment
2024-01-17 22:56:40 -05:00
Liam
e4bbb24dcf vi: check layer state before opening or closing 2024-01-17 22:03:40 -05:00
Andrew Pilley
6536d29c61 Update based on feedback 2024-01-17 18:14:05 -08:00
t895
116f76e4b6 android: Save overlay data while using emulation fragment
This should have been fully embraced before but the items within the popup menu and the adjust controls dialog fell through. This ensures that everything related to the overlay is saved during emulation and can't be lost during a crash.
2024-01-17 20:14:25 -05:00
Liam
ce89580749 nvnflinger: ensure display abandonment considers all layers and future layers 2024-01-17 18:45:39 -05:00
Andrew Pilley
dff0a7c52a Allow -u to accept a username string in addition to index, and suppress the User selector even if settings requires it to be shown for one instance only. 2024-01-17 10:31:00 -08:00
liamwhite
915efa4236
Merge pull request #12689 from liamwhite/remove-format
ci: remove format dep from mainline step2
2024-01-17 00:36:07 -05:00
Liam
4548e5ae1d ci: remove format dep from mainline step2 2024-01-16 22:59:20 -05:00
Narr the Reg
46c2435235
Merge pull request #12380 from flodavid/save-profile
Save configuration profile name used by players
2024-01-16 21:27:25 -06:00
Liam
e9eb017aac renderer_vulkan: recreate swapchain when frame size changes 2024-01-16 16:09:39 -05:00
Narr the Reg
0b0e9ef18d core: hid: Disable special features before disconnecting the controllers 2024-01-16 14:44:54 -06:00
Narr the Reg
7f5adf8982 service: set: Implement stubbed functions 2024-01-15 23:17:03 -06:00
Narr the Reg
89d6856090 service: set: Refractor setting service 2024-01-15 23:16:36 -06:00
Narr the Reg
2cacb9d48c service: hid: Fully implement abstract vibration 2024-01-15 23:15:40 -06:00
liamwhite
2c29c2b8dd
Merge pull request #12686 from szepeviktor/typos3
Fix more typos
2024-01-15 23:26:08 -05:00
Viktor Szépe
16abda59be Fix typos in master 2024-01-16 00:09:25 +00:00
Viktor Szépe
90ab89a0b0 Merge remote-tracking branch 'origin/master' into typos3 2024-01-16 00:09:00 +00:00
Viktor Szépe
6531ad56a6 Fix typos in arrays.xml 2024-01-15 23:39:45 +00:00
Viktor Szépe
e8671ed04e Fix one more typo 2024-01-15 23:34:11 +00:00
Viktor Szépe
2044ae6b3a Fix more typos 2024-01-15 23:26:53 +00:00
Narr the Reg
c661b95864 service: nfc: Create backup when none exist 2024-01-15 14:07:54 -06:00
Liam
2044a289f8 shader_recompiler: fix Offset operand usage for non-OpImage*Gather 2024-01-11 00:56:37 -05:00
flodavid
63b835f822 Save profile name used
- Save the profile name in global config
- Read the profile name when reading the global config
2024-01-08 18:43:56 +01:00
flodavid
e231b8b6f5 yuzu: Add per-game linux gamemode configuration 2024-01-02 21:21:40 +01:00
flodavid
68fe1e3476 fix linux config values not saved 2024-01-02 21:21:40 +01:00
1442 changed files with 112541 additions and 59250 deletions

View File

@ -0,0 +1,21 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
export NDK_CCACHE="$(which ccache)"
ccache -s
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
base64 --decode <<< "${EA_PLAY_ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
export ANDROID_KEY_ALIAS="${PLAY_ANDROID_KEY_ALIAS}"
export ANDROID_KEYSTORE_PASS="${PLAY_ANDROID_KEYSTORE_PASS}"
export SERVICE_ACCOUNT_KEY_PATH="${GITHUB_WORKSPACE}/sa.json"
base64 --decode <<< "${EA_SERVICE_ACCOUNT_KEY_B64}" > "${SERVICE_ACCOUNT_KEY_PATH}"
./gradlew "publishEaReleaseBundle"
ccache -s
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
rm "${ANDROID_KEYSTORE_FILE}"
fi

View File

@ -0,0 +1,21 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
export NDK_CCACHE="$(which ccache)"
ccache -s
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
base64 --decode <<< "${MAINLINE_PLAY_ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
export ANDROID_KEY_ALIAS="${PLAY_ANDROID_KEY_ALIAS}"
export ANDROID_KEYSTORE_PASS="${PLAY_ANDROID_KEYSTORE_PASS}"
export SERVICE_ACCOUNT_KEY_PATH="${GITHUB_WORKSPACE}/sa.json"
base64 --decode <<< "${MAINLINE_SERVICE_ACCOUNT_KEY_B64}" > "${SERVICE_ACCOUNT_KEY_PATH}"
./gradlew "publishMainlineReleaseBundle"
ccache -s
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
rm "${ANDROID_KEYSTORE_FILE}"
fi

View File

@ -33,7 +33,6 @@ stages:
cache: 'true'
version: $(DisplayVersion)
- stage: build_win
dependsOn: format
displayName: 'build-windows'
jobs:
- job: build

View File

@ -0,0 +1,66 @@
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
name: yuzu-android-ea-play-release
on:
workflow_dispatch:
inputs:
release-track:
description: 'Play store release track (internal/alpha/beta/production)'
required: true
default: 'alpha'
jobs:
android:
runs-on: ubuntu-latest
if: ${{ github.repository == 'yuzu-emu/yuzu' }}
steps:
- uses: actions/checkout@v3
name: Checkout
with:
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- run: npm install execa@5
- uses: actions/github-script@v5
name: 'Merge and publish Android EA changes'
env:
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
BUILD_EA: true
with:
script: |
const execa = require("execa");
const mergebot = require('./.github/workflows/android-merge.js').mergebot;
process.chdir('${{ github.workspace }}');
mergebot(github, context, execa);
- name: Get tag name
run: echo "GIT_TAG_NAME=$(cat tag-name.txt)" >> $GITHUB_ENV
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
- name: Build
run: ./.ci/scripts/android/eabuild.sh
env:
EA_PLAY_ANDROID_KEYSTORE_B64: ${{ secrets.PLAY_ANDROID_KEYSTORE_B64 }}
PLAY_ANDROID_KEY_ALIAS: ${{ secrets.PLAY_ANDROID_KEY_ALIAS }}
PLAY_ANDROID_KEYSTORE_PASS: ${{ secrets.PLAY_ANDROID_KEYSTORE_PASS }}
EA_SERVICE_ACCOUNT_KEY_B64: ${{ secrets.EA_SERVICE_ACCOUNT_KEY_B64 }}
STORE_TRACK: ${{ github.event.inputs.release-track }}
AUTO_VERSIONED: true
BUILD_EA: true
- name: Create release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.EA_TAG_NAME }}
name: ${{ env.EA_TAG_NAME }}
draft: false
prerelease: false
repository: yuzu/yuzu-android
token: ${{ secrets.ALT_GITHUB_TOKEN }}

View File

@ -0,0 +1,59 @@
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
name: yuzu-android-mainline-play-release
on:
workflow_dispatch:
inputs:
release-tag:
description: 'Tag # from yuzu-android that you want to build and publish'
required: true
default: '200'
release-track:
description: 'Play store release track (internal/alpha/beta/production)'
required: true
default: 'alpha'
jobs:
android:
runs-on: ubuntu-latest
if: ${{ github.repository == 'yuzu-emu/yuzu' }}
steps:
- uses: actions/checkout@v3
name: Checkout
with:
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- run: npm install execa@5
- uses: actions/github-script@v5
name: 'Pull mainline tag'
env:
MAINLINE_TAG: ${{ github.event.inputs.release-tag }}
with:
script: |
const execa = require("execa");
const mergebot = require('./.github/workflows/android-merge.js').getMainlineTag;
process.chdir('${{ github.workspace }}');
mergebot(execa);
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
- name: Build
run: |
echo "GIT_TAG_NAME=android-${{ github.event.inputs.releast-tag }}" >> $GITHUB_ENV
./.ci/scripts/android/mainlinebuild.sh
env:
MAINLINE_PLAY_ANDROID_KEYSTORE_B64: ${{ secrets.PLAY_ANDROID_KEYSTORE_B64 }}
PLAY_ANDROID_KEY_ALIAS: ${{ secrets.PLAY_ANDROID_KEY_ALIAS }}
PLAY_ANDROID_KEYSTORE_PASS: ${{ secrets.PLAY_ANDROID_KEYSTORE_PASS }}
SERVICE_ACCOUNT_KEY_B64: ${{ secrets.MAINLINE_SERVICE_ACCOUNT_KEY_B64 }}
STORE_TRACK: ${{ github.event.inputs.release-track }}
AUTO_VERSIONED: true

View File

@ -6,9 +6,12 @@
const fs = require("fs");
// which label to check for changes
const CHANGE_LABEL = 'android-merge';
const CHANGE_LABEL_MAINLINE = 'android-merge';
const CHANGE_LABEL_EA = 'android-ea-merge';
// how far back in time should we consider the changes are "recent"? (default: 24 hours)
const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000);
const BUILD_EA = process.env.BUILD_EA == 'true';
const MAINLINE_TAG = process.env.MAINLINE_TAG;
async function checkBaseChanges(github) {
// query the commit date of the latest commit on this branch
@ -40,20 +43,7 @@ async function checkBaseChanges(github) {
async function checkAndroidChanges(github) {
if (checkBaseChanges(github)) return true;
const query = `query($owner:String!, $name:String!, $label:String!) {
repository(name:$name, owner:$owner) {
pullRequests(labels: [$label], states: OPEN, first: 100) {
nodes { number headRepository { pushedAt } }
}
}
}`;
const variables = {
owner: 'yuzu-emu',
name: 'yuzu',
label: CHANGE_LABEL,
};
const result = await github.graphql(query, variables);
const pulls = result.repository.pullRequests.nodes;
const pulls = getPulls(github, false);
for (let i = 0; i < pulls.length; i++) {
let pull = pulls[i];
if (new Date() - new Date(pull.headRepository.pushedAt) <= DETECTION_TIME_FRAME) {
@ -83,7 +73,13 @@ async function tagAndPush(github, owner, repo, execa, commit=false) {
};
const tags = await github.graphql(query, variables);
const tagList = tags.repository.refs.nodes;
const lastTag = tagList[0] ? tagList[0].name : 'dummy-0';
let lastTag = 'android-1';
for (let i = 0; i < tagList.length; ++i) {
if (tagList[i].name.includes('android-')) {
lastTag = tagList[i].name;
break;
}
}
const tagNumber = /\w+-(\d+)/.exec(lastTag)[1] | 0;
const channel = repo.split('-')[1];
const newTag = `${channel}-${tagNumber + 1}`;
@ -101,6 +97,48 @@ async function tagAndPush(github, owner, repo, execa, commit=false) {
console.info('Successfully pushed new changes.');
}
async function tagAndPushEA(github, owner, repo, execa) {
let altToken = process.env.ALT_GITHUB_TOKEN;
if (!altToken) {
throw `Please set ALT_GITHUB_TOKEN environment variable. This token should have write access to ${owner}/${repo}.`;
}
const query = `query ($owner:String!, $name:String!) {
repository(name:$name, owner:$owner) {
refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 10) {
nodes { name }
}
}
}`;
const variables = {
owner: owner,
name: repo,
};
const tags = await github.graphql(query, variables);
const tagList = tags.repository.refs.nodes;
let lastTag = 'ea-1';
for (let i = 0; i < tagList.length; ++i) {
if (tagList[i].name.includes('ea-')) {
lastTag = tagList[i].name;
break;
}
}
const tagNumber = /\w+-(\d+)/.exec(lastTag)[1] | 0;
const newTag = `ea-${tagNumber + 1}`;
console.log(`New tag: ${newTag}`);
console.info('Pushing tags to GitHub ...');
await execa("git", ["remote", "add", "android", "https://github.com/yuzu-emu/yuzu-android.git"]);
await execa("git", ["fetch", "android"]);
await execa("git", ['tag', newTag]);
await execa("git", ['push', 'android', `${newTag}`]);
fs.writeFile('tag-name.txt', newTag, (err) => {
if (err) throw 'Could not write tag name to file!'
})
console.info('Successfully pushed new changes.');
}
async function generateReadme(pulls, context, mergeResults, execa) {
let baseUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/`;
let output =
@ -202,10 +240,7 @@ async function resetBranch(execa) {
}
}
async function mergebot(github, context, execa) {
// Reset our local copy of master to what appears on yuzu-emu/yuzu - master
await resetBranch(execa);
async function getPulls(github) {
const query = `query ($owner:String!, $name:String!, $label:String!) {
repository(name:$name, owner:$owner) {
pullRequests(labels: [$label], states: OPEN, first: 100) {
@ -215,13 +250,49 @@ async function mergebot(github, context, execa) {
}
}
}`;
const variables = {
const mainlineVariables = {
owner: 'yuzu-emu',
name: 'yuzu',
label: CHANGE_LABEL,
label: CHANGE_LABEL_MAINLINE,
};
const result = await github.graphql(query, variables);
const pulls = result.repository.pullRequests.nodes;
const mainlineResult = await github.graphql(query, mainlineVariables);
const pulls = mainlineResult.repository.pullRequests.nodes;
if (BUILD_EA) {
const eaVariables = {
owner: 'yuzu-emu',
name: 'yuzu',
label: CHANGE_LABEL_EA,
};
const eaResult = await github.graphql(query, eaVariables);
const eaPulls = eaResult.repository.pullRequests.nodes;
return pulls.concat(eaPulls);
}
return pulls;
}
async function getMainlineTag(execa) {
console.log(`::group::Getting mainline tag android-${MAINLINE_TAG}`);
let hasFailed = false;
try {
await execa("git", ["remote", "add", "mainline", "https://github.com/yuzu-emu/yuzu-android.git"]);
await execa("git", ["fetch", "mainline", "--tags"]);
await execa("git", ["checkout", `tags/android-${MAINLINE_TAG}`]);
await execa("git", ["submodule", "update", "--init", "--recursive"]);
} catch (err) {
console.log('::error title=Failed pull tag');
hasFailed = true;
}
console.log("::endgroup::");
if (hasFailed) {
throw 'Failed pull mainline tag. Aborting!';
}
}
async function mergebot(github, context, execa) {
// Reset our local copy of master to what appears on yuzu-emu/yuzu - master
await resetBranch(execa);
const pulls = await getPulls(github);
let displayList = [];
for (let i = 0; i < pulls.length; i++) {
let pull = pulls[i];
@ -231,11 +302,17 @@ async function mergebot(github, context, execa) {
console.table(displayList);
await fetchPullRequests(pulls, "https://github.com/yuzu-emu/yuzu", execa);
const mergeResults = await mergePullRequests(pulls, execa);
if (BUILD_EA) {
await tagAndPushEA(github, 'yuzu-emu', `yuzu-android`, execa);
} else {
await generateReadme(pulls, context, mergeResults, execa);
await tagAndPush(github, 'yuzu-emu', `yuzu-android`, execa, true);
}
}
module.exports.mergebot = mergebot;
module.exports.checkAndroidChanges = checkAndroidChanges;
module.exports.tagAndPush = tagAndPush;
module.exports.checkBaseChanges = checkBaseChanges;
module.exports.getMainlineTag = getMainlineTag;

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
name: yuzu-android-publish
@ -16,7 +16,7 @@ on:
jobs:
android:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu-android' }}
if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu' }}
steps:
# this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v3

View File

@ -73,7 +73,7 @@ jobs:
build-mac:
name: 'test build (macos)'
needs: format
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v3
with:
@ -81,13 +81,12 @@ jobs:
fetch-depth: 0
- name: Install dependencies
run: |
# workaround for https://github.com/actions/setup-python/issues/577
brew install autoconf automake boost@1.83 ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd || brew link --overwrite python@3.12
brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
- name: Build
run: |
mkdir build
cd build
export Qt5_DIR="/usr/local/opt/qt@5/lib/cmake"
export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
ninja
build-msvc:

3
.gitmodules vendored
View File

@ -64,3 +64,6 @@
[submodule "oaknut"]
path = externals/oaknut
url = https://github.com/merryhime/oaknut
[submodule "Vulkan-Utility-Libraries"]
path = externals/Vulkan-Utility-Libraries
url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git

View File

@ -155,3 +155,7 @@ License: MIT
Files: externals/gamemode/*
Copyright: Copyright 2017-2019 Feral Interactive
License: BSD-3-Clause
Files: src/android/app/debug.keystore
Copyright: 2023 yuzu Emulator Project
License: GPL-3.0-or-later

View File

@ -36,6 +36,8 @@ option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ON)
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
@ -305,7 +307,11 @@ find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)
if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
find_package(Vulkan 1.3.274 REQUIRED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
if (NOT YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
find_package(VulkanUtilityLibraries REQUIRED)
endif()
if (ENABLE_LIBUSB)
@ -316,6 +322,10 @@ if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak 6 CONFIG)
endif()
if (ARCHITECTURE_arm64)
find_package(oaknut 2.0.1 CONFIG)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
find_package(dynarmic 6.4.0 CONFIG)
endif()

View File

@ -2,18 +2,20 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
find_path(SimpleIni_INCLUDE_DIR SimpleIni.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SimpleIni
REQUIRED_VARS SimpleIni_INCLUDE_DIR
)
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
add_library(SimpleIni::SimpleIni INTERFACE IMPORTED)
set_target_properties(SimpleIni::SimpleIni PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SimpleIni_INCLUDE_DIR}"
find_package(SimpleIni QUIET CONFIG)
if (SimpleIni_CONSIDERED_CONFIGS)
find_package_handle_standard_args(SimpleIni CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
pkg_search_module(SIMPLEINI QUIET IMPORTED_TARGET simpleini)
find_package_handle_standard_args(SimpleIni
REQUIRED_VARS SIMPLEINI_INCLUDEDIR
VERSION_VAR SIMPLEINI_VERSION
)
endif()
mark_as_advanced(SimpleIni_INCLUDE_DIR)
if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
add_library(SimpleIni::SimpleIni ALIAS PkgConfig::SIMPLEINI)
endif()

View File

@ -1,3 +1,15 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
| [12461](https://github.com/yuzu-emu/yuzu//pull/12461) | [`7464cae24`](https://github.com/yuzu-emu/yuzu//pull/12461/files) | Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. | [Kelebek1](https://github.com/Kelebek1/) | Yes |
| [13018](https://github.com/yuzu-emu/yuzu//pull/13018) | [`01cbc638a`](https://github.com/yuzu-emu/yuzu//pull/13018/files) | am: rewrite part 2 | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13174](https://github.com/yuzu-emu/yuzu//pull/13174) | [`7d1284826`](https://github.com/yuzu-emu/yuzu//pull/13174/files) | glue/time: Remove global variables | [FearlessTobi](https://github.com/FearlessTobi/) | Yes |
| [13177](https://github.com/yuzu-emu/yuzu//pull/13177) | [`f5cc94f05`](https://github.com/yuzu-emu/yuzu//pull/13177/files) | vfs: misc performance improvements | [liamwhite](https://github.com/liamwhite/) | Yes |
End of merge log. You can find the original README.md below the break.
-----
<!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later

View File

@ -11,3 +11,4 @@ type = QT
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
source_file = ../../src/android/app/src/main/res/values/strings.xml
type = ANDROID
lang_map = ja_JP:ja, ko_KR:ko, pt_BR:pt-rBR, pt_PT:pt-rPT, ru_RU:ru, vi_VN:vi, zh_CN:zh-rCN, zh_TW:zh-rTW

2209
dist/languages/ar.ts vendored

File diff suppressed because it is too large Load Diff

2185
dist/languages/ca.ts vendored

File diff suppressed because it is too large Load Diff

2229
dist/languages/cs.ts vendored

File diff suppressed because it is too large Load Diff

2263
dist/languages/da.ts vendored

File diff suppressed because it is too large Load Diff

1778
dist/languages/de.ts vendored

File diff suppressed because it is too large Load Diff

2155
dist/languages/el.ts vendored

File diff suppressed because it is too large Load Diff

1871
dist/languages/es.ts vendored

File diff suppressed because it is too large Load Diff

1829
dist/languages/fr.ts vendored

File diff suppressed because it is too large Load Diff

2073
dist/languages/hu.ts vendored

File diff suppressed because it is too large Load Diff

2294
dist/languages/id.ts vendored

File diff suppressed because it is too large Load Diff

1845
dist/languages/it.ts vendored

File diff suppressed because it is too large Load Diff

2143
dist/languages/ja_JP.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/ko_KR.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/nb.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/nl.ts vendored

File diff suppressed because it is too large Load Diff

2071
dist/languages/pl.ts vendored

File diff suppressed because it is too large Load Diff

2193
dist/languages/pt_BR.ts vendored

File diff suppressed because it is too large Load Diff

1827
dist/languages/pt_PT.ts vendored

File diff suppressed because it is too large Load Diff

1984
dist/languages/ru_RU.ts vendored

File diff suppressed because it is too large Load Diff

2419
dist/languages/sv.ts vendored

File diff suppressed because it is too large Load Diff

2147
dist/languages/tr_TR.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/uk.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/vi.ts vendored

File diff suppressed because it is too large Load Diff

1907
dist/languages/vi_VN.ts vendored

File diff suppressed because it is too large Load Diff

1865
dist/languages/zh_CN.ts vendored

File diff suppressed because it is too large Load Diff

1828
dist/languages/zh_TW.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -14,16 +14,17 @@ set(BUILD_SHARED_LIBS OFF)
# Skip install rules for all externals
set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
# xbyak
# Xbyak (also used by Dynarmic, so needs to be added first)
if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
add_subdirectory(xbyak)
endif()
# Dynarmic
# Oaknut (also used by Dynarmic, so needs to be added first)
if (ARCHITECTURE_arm64 AND NOT TARGET merry::oaknut)
add_subdirectory(oaknut)
endif()
# Dynarmic
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
set(DYNARMIC_IGNORE_ASSERTS ON)
add_subdirectory(dynarmic)
@ -154,6 +155,11 @@ if (YUZU_USE_EXTERNAL_VULKAN_HEADERS)
add_subdirectory(Vulkan-Headers)
endif()
# Vulkan-Utility-Libraries
if (YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
add_subdirectory(Vulkan-Utility-Libraries)
endif()
# TZDB (Time Zone Database)
add_subdirectory(nx_tzdb)
@ -178,6 +184,9 @@ if (NOT TARGET stb::headers)
add_library(stb::headers ALIAS stb)
endif()
add_library(tz tz/tz/tz.cpp)
target_include_directories(tz PUBLIC ./tz)
add_library(bc_decoder bc_decoder/bc_decoder.cpp)
target_include_directories(bc_decoder PUBLIC ./bc_decoder)
@ -305,3 +314,10 @@ endif()
if (NOT TARGET SimpleIni::SimpleIni)
add_subdirectory(simpleini)
endif()
# sse2neon
if (ARCHITECTURE_arm64 AND NOT TARGET sse2neon)
add_library(sse2neon INTERFACE)
target_include_directories(sse2neon INTERFACE sse2neon)
endif()

1
externals/Vulkan-Utility-Libraries vendored Submodule

@ -0,0 +1 @@
Subproject commit 524f8910d0e4a5f2ec5961996b23e5b74b95cb1d

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit 0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378
Subproject commit ba8192d89078af51ae6f97c9352e3683612cdff1

View File

@ -32,7 +32,7 @@ set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip")
set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb")
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE})
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR})
set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")

View File

@ -11,6 +11,10 @@ execute_process(
WORKING_DIRECTORY ${ZONE_PATH}
OUTPUT_VARIABLE FILE_LIST)
if (NOT FILE_LIST)
message(FATAL_ERROR "No timezone files found in directory ${ZONE_PATH}, did the download fail?")
endif()
set(DIRECTORY_NAME ${HEADER_NAME})
set(FILE_DATA "")

@ -1 +1 @@
Subproject commit 404d39004570a26c734a9d1fa29ab4d63089c599
Subproject commit 97929690234f2b4add36b33657fe3fe09bd57dfd

2
externals/oaknut vendored

@ -1 +1 @@
Subproject commit 918bd94f025d6a2de13978468351598997ae3909
Subproject commit 9d091109deb445bc6e9289c6195a282b7c993d49

9282
externals/sse2neon/sse2neon.h vendored Normal file

File diff suppressed because it is too large Load Diff

1636
externals/tz/tz/tz.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

81
externals/tz/tz/tz.h vendored Normal file
View File

@ -0,0 +1,81 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: 1996 Arthur David Olson
// SPDX-License-Identifier: BSD-2-Clause
#pragma once
#include <cstdint>
#include <limits>
#include <span>
#include <array>
#include <time.h>
namespace Tz {
using u8 = uint8_t;
using s8 = int8_t;
using u16 = uint16_t;
using s16 = int16_t;
using u32 = uint32_t;
using s32 = int32_t;
using u64 = uint64_t;
using s64 = int64_t;
constexpr size_t TZ_MAX_TIMES = 1000;
constexpr size_t TZ_MAX_TYPES = 128;
constexpr size_t TZ_MAX_CHARS = 50;
constexpr size_t MY_TZNAME_MAX = 255;
constexpr size_t TZNAME_MAXIMUM = 255;
constexpr size_t TZ_MAX_LEAPS = 50;
constexpr s64 TIME_T_MAX = std::numeric_limits<s64>::max();
constexpr s64 TIME_T_MIN = std::numeric_limits<s64>::min();
constexpr size_t CHARS_EXTRA = 3;
constexpr size_t MAX_ZONE_CHARS = std::max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof("UTC"));
constexpr size_t MAX_TZNAME_CHARS = 2 * (MY_TZNAME_MAX + 1);
struct ttinfo {
s32 tt_utoff;
bool tt_isdst;
s32 tt_desigidx;
bool tt_ttisstd;
bool tt_ttisut;
};
static_assert(sizeof(ttinfo) == 0x10, "ttinfo has the wrong size!");
struct Rule {
s32 timecnt;
s32 typecnt;
s32 charcnt;
bool goback;
bool goahead;
std::array <u8, 0x2> padding0;
std::array<s64, TZ_MAX_TIMES> ats;
std::array<u8, TZ_MAX_TIMES> types;
std::array<ttinfo, TZ_MAX_TYPES> ttis;
std::array<char, std::max(MAX_ZONE_CHARS, MAX_TZNAME_CHARS)> chars;
s32 defaulttype;
std::array <u8, 0x12C4> padding1;
};
static_assert(sizeof(Rule) == 0x4000, "Rule has the wrong size!");
struct CalendarTimeInternal {
s32 tm_sec;
s32 tm_min;
s32 tm_hour;
s32 tm_mday;
s32 tm_mon;
s32 tm_year;
s32 tm_wday;
s32 tm_yday;
s32 tm_isdst;
std::array<char, 16> tm_zone;
s32 tm_utoff;
s32 time_index;
};
static_assert(sizeof(CalendarTimeInternal) == 0x3C, "CalendarTimeInternal has the wrong size!");
s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary);
bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep);
u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp);
} // namespace Tz

View File

@ -121,6 +121,7 @@ else()
-Wno-attributes
-Wno-invalid-offsetof
-Wno-unused-parameter
-Wno-missing-field-initializers
)
if (CMAKE_CXX_COMPILER_ID MATCHES Clang) # Clang or AppleClang
@ -164,6 +165,7 @@ else()
if (MINGW)
add_definitions(-DMINGW_HAS_SECURE_API)
add_compile_options("-msse4.1")
if (MINGW_STATIC_BUILD)
add_definitions(-DQT_STATICPLUGIN)

View File

@ -3,8 +3,8 @@
import android.annotation.SuppressLint
import kotlin.collections.setOf
import org.jetbrains.kotlin.konan.properties.Properties
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
plugins {
id("com.android.application")
@ -13,6 +13,7 @@ plugins {
kotlin("plugin.serialization") version "1.9.20"
id("androidx.navigation.safeargs.kotlin")
id("org.jlleitschuh.gradle.ktlint") version "11.4.0"
id("com.github.triplet.play") version "3.8.6"
}
/**
@ -58,15 +59,7 @@ android {
targetSdk = 34
versionName = getGitVersion()
// If you want to use autoVersion for the versionCode, create a property in local.properties
// named "autoVersioned" and set it to "true"
val properties = Properties()
val versionProperty = try {
properties.load(project.rootProject.file("local.properties").inputStream())
properties.getProperty("autoVersioned") ?: ""
} catch (e: Exception) { "" }
versionCode = if (versionProperty == "true") {
versionCode = if (System.getenv("AUTO_VERSIONED") == "true") {
autoVersion
} else {
1
@ -82,8 +75,8 @@ android {
}
val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE")
if (keystoreFile != null) {
signingConfigs {
if (keystoreFile != null) {
create("release") {
storeFile = file(keystoreFile)
storePassword = System.getenv("ANDROID_KEYSTORE_PASS")
@ -91,6 +84,12 @@ android {
keyPassword = System.getenv("ANDROID_KEYSTORE_PASS")
}
}
create("default") {
storeFile = file("$projectDir/debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
}
}
// Define build types, which are orthogonal to product flavors.
@ -101,7 +100,7 @@ android {
signingConfig = if (keystoreFile != null) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
signingConfigs.getByName("default")
}
resValue("string", "app_name_suffixed", "yuzu")
@ -118,7 +117,7 @@ android {
register("relWithDebInfo") {
isDefault = true
resValue("string", "app_name_suffixed", "yuzu Debug Release")
signingConfig = signingConfigs.getByName("debug")
signingConfig = signingConfigs.getByName("default")
isMinifyEnabled = true
isDebuggable = true
proguardFiles(
@ -133,6 +132,7 @@ android {
// Signed by debug key disallowing distribution on Play Store.
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
debug {
signingConfig = signingConfigs.getByName("default")
resValue("string", "app_name_suffixed", "yuzu Debug")
isDebuggable = true
isJniDebuggable = true
@ -214,6 +214,15 @@ ktlint {
}
}
play {
val keyPath = System.getenv("SERVICE_ACCOUNT_KEY_PATH")
if (keyPath != null) {
serviceAccountCredentials.set(File(keyPath))
}
track.set(System.getenv("STORE_TRACK") ?: "internal")
releaseStatus.set(ReleaseStatus.COMPLETED)
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
@ -250,12 +259,18 @@ fun runGitCommand(command: List<String>): String {
}
fun getGitVersion(): String {
val gitVersion = runGitCommand(
listOf(
"git",
"describe",
"--always",
"--long"
)
).replace(Regex("(-0)?-[^-]+$"), "")
val versionName = if (System.getenv("GITHUB_ACTIONS") != null) {
val gitTag = System.getenv("GIT_TAG_NAME") ?: ""
gitTag
System.getenv("GIT_TAG_NAME") ?: gitVersion
} else {
runGitCommand(listOf("git", "describe", "--always", "--long"))
.replace(Regex("(-0)?-[^-]+$"), "")
gitVersion
}
return versionName.ifEmpty { "0.0" }
}

Binary file not shown.

View File

@ -12,10 +12,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
<uses-feature android:name="android.hardware.vulkan.version" android:version="0x401000" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="org.yuzu.yuzu_emu.YuzuApplication"
@ -80,10 +79,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:resource="@xml/nfc_tech_filter" />
</activity>
<service android:name="org.yuzu.yuzu_emu.utils.ForegroundService" android:foregroundServiceType="specialUse">
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" android:value="Keep emulation running in background"/>
</service>
<provider
android:name=".features.DocumentProvider"
android:authorities="${applicationId}.user"

View File

@ -3,58 +3,30 @@
package org.yuzu.yuzu_emu
import android.app.Dialog
import android.content.DialogInterface
import android.net.Uri
import android.os.Bundle
import android.text.Html
import android.text.method.LinkMovementMethod
import android.view.Surface
import android.view.View
import android.widget.TextView
import androidx.annotation.Keep
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.lang.ref.WeakReference
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.fragments.CoreErrorDialogFragment
import org.yuzu.yuzu_emu.utils.DocumentsTree
import org.yuzu.yuzu_emu.utils.FileUtil
import org.yuzu.yuzu_emu.utils.Log
import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
import org.yuzu.yuzu_emu.model.InstallResult
import org.yuzu.yuzu_emu.model.Patch
import org.yuzu.yuzu_emu.model.GameVerificationResult
/**
* Class which contains methods that interact
* with the native side of the Yuzu code.
*/
object NativeLibrary {
/**
* Default controller id for each device
*/
const val Player1Device = 0
const val Player2Device = 1
const val Player3Device = 2
const val Player4Device = 3
const val Player5Device = 4
const val Player6Device = 5
const val Player7Device = 6
const val Player8Device = 7
const val ConsoleDevice = 8
/**
* Controller type for each device
*/
const val ProController = 3
const val Handheld = 4
const val JoyconDual = 5
const val JoyconLeft = 6
const val JoyconRight = 7
const val GameCube = 8
const val Pokeball = 9
const val NES = 10
const val SNES = 11
const val N64 = 12
const val SegaGenesis = 13
@JvmField
var sEmulationActivity = WeakReference<EmulationActivity?>(null)
@ -124,120 +96,17 @@ object NativeLibrary {
FileUtil.getFilename(Uri.parse(path))
}
/**
* Returns true if pro controller isn't available and handheld is
*/
external fun isHandheldOnly(): Boolean
/**
* Changes controller type for a specific device.
*
* @param Device The input descriptor of the gamepad.
* @param Type The NpadStyleIndex of the gamepad.
*/
external fun setDeviceType(Device: Int, Type: Int): Boolean
/**
* Handles event when a gamepad is connected.
*
* @param Device The input descriptor of the gamepad.
*/
external fun onGamePadConnectEvent(Device: Int): Boolean
/**
* Handles event when a gamepad is disconnected.
*
* @param Device The input descriptor of the gamepad.
*/
external fun onGamePadDisconnectEvent(Device: Int): Boolean
/**
* Handles button press events for a gamepad.
*
* @param Device The input descriptor of the gamepad.
* @param Button Key code identifying which button was pressed.
* @param Action Mask identifying which action is happening (button pressed down, or button released).
* @return If we handled the button press.
*/
external fun onGamePadButtonEvent(Device: Int, Button: Int, Action: Int): Boolean
/**
* Handles joystick movement events.
*
* @param Device The device ID of the gamepad.
* @param Axis The axis ID
* @param x_axis The value of the x-axis represented by the given ID.
* @param y_axis The value of the y-axis represented by the given ID.
*/
external fun onGamePadJoystickEvent(
Device: Int,
Axis: Int,
x_axis: Float,
y_axis: Float
): Boolean
/**
* Handles motion events.
*
* @param delta_timestamp The finger id corresponding to this event
* @param gyro_x,gyro_y,gyro_z The value of the accelerometer sensor.
* @param accel_x,accel_y,accel_z The value of the y-axis
*/
external fun onGamePadMotionEvent(
Device: Int,
delta_timestamp: Long,
gyro_x: Float,
gyro_y: Float,
gyro_z: Float,
accel_x: Float,
accel_y: Float,
accel_z: Float
): Boolean
/**
* Signals and load a nfc tag
*
* @param data Byte array containing all the data from a nfc tag
*/
external fun onReadNfcTag(data: ByteArray?): Boolean
/**
* Removes current loaded nfc tag
*/
external fun onRemoveNfcTag(): Boolean
/**
* Handles touch press events.
*
* @param finger_id The finger id corresponding to this event
* @param x_axis The value of the x-axis.
* @param y_axis The value of the y-axis.
*/
external fun onTouchPressed(finger_id: Int, x_axis: Float, y_axis: Float)
/**
* Handles touch movement.
*
* @param x_axis The value of the instantaneous x-axis.
* @param y_axis The value of the instantaneous y-axis.
*/
external fun onTouchMoved(finger_id: Int, x_axis: Float, y_axis: Float)
/**
* Handles touch release events.
*
* @param finger_id The finger id corresponding to this event
*/
external fun onTouchReleased(finger_id: Int)
external fun setAppDirectory(directory: String)
/**
* Installs a nsp or xci file to nand
* @param filename String representation of file uri
* @param extension Lowercase string representation of file extension without "."
* @return int representation of [InstallResult]
*/
external fun installFileToNand(filename: String, extension: String): Int
external fun installFileToNand(
filename: String,
callback: (max: Long, progress: Long) -> Boolean
): Int
external fun doesUpdateMatchProgram(programId: String, updatePath: String): Boolean
@ -255,7 +124,7 @@ object NativeLibrary {
/**
* Begins emulation.
*/
external fun run(path: String?)
external fun run(path: String?, programIndex: Int, frontendInitiated: Boolean)
// Surface Handling
external fun surfaceChanged(surf: Surface?)
@ -297,6 +166,11 @@ object NativeLibrary {
*/
external fun getCpuBackend(): String
/**
* Returns the current GPU Driver.
*/
external fun getGpuDriver(): String
external fun applySettings()
external fun logSettings()
@ -307,46 +181,13 @@ object NativeLibrary {
ErrorUnknown
}
private var coreErrorAlertResult = false
private val coreErrorAlertLock = Object()
class CoreErrorDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val title = requireArguments().serializable<String>("title")
val message = requireArguments().serializable<String>("message")
return MaterialAlertDialogBuilder(requireActivity())
.setTitle(title)
.setMessage(message)
.setPositiveButton(R.string.continue_button, null)
.setNegativeButton(R.string.abort_button) { _: DialogInterface?, _: Int ->
coreErrorAlertResult = false
synchronized(coreErrorAlertLock) { coreErrorAlertLock.notify() }
}
.create()
}
override fun onDismiss(dialog: DialogInterface) {
coreErrorAlertResult = true
synchronized(coreErrorAlertLock) { coreErrorAlertLock.notify() }
}
companion object {
fun newInstance(title: String?, message: String?): CoreErrorDialogFragment {
val frag = CoreErrorDialogFragment()
val args = Bundle()
args.putString("title", title)
args.putString("message", message)
frag.arguments = args
return frag
}
}
}
var coreErrorAlertResult = false
val coreErrorAlertLock = Object()
private fun onCoreErrorImpl(title: String, message: String) {
val emulationActivity = sEmulationActivity.get()
if (emulationActivity == null) {
error("[NativeLibrary] EmulationActivity not present")
Log.error("[NativeLibrary] EmulationActivity not present")
return
}
@ -362,7 +203,7 @@ object NativeLibrary {
fun onCoreError(error: CoreError?, details: String): Boolean {
val emulationActivity = sEmulationActivity.get()
if (emulationActivity == null) {
error("[NativeLibrary] EmulationActivity not present")
Log.error("[NativeLibrary] EmulationActivity not present")
return false
}
@ -393,7 +234,7 @@ object NativeLibrary {
}
// Show the AlertDialog on the main thread.
emulationActivity.runOnUiThread(Runnable { onCoreErrorImpl(title, message) })
emulationActivity.runOnUiThread { onCoreErrorImpl(title, message) }
// Wait for the lock to notify that it is complete.
synchronized(coreErrorAlertLock) { coreErrorAlertLock.wait() }
@ -478,6 +319,12 @@ object NativeLibrary {
sEmulationActivity.get()!!.onEmulationStopped(status)
}
@Keep
@JvmStatic
fun onProgramChanged(programIndex: Int) {
sEmulationActivity.get()!!.onProgramChanged(programIndex)
}
/**
* Logs the Yuzu version, Android version and, CPU.
*/
@ -535,9 +382,49 @@ object NativeLibrary {
*
* @param path Path to game file. Can be a [Uri].
* @param programId String representation of a game's program ID
* @return Array of pairs where the first value is the name of an addon and the second is the version
* @return Array of available patches
*/
external fun getAddonsForFile(path: String, programId: String): Array<Pair<String, String>>?
external fun getPatchesForFile(path: String, programId: String): Array<Patch>?
/**
* Removes an update for a given [programId]
* @param programId String representation of a game's program ID
*/
external fun removeUpdate(programId: String)
/**
* Removes all DLC for a [programId]
* @param programId String representation of a game's program ID
*/
external fun removeDLC(programId: String)
/**
* Removes a mod installed for a given [programId]
* @param programId String representation of a game's program ID
* @param name The name of a mod as given by [getPatchesForFile]. This corresponds with the name
* of the mod's directory in a game's load folder.
*/
external fun removeMod(programId: String, name: String)
/**
* Verifies all installed content
* @param callback UI callback for verification progress. Return true in the callback to cancel.
* @return Array of content that failed verification. Successful if empty.
*/
external fun verifyInstalledContents(
callback: (max: Long, progress: Long) -> Boolean
): Array<String>
/**
* Verifies the contents of a game
* @param path String path to a game
* @param callback UI callback for verification progress. Return true in the callback to cancel.
* @return Int that is meant to be converted to a [GameVerificationResult]
*/
external fun verifyGameContents(
path: String,
callback: (max: Long, progress: Long) -> Boolean
): Int
/**
* Gets the save location for a specific game
@ -569,55 +456,7 @@ object NativeLibrary {
external fun clearFilesystemProvider()
/**
* Button type for use in onTouchEvent
* Checks if all necessary keys are present for decryption
*/
object ButtonType {
const val BUTTON_A = 0
const val BUTTON_B = 1
const val BUTTON_X = 2
const val BUTTON_Y = 3
const val STICK_L = 4
const val STICK_R = 5
const val TRIGGER_L = 6
const val TRIGGER_R = 7
const val TRIGGER_ZL = 8
const val TRIGGER_ZR = 9
const val BUTTON_PLUS = 10
const val BUTTON_MINUS = 11
const val DPAD_LEFT = 12
const val DPAD_UP = 13
const val DPAD_RIGHT = 14
const val DPAD_DOWN = 15
const val BUTTON_SL = 16
const val BUTTON_SR = 17
const val BUTTON_HOME = 18
const val BUTTON_CAPTURE = 19
}
/**
* Stick type for use in onTouchEvent
*/
object StickType {
const val STICK_L = 0
const val STICK_R = 1
}
/**
* Button states
*/
object ButtonState {
const val RELEASED = 0
const val PRESSED = 1
}
/**
* Result from installFileToNand
*/
object InstallFileToNandResult {
const val Success = 0
const val SuccessFileOverwritten = 1
const val Error = 2
const val ErrorBaseGame = 3
const val ErrorFilenameExtension = 4
}
external fun areKeysPresent(): Boolean
}

View File

@ -7,6 +7,7 @@ import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import org.yuzu.yuzu_emu.features.input.NativeInput
import java.io.File
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.DocumentsTree
@ -17,17 +18,6 @@ fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
class YuzuApplication : Application() {
private fun createNotificationChannels() {
val emulationChannel = NotificationChannel(
getString(R.string.emulation_notification_channel_id),
getString(R.string.emulation_notification_channel_name),
NotificationManager.IMPORTANCE_LOW
)
emulationChannel.description = getString(
R.string.emulation_notification_channel_description
)
emulationChannel.setSound(null, null)
emulationChannel.vibrationPattern = null
val noticeChannel = NotificationChannel(
getString(R.string.notice_notification_channel_id),
getString(R.string.notice_notification_channel_name),
@ -39,7 +29,6 @@ class YuzuApplication : Application() {
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(emulationChannel)
notificationManager.createNotificationChannel(noticeChannel)
}
@ -49,6 +38,7 @@ class YuzuApplication : Application() {
documentsTree = DocumentsTree()
DirectoryInitialization.start()
GpuDriverHelper.initializeDriverParameters()
NativeInput.reloadInputDevices()
NativeLibrary.logDeviceInfo()
Log.logDeviceInfo()

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.activities
import android.annotation.SuppressLint
import android.app.Activity
import android.app.PendingIntent
import android.app.PictureInPictureParams
import android.app.RemoteAction
@ -40,17 +39,18 @@ import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.databinding.ActivityEmulationBinding
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.model.EmulationViewModel
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.utils.ForegroundService
import org.yuzu.yuzu_emu.utils.InputHandler
import org.yuzu.yuzu_emu.utils.Log
import org.yuzu.yuzu_emu.utils.MemoryUtil
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.NfcReader
import org.yuzu.yuzu_emu.utils.ParamPackage
import org.yuzu.yuzu_emu.utils.ThemeHelper
import java.text.NumberFormat
import kotlin.math.roundToInt
@ -66,8 +66,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
private var motionTimestamp: Long = 0
private var flipMotionOrientation: Boolean = false
private var controllerIds = InputHandler.getGameControllerIds()
private val actionPause = "ACTION_EMULATOR_PAUSE"
private val actionPlay = "ACTION_EMULATOR_PLAY"
private val actionMute = "ACTION_EMULATOR_MUTE"
@ -75,18 +73,39 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
private val emulationViewModel: EmulationViewModel by viewModels()
override fun onDestroy() {
stopForegroundService(this)
emulationViewModel.clear()
super.onDestroy()
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.gameLaunched = true
ThemeHelper.setTheme(this)
super.onCreate(savedInstanceState)
InputHandler.updateControllerData()
val players = NativeConfig.getInputSettings(true)
var hasConfiguredControllers = false
players.forEach {
if (it.hasMapping()) {
hasConfiguredControllers = true
}
}
if (!hasConfiguredControllers && InputHandler.androidControllers.isNotEmpty()) {
var params: ParamPackage? = null
for (controller in InputHandler.registeredControllers) {
if (controller.get("port", -1) == 0) {
params = controller
break
}
}
if (params != null) {
NativeInput.updateMappingsWithDefault(
0,
params,
params.get("display", getString(R.string.unknown))
)
NativeConfig.saveGlobalConfig()
}
}
binding = ActivityEmulationBinding.inflate(layoutInflater)
setContentView(binding.root)
@ -104,8 +123,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
nfcReader = NfcReader(this)
nfcReader.initialize()
InputHandler.initialize()
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) {
if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.totalMemory)) {
@ -127,10 +144,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
.apply()
}
}
// Start a foreground service to prevent the app from getting killed in the background
val startIntent = Intent(this, ForegroundService::class.java)
startForegroundService(startIntent)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
@ -160,7 +173,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
super.onResume()
nfcReader.startScanning()
startMotionSensorListener()
InputHandler.updateControllerIds()
InputHandler.updateControllerData()
buildPictureInPictureParams()
}
@ -171,11 +184,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
stopMotionSensorListener()
}
override fun onStop() {
super.onStop()
NativeConfig.saveGlobalConfig()
}
override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
@ -190,6 +198,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
super.onNewIntent(intent)
setIntent(intent)
nfcReader.onNewIntent(intent)
InputHandler.updateControllerData()
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@ -199,6 +208,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
return super.dispatchKeyEvent(event)
}
if (emulationViewModel.drawerOpen.value) {
return super.dispatchKeyEvent(event)
}
return InputHandler.dispatchKeyEvent(event)
}
@ -209,6 +222,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
return super.dispatchGenericMotionEvent(event)
}
if (emulationViewModel.drawerOpen.value) {
return super.dispatchGenericMotionEvent(event)
}
// Don't attempt to do anything if we are disconnecting a device.
if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
return true
@ -254,8 +271,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
val deltaTimestamp = (event.timestamp - motionTimestamp) / 1000
motionTimestamp = event.timestamp
NativeLibrary.onGamePadMotionEvent(
NativeLibrary.Player1Device,
NativeInput.onDeviceMotionEvent(
NativeInput.Player1Device,
deltaTimestamp,
gyro[0],
gyro[1],
@ -264,8 +281,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
accel[1],
accel[2]
)
NativeLibrary.onGamePadMotionEvent(
NativeLibrary.ConsoleDevice,
NativeInput.onDeviceMotionEvent(
NativeInput.ConsoleDevice,
deltaTimestamp,
gyro[0],
gyro[1],
@ -444,9 +461,14 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
fun onEmulationStopped(status: Int) {
if (status == 0) {
if (status == 0 && emulationViewModel.programChanged.value == -1) {
finish()
}
emulationViewModel.setEmulationStopped(true)
}
fun onProgramChanged(programIndex: Int) {
emulationViewModel.setProgramChanged(programIndex)
}
private fun startMotionSensorListener() {
@ -475,12 +497,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
activity.startActivity(launcher)
}
fun stopForegroundService(activity: Activity) {
val startIntent = Intent(activity, ForegroundService::class.java)
startIntent.action = ForegroundService.ACTION_STOP
activity.startForegroundService(startIntent)
}
private fun areCoordinatesOutside(view: View?, x: Float, y: Float): Boolean {
if (view == null) {
return true

View File

@ -14,16 +14,21 @@ import androidx.recyclerview.widget.RecyclerView
* Generic adapter that implements an [AsyncDifferConfig] and covers some of the basic boilerplate
* code used in every [RecyclerView].
* Type assigned to [Model] must inherit from [Object] in order to be compared properly.
* @param exact Decides whether each item will be compared by reference or by their contents
*/
abstract class AbstractDiffAdapter<Model : Any, Holder : AbstractViewHolder<Model>> :
ListAdapter<Model, Holder>(AsyncDifferConfig.Builder(DiffCallback<Model>()).build()) {
abstract class AbstractDiffAdapter<Model : Any, Holder : AbstractViewHolder<Model>>(
exact: Boolean = true
) : ListAdapter<Model, Holder>(AsyncDifferConfig.Builder(DiffCallback<Model>(exact)).build()) {
override fun onBindViewHolder(holder: Holder, position: Int) =
holder.bind(currentList[position])
private class DiffCallback<Model> : DiffUtil.ItemCallback<Model>() {
private class DiffCallback<Model>(val exact: Boolean) : DiffUtil.ItemCallback<Model>() {
override fun areItemsTheSame(oldItem: Model & Any, newItem: Model & Any): Boolean {
if (exact) {
return oldItem === newItem
}
return oldItem == newItem
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: Model & Any, newItem: Model & Any): Boolean {

View File

@ -6,27 +6,32 @@ package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import org.yuzu.yuzu_emu.databinding.ListItemAddonBinding
import org.yuzu.yuzu_emu.model.Addon
import org.yuzu.yuzu_emu.model.Patch
import org.yuzu.yuzu_emu.model.AddonViewModel
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class AddonAdapter : AbstractDiffAdapter<Addon, AddonAdapter.AddonViewHolder>() {
class AddonAdapter(val addonViewModel: AddonViewModel) :
AbstractDiffAdapter<Patch, AddonAdapter.AddonViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddonViewHolder {
ListItemAddonBinding.inflate(LayoutInflater.from(parent.context), parent, false)
.also { return AddonViewHolder(it) }
}
inner class AddonViewHolder(val binding: ListItemAddonBinding) :
AbstractViewHolder<Addon>(binding) {
override fun bind(model: Addon) {
AbstractViewHolder<Patch>(binding) {
override fun bind(model: Patch) {
binding.root.setOnClickListener {
binding.addonSwitch.isChecked = !binding.addonSwitch.isChecked
binding.addonCheckbox.isChecked = !binding.addonCheckbox.isChecked
}
binding.title.text = model.title
binding.title.text = model.name
binding.version.text = model.version
binding.addonSwitch.setOnCheckedChangeListener { _, checked ->
binding.addonCheckbox.setOnCheckedChangeListener { _, checked ->
model.enabled = checked
}
binding.addonSwitch.isChecked = model.enabled
binding.addonCheckbox.isChecked = model.enabled
binding.buttonDelete.setOnClickListener {
addonViewModel.setAddonToDelete(model)
}
}
}
}

View File

@ -3,14 +3,15 @@
package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardDriverOptionBinding
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.model.Driver
import org.yuzu.yuzu_emu.model.DriverViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class DriverAdapter(private val driverViewModel: DriverViewModel) :
@ -43,29 +44,15 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
}
// Delay marquee by 3s
title.postDelayed(
{
title.isSelected = true
title.ellipsize = TextUtils.TruncateAt.MARQUEE
version.isSelected = true
version.ellipsize = TextUtils.TruncateAt.MARQUEE
description.isSelected = true
description.ellipsize = TextUtils.TruncateAt.MARQUEE
},
3000
)
title.marquee()
version.marquee()
description.marquee()
title.text = model.title
version.text = model.version
description.text = model.description
if (model.description.isNotEmpty()) {
version.visibility = View.VISIBLE
description.visibility = View.VISIBLE
buttonDelete.visibility = View.VISIBLE
} else {
version.visibility = View.GONE
description.visibility = View.GONE
buttonDelete.visibility = View.GONE
}
buttonDelete.setVisible(
model.title != binding.root.context.getString(R.string.system_gpu_driver)
)
}
}
}

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.adapters
import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
@ -12,6 +11,7 @@ import org.yuzu.yuzu_emu.databinding.CardFolderBinding
import org.yuzu.yuzu_emu.fragments.GameFolderPropertiesDialogFragment
import org.yuzu.yuzu_emu.model.GameDir
import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesViewModel) :
@ -29,13 +29,7 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
override fun bind(model: GameDir) {
binding.apply {
path.text = Uri.parse(model.uriString).path
path.postDelayed(
{
path.isSelected = true
path.ellipsize = TextUtils.TruncateAt.MARQUEE
},
3000
)
path.marquee()
buttonEdit.setOnClickListener {
GameFolderPropertiesDialogFragment.newInstance(model)

View File

@ -3,11 +3,7 @@
package org.yuzu.yuzu_emu.adapters
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
@ -15,10 +11,6 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@ -30,15 +22,15 @@ import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.databinding.CardGameBinding
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.utils.GameIconUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class GameAdapter(private val activity: AppCompatActivity) :
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>() {
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder {
CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
.also { return GameViewHolder(it) }
@ -52,14 +44,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
binding.textGameTitle.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ")
binding.textGameTitle.postDelayed(
{
binding.textGameTitle.ellipsize = TextUtils.TruncateAt.MARQUEE
binding.textGameTitle.isSelected = true
},
3000
)
binding.textGameTitle.marquee()
binding.cardGame.setOnClickListener { onClick(model) }
binding.cardGame.setOnLongClickListener { onLongClick(model) }
}
@ -89,36 +74,13 @@ class GameAdapter(private val activity: AppCompatActivity) :
)
.apply()
val openIntent =
Intent(YuzuApplication.appContext, EmulationActivity::class.java).apply {
action = Intent.ACTION_VIEW
data = Uri.parse(game.path)
}
activity.lifecycleScope.launch {
withContext(Dispatchers.IO) {
val layerDrawable = ResourcesCompat.getDrawable(
YuzuApplication.appContext.resources,
R.drawable.shortcut,
null
) as LayerDrawable
layerDrawable.setDrawableByLayerId(
R.id.shortcut_foreground,
GameIconUtils.getGameIcon(activity, game)
.toDrawable(YuzuApplication.appContext.resources)
)
val inset = YuzuApplication.appContext.resources
.getDimensionPixelSize(R.dimen.icon_inset)
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
val shortcut =
ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
.setShortLabel(game.title)
.setIcon(
IconCompat.createWithAdaptiveBitmap(
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
)
)
.setIntent(openIntent)
.setIcon(GameIconUtils.getShortcutIcon(activity, game))
.setIntent(game.launchIntent)
.build()
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
}

View File

@ -3,21 +3,18 @@
package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.launch
import org.yuzu.yuzu_emu.databinding.CardInstallableIconBinding
import org.yuzu.yuzu_emu.databinding.CardSimpleOutlinedBinding
import org.yuzu.yuzu_emu.model.GameProperty
import org.yuzu.yuzu_emu.model.InstallableProperty
import org.yuzu.yuzu_emu.model.SubmenuProperty
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.utils.collect
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class GamePropertiesAdapter(
@ -76,23 +73,15 @@ class GamePropertiesAdapter(
)
)
binding.details.postDelayed({
binding.details.isSelected = true
binding.details.ellipsize = TextUtils.TruncateAt.MARQUEE
}, 3000)
binding.details.marquee()
if (submenuProperty.details != null) {
binding.details.visibility = View.VISIBLE
binding.details.setVisible(true)
binding.details.text = submenuProperty.details.invoke()
} else if (submenuProperty.detailsFlow != null) {
binding.details.visibility = View.VISIBLE
viewLifecycle.lifecycleScope.launch {
viewLifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
submenuProperty.detailsFlow.collect { binding.details.text = it }
}
}
binding.details.setVisible(true)
submenuProperty.detailsFlow.collect(viewLifecycle) { binding.details.text = it }
} else {
binding.details.visibility = View.GONE
binding.details.setVisible(false)
}
}
}
@ -112,14 +101,10 @@ class GamePropertiesAdapter(
)
)
if (installableProperty.install != null) {
binding.buttonInstall.visibility = View.VISIBLE
binding.buttonInstall.setOnClickListener { installableProperty.install.invoke() }
}
if (installableProperty.export != null) {
binding.buttonExport.visibility = View.VISIBLE
binding.buttonExport.setOnClickListener { installableProperty.export.invoke() }
}
binding.buttonInstall.setVisible(installableProperty.install != null)
binding.buttonInstall.setOnClickListener { installableProperty.install?.invoke() }
binding.buttonExport.setVisible(installableProperty.export != null)
binding.buttonExport.setOnClickListener { installableProperty.export?.invoke() }
}
}

View File

@ -3,22 +3,19 @@
package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.launch
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment
import org.yuzu.yuzu_emu.model.HomeSetting
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.utils.collect
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class HomeSettingAdapter(
@ -59,18 +56,8 @@ class HomeSettingAdapter(
binding.optionIcon.alpha = 0.5f
}
viewLifecycle.lifecycleScope.launch {
viewLifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {
model.details.collect { updateOptionDetails(it) }
}
}
binding.optionDetail.postDelayed(
{
binding.optionDetail.ellipsize = TextUtils.TruncateAt.MARQUEE
binding.optionDetail.isSelected = true
},
3000
)
model.details.collect(viewLifecycle) { updateOptionDetails(it) }
binding.optionDetail.marquee()
binding.root.setOnClickListener { onClick(model) }
}
@ -90,7 +77,7 @@ class HomeSettingAdapter(
private fun updateOptionDetails(detailString: String) {
if (detailString.isNotEmpty()) {
binding.optionDetail.text = detailString
binding.optionDetail.visibility = View.VISIBLE
binding.optionDetail.setVisible(true)
}
}
}

View File

@ -4,10 +4,10 @@
package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.yuzu.yuzu_emu.databinding.CardInstallableBinding
import org.yuzu.yuzu_emu.model.Installable
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class InstallableAdapter(installables: List<Installable>) :
@ -26,14 +26,10 @@ class InstallableAdapter(installables: List<Installable>) :
binding.title.setText(model.titleId)
binding.description.setText(model.descriptionId)
if (model.install != null) {
binding.buttonInstall.visibility = View.VISIBLE
binding.buttonInstall.setOnClickListener { model.install.invoke() }
}
if (model.export != null) {
binding.buttonExport.visibility = View.VISIBLE
binding.buttonExport.setOnClickListener { model.export.invoke() }
}
binding.buttonInstall.setVisible(model.install != null)
binding.buttonInstall.setOnClickListener { model.install?.invoke() }
binding.buttonExport.setVisible(model.export != null)
binding.buttonExport.setOnClickListener { model.export?.invoke() }
}
}
}

View File

@ -4,12 +4,12 @@
package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.fragments.LicenseBottomSheetDialogFragment
import org.yuzu.yuzu_emu.model.License
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class LicenseAdapter(private val activity: AppCompatActivity, licenses: List<License>) :
@ -25,7 +25,7 @@ class LicenseAdapter(private val activity: AppCompatActivity, licenses: List<Lic
binding.apply {
textSettingName.text = root.context.getString(model.titleId)
textSettingDescription.text = root.context.getString(model.descriptionId)
textSettingValue.visibility = View.GONE
textSettingValue.setVisible(false)
root.setOnClickListener { onClick(model) }
}

View File

@ -5,7 +5,6 @@ package org.yuzu.yuzu_emu.adapters
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
@ -17,6 +16,7 @@ import org.yuzu.yuzu_emu.model.SetupCallback
import org.yuzu.yuzu_emu.model.SetupPage
import org.yuzu.yuzu_emu.model.StepState
import org.yuzu.yuzu_emu.utils.ViewUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class SetupAdapter(val activity: AppCompatActivity, pages: List<SetupPage>) :
@ -30,8 +30,8 @@ class SetupAdapter(val activity: AppCompatActivity, pages: List<SetupPage>) :
AbstractViewHolder<SetupPage>(binding), SetupCallback {
override fun bind(model: SetupPage) {
if (model.stepCompleted.invoke() == StepState.COMPLETE) {
binding.buttonAction.visibility = View.INVISIBLE
binding.textConfirmation.visibility = View.VISIBLE
binding.buttonAction.setVisible(visible = false, gone = false)
binding.textConfirmation.setVisible(true)
}
binding.icon.setImageDrawable(

View File

@ -0,0 +1,416 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input
import org.yuzu.yuzu_emu.features.input.model.NativeButton
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
import org.yuzu.yuzu_emu.features.input.model.InputType
import org.yuzu.yuzu_emu.features.input.model.ButtonName
import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ParamPackage
import android.view.InputDevice
object NativeInput {
/**
* Default controller id for each device
*/
const val Player1Device = 0
const val Player2Device = 1
const val Player3Device = 2
const val Player4Device = 3
const val Player5Device = 4
const val Player6Device = 5
const val Player7Device = 6
const val Player8Device = 7
const val ConsoleDevice = 8
/**
* Button states
*/
object ButtonState {
const val RELEASED = 0
const val PRESSED = 1
}
/**
* Returns true if pro controller isn't available and handheld is.
* Intended to check where the input overlay should direct its inputs.
*/
external fun isHandheldOnly(): Boolean
/**
* Handles button press events for a gamepad.
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
* @param port Port determined by controller connection order.
* @param buttonId The Android Keycode corresponding to this event.
* @param action Mask identifying which action is happening (button pressed down, or button released).
*/
external fun onGamePadButtonEvent(
guid: String,
port: Int,
buttonId: Int,
action: Int
)
/**
* Handles axis movement events.
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
* @param port Port determined by controller connection order.
* @param axis The axis ID.
* @param value Value along the given axis.
*/
external fun onGamePadAxisEvent(guid: String, port: Int, axis: Int, value: Float)
/**
* Handles motion events.
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
* @param port Port determined by controller connection order.
* @param deltaTimestamp The finger id corresponding to this event.
* @param xGyro The value of the x-axis for the gyroscope.
* @param yGyro The value of the y-axis for the gyroscope.
* @param zGyro The value of the z-axis for the gyroscope.
* @param xAccel The value of the x-axis for the accelerometer.
* @param yAccel The value of the y-axis for the accelerometer.
* @param zAccel The value of the z-axis for the accelerometer.
*/
external fun onGamePadMotionEvent(
guid: String,
port: Int,
deltaTimestamp: Long,
xGyro: Float,
yGyro: Float,
zGyro: Float,
xAccel: Float,
yAccel: Float,
zAccel: Float
)
/**
* Signals and load a nfc tag
* @param data Byte array containing all the data from a nfc tag.
*/
external fun onReadNfcTag(data: ByteArray?)
/**
* Removes current loaded nfc tag.
*/
external fun onRemoveNfcTag()
/**
* Handles touch press events.
* @param fingerId The finger id corresponding to this event.
* @param xAxis The value of the x-axis on the touchscreen.
* @param yAxis The value of the y-axis on the touchscreen.
*/
external fun onTouchPressed(fingerId: Int, xAxis: Float, yAxis: Float)
/**
* Handles touch movement.
* @param fingerId The finger id corresponding to this event.
* @param xAxis The value of the x-axis on the touchscreen.
* @param yAxis The value of the y-axis on the touchscreen.
*/
external fun onTouchMoved(fingerId: Int, xAxis: Float, yAxis: Float)
/**
* Handles touch release events.
* @param fingerId The finger id corresponding to this event
*/
external fun onTouchReleased(fingerId: Int)
/**
* Sends a button input to the global virtual controllers.
* @param port Port determined by controller connection order.
* @param button The [NativeButton] corresponding to this event.
* @param action Mask identifying which action is happening (button pressed down, or button released).
*/
fun onOverlayButtonEvent(port: Int, button: NativeButton, action: Int) =
onOverlayButtonEventImpl(port, button.int, action)
private external fun onOverlayButtonEventImpl(port: Int, buttonId: Int, action: Int)
/**
* Sends a joystick input to the global virtual controllers.
* @param port Port determined by controller connection order.
* @param stick The [NativeAnalog] corresponding to this event.
* @param xAxis Value along the X axis.
* @param yAxis Value along the Y axis.
*/
fun onOverlayJoystickEvent(port: Int, stick: NativeAnalog, xAxis: Float, yAxis: Float) =
onOverlayJoystickEventImpl(port, stick.int, xAxis, yAxis)
private external fun onOverlayJoystickEventImpl(
port: Int,
stickId: Int,
xAxis: Float,
yAxis: Float
)
/**
* Handles motion events for the global virtual controllers.
* @param port Port determined by controller connection order
* @param deltaTimestamp The finger id corresponding to this event.
* @param xGyro The value of the x-axis for the gyroscope.
* @param yGyro The value of the y-axis for the gyroscope.
* @param zGyro The value of the z-axis for the gyroscope.
* @param xAccel The value of the x-axis for the accelerometer.
* @param yAccel The value of the y-axis for the accelerometer.
* @param zAccel The value of the z-axis for the accelerometer.
*/
external fun onDeviceMotionEvent(
port: Int,
deltaTimestamp: Long,
xGyro: Float,
yGyro: Float,
zGyro: Float,
xAccel: Float,
yAccel: Float,
zAccel: Float
)
/**
* Reloads all input devices from the currently loaded Settings::values.players into HID Core
*/
external fun reloadInputDevices()
/**
* Registers a controller to be used with mapping
* @param device An [InputDevice] or the input overlay wrapped with [YuzuInputDevice]
*/
external fun registerController(device: YuzuInputDevice)
/**
* Gets the names of input devices that have been registered with the input subsystem via [registerController]
*/
external fun getInputDevices(): Array<String>
/**
* Reads all input profiles from disk. Must be called before creating a profile picker.
*/
external fun loadInputProfiles()
/**
* Gets the names of each available input profile.
*/
external fun getInputProfileNames(): Array<String>
/**
* Checks if the user-provided name for an input profile is valid.
* @param name User-provided name for an input profile.
* @return Whether [name] is valid or not.
*/
external fun isProfileNameValid(name: String): Boolean
/**
* Creates a new input profile.
* @param name The new profile's name.
* @param playerIndex Index of the player that's currently being edited. Used to write the profile
* name to this player's config.
* @return Whether creating the profile was successful or not.
*/
external fun createProfile(name: String, playerIndex: Int): Boolean
/**
* Deletes an input profile.
* @param name Name of the profile to delete.
* @param playerIndex Index of the player that's currently being edited. Used to remove the profile
* name from this player's config if they have it loaded.
* @return Whether deleting this profile was successful or not.
*/
external fun deleteProfile(name: String, playerIndex: Int): Boolean
/**
* Loads an input profile.
* @param name Name of the input profile to load.
* @param playerIndex Index of the player that will have this profile loaded.
* @return Whether loading this profile was successful or not.
*/
external fun loadProfile(name: String, playerIndex: Int): Boolean
/**
* Saves an input profile.
* @param name Name of the profile to save.
* @param playerIndex Index of the player that's currently being edited. Used to write the profile
* name to this player's config.
* @return Whether saving the profile was successful or not.
*/
external fun saveProfile(name: String, playerIndex: Int): Boolean
/**
* Intended to be used immediately before a call to [NativeConfig.saveControlPlayerValues]
* Must be used while per-game config is loaded.
*/
external fun loadPerGameConfiguration(
playerIndex: Int,
selectedIndex: Int,
selectedProfileName: String
)
/**
* Tells the input subsystem to start listening for inputs to map.
* @param type Type of input to map as shown by the int property in each [InputType].
*/
external fun beginMapping(type: Int)
/**
* Gets an input's [ParamPackage] as a serialized string. Used for input verification before mapping.
* Must be run after [beginMapping] and before [stopMapping].
*/
external fun getNextInput(): String
/**
* Tells the input subsystem to stop listening for inputs to map.
*/
external fun stopMapping()
/**
* Updates a controller's mappings with auto-mapping params.
* @param playerIndex Index of the player to auto-map.
* @param deviceParams [ParamPackage] representing the device to auto-map as received
* from [getInputDevices].
* @param displayName Name of the device to auto-map as received from the "display" param in [deviceParams].
* Intended to be a way to provide a default name for a controller if the "display" param is empty.
*/
fun updateMappingsWithDefault(
playerIndex: Int,
deviceParams: ParamPackage,
displayName: String
) = updateMappingsWithDefaultImpl(playerIndex, deviceParams.serialize(), displayName)
private external fun updateMappingsWithDefaultImpl(
playerIndex: Int,
deviceParams: String,
displayName: String
)
/**
* Gets the params for a specific button.
* @param playerIndex Index of the player to get params from.
* @param button The [NativeButton] to get params for.
* @return A [ParamPackage] representing a player's specific button.
*/
fun getButtonParam(playerIndex: Int, button: NativeButton): ParamPackage =
ParamPackage(getButtonParamImpl(playerIndex, button.int))
private external fun getButtonParamImpl(playerIndex: Int, buttonId: Int): String
/**
* Sets the params for a specific button.
* @param playerIndex Index of the player to set params for.
* @param button The [NativeButton] to set params for.
* @param param A [ParamPackage] to set.
*/
fun setButtonParam(playerIndex: Int, button: NativeButton, param: ParamPackage) =
setButtonParamImpl(playerIndex, button.int, param.serialize())
private external fun setButtonParamImpl(playerIndex: Int, buttonId: Int, param: String)
/**
* Gets the params for a specific stick.
* @param playerIndex Index of the player to get params from.
* @param stick The [NativeAnalog] to get params for.
* @return A [ParamPackage] representing a player's specific stick.
*/
fun getStickParam(playerIndex: Int, stick: NativeAnalog): ParamPackage =
ParamPackage(getStickParamImpl(playerIndex, stick.int))
private external fun getStickParamImpl(playerIndex: Int, stickId: Int): String
/**
* Sets the params for a specific stick.
* @param playerIndex Index of the player to set params for.
* @param stick The [NativeAnalog] to set params for.
* @param param A [ParamPackage] to set.
*/
fun setStickParam(playerIndex: Int, stick: NativeAnalog, param: ParamPackage) =
setStickParamImpl(playerIndex, stick.int, param.serialize())
private external fun setStickParamImpl(playerIndex: Int, stickId: Int, param: String)
/**
* Gets the int representation of a [ButtonName]. Tells you what to show as the mapped input for
* a button/analog/other.
* @param param A [ParamPackage] that represents a specific button's params.
* @return The [ButtonName] for [param].
*/
fun getButtonName(param: ParamPackage): ButtonName =
ButtonName.from(getButtonNameImpl(param.serialize()))
private external fun getButtonNameImpl(param: String): Int
/**
* Gets each supported [NpadStyleIndex] for a given player.
* @param playerIndex Index of the player to get supported indexes for.
* @return List of each supported [NpadStyleIndex].
*/
fun getSupportedStyleTags(playerIndex: Int): List<NpadStyleIndex> =
getSupportedStyleTagsImpl(playerIndex).map { NpadStyleIndex.from(it) }
private external fun getSupportedStyleTagsImpl(playerIndex: Int): IntArray
/**
* Gets the [NpadStyleIndex] for a given player.
* @param playerIndex Index of the player to get an [NpadStyleIndex] from.
* @return The [NpadStyleIndex] for a given player.
*/
fun getStyleIndex(playerIndex: Int): NpadStyleIndex =
NpadStyleIndex.from(getStyleIndexImpl(playerIndex))
private external fun getStyleIndexImpl(playerIndex: Int): Int
/**
* Sets the [NpadStyleIndex] for a given player.
* @param playerIndex Index of the player to change.
* @param style The new style to set.
*/
fun setStyleIndex(playerIndex: Int, style: NpadStyleIndex) =
setStyleIndexImpl(playerIndex, style.int)
private external fun setStyleIndexImpl(playerIndex: Int, styleIndex: Int)
/**
* Checks if a device is a controller.
* @param params [ParamPackage] for an input device retrieved from [getInputDevices]
* @return Whether the device is a controller or not.
*/
fun isController(params: ParamPackage): Boolean = isControllerImpl(params.serialize())
private external fun isControllerImpl(params: String): Boolean
/**
* Checks if a controller is connected
* @param playerIndex Index of the player to check.
* @return Whether the player is connected or not.
*/
external fun getIsConnected(playerIndex: Int): Boolean
/**
* Connects/disconnects a controller and ensures that connection order stays in-tact.
* @param playerIndex Index of the player to connect/disconnect.
* @param connected Whether to connect or disconnect this controller.
*/
fun connectControllers(playerIndex: Int, connected: Boolean = true) {
val connectedControllers = mutableListOf<Boolean>().apply {
if (connected) {
for (i in 0 until 8) {
add(i <= playerIndex)
}
} else {
for (i in 0 until 8) {
add(i < playerIndex)
}
}
}
connectControllersImpl(connectedControllers.toBooleanArray())
}
private external fun connectControllersImpl(connected: BooleanArray)
/**
* Resets all of the button and analog mappings for a player.
* @param playerIndex Index of the player that will have its mappings reset.
*/
external fun resetControllerMappings(playerIndex: Int)
}

View File

@ -0,0 +1,93 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input
import android.view.InputDevice
import androidx.annotation.Keep
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.utils.InputHandler.getGUID
@Keep
interface YuzuInputDevice {
fun getName(): String
fun getGUID(): String
fun getPort(): Int
fun getSupportsVibration(): Boolean
fun vibrate(intensity: Float)
fun getAxes(): Array<Int> = arrayOf()
fun hasKeys(keys: IntArray): BooleanArray = BooleanArray(0)
}
class YuzuPhysicalDevice(
private val device: InputDevice,
private val port: Int,
useSystemVibrator: Boolean
) : YuzuInputDevice {
private val vibrator = if (useSystemVibrator) {
YuzuVibrator.getSystemVibrator()
} else {
YuzuVibrator.getControllerVibrator(device)
}
override fun getName(): String {
return device.name
}
override fun getGUID(): String {
return device.getGUID()
}
override fun getPort(): Int {
return port
}
override fun getSupportsVibration(): Boolean {
return vibrator.supportsVibration()
}
override fun vibrate(intensity: Float) {
vibrator.vibrate(intensity)
}
override fun getAxes(): Array<Int> = device.motionRanges.map { it.axis }.toTypedArray()
override fun hasKeys(keys: IntArray): BooleanArray = device.hasKeys(*keys)
}
class YuzuInputOverlayDevice(
private val vibration: Boolean,
private val port: Int
) : YuzuInputDevice {
private val vibrator = YuzuVibrator.getSystemVibrator()
override fun getName(): String {
return YuzuApplication.appContext.getString(R.string.input_overlay)
}
override fun getGUID(): String {
return "00000000000000000000000000000000"
}
override fun getPort(): Int {
return port
}
override fun getSupportsVibration(): Boolean {
if (vibration) {
return vibrator.supportsVibration()
}
return false
}
override fun vibrate(intensity: Float) {
if (vibration) {
vibrator.vibrate(intensity)
}
}
}

View File

@ -0,0 +1,76 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input
import android.content.Context
import android.os.Build
import android.os.CombinedVibration
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.view.InputDevice
import androidx.annotation.Keep
import androidx.annotation.RequiresApi
import org.yuzu.yuzu_emu.YuzuApplication
@Keep
@Suppress("DEPRECATION")
interface YuzuVibrator {
fun supportsVibration(): Boolean
fun vibrate(intensity: Float)
companion object {
fun getControllerVibrator(device: InputDevice): YuzuVibrator =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
YuzuVibratorManager(device.vibratorManager)
} else {
YuzuVibratorManagerCompat(device.vibrator)
}
fun getSystemVibrator(): YuzuVibrator =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val vibratorManager = YuzuApplication.appContext
.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
YuzuVibratorManager(vibratorManager)
} else {
val vibrator = YuzuApplication.appContext
.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
YuzuVibratorManagerCompat(vibrator)
}
fun getVibrationEffect(intensity: Float): VibrationEffect? {
if (intensity > 0f) {
return VibrationEffect.createOneShot(
50,
(255.0 * intensity).toInt().coerceIn(1, 255)
)
}
return null
}
}
}
@RequiresApi(Build.VERSION_CODES.S)
class YuzuVibratorManager(private val vibratorManager: VibratorManager) : YuzuVibrator {
override fun supportsVibration(): Boolean {
return vibratorManager.vibratorIds.isNotEmpty()
}
override fun vibrate(intensity: Float) {
val vibration = YuzuVibrator.getVibrationEffect(intensity) ?: return
vibratorManager.vibrate(CombinedVibration.createParallel(vibration))
}
}
class YuzuVibratorManagerCompat(private val vibrator: Vibrator) : YuzuVibrator {
override fun supportsVibration(): Boolean {
return vibrator.hasVibrator()
}
override fun vibrate(intensity: Float) {
val vibration = YuzuVibrator.getVibrationEffect(intensity) ?: return
vibrator.vibrate(vibration)
}
}

View File

@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
enum class AnalogDirection(val int: Int, val param: String) {
Up(0, "up"),
Down(1, "down"),
Left(2, "left"),
Right(3, "right")
}

View File

@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
// Loosely matches the enum in common/input.h
enum class ButtonName(val int: Int) {
Invalid(1),
// This will display the engine name instead of the button name
Engine(2),
// This will display the button by value instead of the button name
Value(3);
companion object {
fun from(int: Int): ButtonName = entries.firstOrNull { it.int == int } ?: Invalid
}
}

View File

@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
// Must match the corresponding enum in input_common/main.h
enum class InputType(val int: Int) {
None(0),
Button(1),
Stick(2),
Motion(3),
Touch(4)
}

View File

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
// Must match enum in src/common/settings_input.h
enum class NativeAnalog(val int: Int) {
LStick(0),
RStick(1);
companion object {
fun from(int: Int): NativeAnalog = entries.firstOrNull { it.int == int } ?: LStick
}
}

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
// Must match enum in src/common/settings_input.h
enum class NativeButton(val int: Int) {
A(0),
B(1),
X(2),
Y(3),
LStick(4),
RStick(5),
L(6),
R(7),
ZL(8),
ZR(9),
Plus(10),
Minus(11),
DLeft(12),
DUp(13),
DRight(14),
DDown(15),
SLLeft(16),
SRLeft(17),
Home(18),
Capture(19),
SLRight(20),
SRRight(21);
companion object {
fun from(int: Int): NativeButton = entries.firstOrNull { it.int == int } ?: A
}
}

View File

@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
// Must match enum in src/common/settings_input.h
enum class NativeTrigger(val int: Int) {
LTrigger(0),
RTrigger(1)
}

View File

@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.R
// Must match enum in src/core/hid/hid_types.h
enum class NpadStyleIndex(val int: Int, @StringRes val nameId: Int = 0) {
None(0),
Fullkey(3, R.string.pro_controller),
Handheld(4, R.string.handheld),
HandheldNES(4),
JoyconDual(5, R.string.dual_joycons),
JoyconLeft(6, R.string.left_joycon),
JoyconRight(7, R.string.right_joycon),
GameCube(8, R.string.gamecube_controller),
Pokeball(9),
NES(10),
SNES(12),
N64(13),
SegaGenesis(14),
SystemExt(32),
System(33);
companion object {
fun from(int: Int): NpadStyleIndex = entries.firstOrNull { it.int == int } ?: None
}
}

View File

@ -0,0 +1,83 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.input.model
import androidx.annotation.Keep
@Keep
data class PlayerInput(
var connected: Boolean,
var buttons: Array<String>,
var analogs: Array<String>,
var motions: Array<String>,
var vibrationEnabled: Boolean,
var vibrationStrength: Int,
var bodyColorLeft: Long,
var bodyColorRight: Long,
var buttonColorLeft: Long,
var buttonColorRight: Long,
var profileName: String,
var useSystemVibrator: Boolean
) {
// It's recommended to use the generated equals() and hashCode() methods
// when using arrays in a data class
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PlayerInput
if (connected != other.connected) return false
if (!buttons.contentEquals(other.buttons)) return false
if (!analogs.contentEquals(other.analogs)) return false
if (!motions.contentEquals(other.motions)) return false
if (vibrationEnabled != other.vibrationEnabled) return false
if (vibrationStrength != other.vibrationStrength) return false
if (bodyColorLeft != other.bodyColorLeft) return false
if (bodyColorRight != other.bodyColorRight) return false
if (buttonColorLeft != other.buttonColorLeft) return false
if (buttonColorRight != other.buttonColorRight) return false
if (profileName != other.profileName) return false
return useSystemVibrator == other.useSystemVibrator
}
override fun hashCode(): Int {
var result = connected.hashCode()
result = 31 * result + buttons.contentHashCode()
result = 31 * result + analogs.contentHashCode()
result = 31 * result + motions.contentHashCode()
result = 31 * result + vibrationEnabled.hashCode()
result = 31 * result + vibrationStrength
result = 31 * result + bodyColorLeft.hashCode()
result = 31 * result + bodyColorRight.hashCode()
result = 31 * result + buttonColorLeft.hashCode()
result = 31 * result + buttonColorRight.hashCode()
result = 31 * result + profileName.hashCode()
result = 31 * result + useSystemVibrator.hashCode()
return result
}
fun hasMapping(): Boolean {
var hasMapping = false
buttons.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
hasMapping = true
}
}
analogs.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
hasMapping = true
}
}
motions.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
hasMapping = true
}
}
return hasMapping
}
}

View File

@ -25,7 +25,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
HAPTIC_FEEDBACK("haptic_feedback"),
SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"),
SHOW_INPUT_OVERLAY("show_input_overlay"),
TOUCHSCREEN("touchscreen");
TOUCHSCREEN("touchscreen"),
SHOW_THERMAL_OVERLAY("show_thermal_overlay");
override fun getBoolean(needsGlobal: Boolean): Boolean =
NativeConfig.getBoolean(key, needsGlobal)

View File

@ -23,7 +23,10 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
THEME("theme"),
THEME_MODE("theme_mode"),
OVERLAY_SCALE("control_scale"),
OVERLAY_OPACITY("control_opacity");
OVERLAY_OPACITY("control_opacity"),
LOCK_DRAWER("lock_drawer"),
VERTICAL_ALIGNMENT("vertical_alignment"),
FSR_SHARPENING_SLIDER("fsr_sharpening_slider");
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)

View File

@ -4,17 +4,30 @@
package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
object Settings {
enum class MenuTag(val titleId: Int) {
enum class MenuTag(val titleId: Int = 0) {
SECTION_ROOT(R.string.advanced_settings),
SECTION_SYSTEM(R.string.preferences_system),
SECTION_RENDERER(R.string.preferences_graphics),
SECTION_AUDIO(R.string.preferences_audio),
SECTION_INPUT(R.string.preferences_controls),
SECTION_INPUT_PLAYER_ONE,
SECTION_INPUT_PLAYER_TWO,
SECTION_INPUT_PLAYER_THREE,
SECTION_INPUT_PLAYER_FOUR,
SECTION_INPUT_PLAYER_FIVE,
SECTION_INPUT_PLAYER_SIX,
SECTION_INPUT_PLAYER_SEVEN,
SECTION_INPUT_PLAYER_EIGHT,
SECTION_THEME(R.string.preferences_theme),
SECTION_DEBUG(R.string.preferences_debug);
}
fun getPlayerString(player: Int): String =
YuzuApplication.appContext.getString(R.string.preferences_player, player)
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
@ -93,4 +106,15 @@ object Settings {
entries.firstOrNull { it.int == int } ?: Unspecified
}
}
enum class EmulationVerticalAlignment(val int: Int) {
Top(1),
Center(0),
Bottom(2);
companion object {
fun from(int: Int): EmulationVerticalAlignment =
entries.firstOrNull { it.int == int } ?: Center
}
}
}

View File

@ -6,7 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig
enum class StringSetting(override val key: String) : AbstractStringSetting {
DRIVER_PATH("driver_path");
DRIVER_PATH("driver_path"),
DEVICE_NAME("device_name");
override fun getString(needsGlobal: Boolean): String = NativeConfig.getString(key, needsGlobal)

View File

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.AnalogDirection
import org.yuzu.yuzu_emu.features.input.model.InputType
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
import org.yuzu.yuzu_emu.utils.ParamPackage
class AnalogInputSetting(
override val playerIndex: Int,
val nativeAnalog: NativeAnalog,
val analogDirection: AnalogDirection,
@StringRes titleId: Int = 0,
titleString: String = ""
) : InputSetting(titleId, titleString) {
override val type = TYPE_INPUT
override val inputType = InputType.Stick
override fun getSelectedValue(): String {
val params = NativeInput.getStickParam(playerIndex, nativeAnalog)
val analog = analogToText(params, analogDirection.param)
return getDisplayString(params, analog)
}
override fun setSelectedValue(param: ParamPackage) =
NativeInput.setStickParam(playerIndex, nativeAnalog, param)
}

View File

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.utils.ParamPackage
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.InputType
import org.yuzu.yuzu_emu.features.input.model.NativeButton
class ButtonInputSetting(
override val playerIndex: Int,
val nativeButton: NativeButton,
@StringRes titleId: Int = 0,
titleString: String = ""
) : InputSetting(titleId, titleString) {
override val type = TYPE_INPUT
override val inputType = InputType.Button
override fun getSelectedValue(): String {
val params = NativeInput.getButtonParam(playerIndex, nativeButton)
val button = buttonToText(params)
return getDisplayString(params, button)
}
override fun setSelectedValue(param: ParamPackage) =
NativeInput.setButtonParam(playerIndex, nativeButton, param)
}

View File

@ -3,13 +3,16 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractLongSetting
class DateTimeSetting(
private val longSetting: AbstractLongSetting,
titleId: Int,
descriptionId: Int
) : SettingsItem(longSetting, titleId, descriptionId) {
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = ""
) : SettingsItem(longSetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_DATETIME_SETTING
fun getValue(needsGlobal: Boolean = false): Long = longSetting.getLong(needsGlobal)

View File

@ -3,8 +3,11 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
class HeaderSetting(
titleId: Int
) : SettingsItem(emptySetting, titleId, 0) {
@StringRes titleId: Int = 0,
titleString: String = ""
) : SettingsItem(emptySetting, titleId, titleString, 0, "") {
override val type = TYPE_HEADER
}

View File

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.utils.NativeConfig
class InputProfileSetting(private val playerIndex: Int) :
SettingsItem(emptySetting, R.string.profile, "", 0, "") {
override val type = TYPE_INPUT_PROFILE
fun getCurrentProfile(): String =
NativeConfig.getInputSettings(true)[playerIndex].profileName
fun getProfileNames(): Array<String> = NativeInput.getInputProfileNames()
fun isProfileNameValid(name: String): Boolean = NativeInput.isProfileNameValid(name)
fun createProfile(name: String): Boolean = NativeInput.createProfile(name, playerIndex)
fun deleteProfile(name: String): Boolean = NativeInput.deleteProfile(name, playerIndex)
fun loadProfile(name: String): Boolean {
val result = NativeInput.loadProfile(name, playerIndex)
NativeInput.reloadInputDevices()
return result
}
fun saveProfile(name: String): Boolean = NativeInput.saveProfile(name, playerIndex)
}

View File

@ -0,0 +1,134 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.ButtonName
import org.yuzu.yuzu_emu.features.input.model.InputType
import org.yuzu.yuzu_emu.utils.ParamPackage
sealed class InputSetting(
@StringRes titleId: Int,
titleString: String
) : SettingsItem(emptySetting, titleId, titleString, 0, "") {
override val type = TYPE_INPUT
abstract val inputType: InputType
abstract val playerIndex: Int
protected val context get() = YuzuApplication.appContext
abstract fun getSelectedValue(): String
abstract fun setSelectedValue(param: ParamPackage)
protected fun getDisplayString(params: ParamPackage, control: String): String {
val deviceName = params.get("display", "")
deviceName.ifEmpty {
return context.getString(R.string.not_set)
}
return "$deviceName: $control"
}
private fun getDirectionName(direction: String): String =
when (direction) {
"up" -> context.getString(R.string.up)
"down" -> context.getString(R.string.down)
"left" -> context.getString(R.string.left)
"right" -> context.getString(R.string.right)
else -> direction
}
protected fun buttonToText(param: ParamPackage): String {
if (!param.has("engine")) {
return context.getString(R.string.not_set)
}
val toggle = if (param.get("toggle", false)) "~" else ""
val inverted = if (param.get("inverted", false)) "!" else ""
val invert = if (param.get("invert", "+") == "-") "-" else ""
val turbo = if (param.get("turbo", false)) "$" else ""
val commonButtonName = NativeInput.getButtonName(param)
if (commonButtonName == ButtonName.Invalid) {
return context.getString(R.string.invalid)
}
if (commonButtonName == ButtonName.Engine) {
return param.get("engine", "")
}
if (commonButtonName == ButtonName.Value) {
if (param.has("hat")) {
val hat = getDirectionName(param.get("direction", ""))
return context.getString(R.string.qualified_hat, turbo, toggle, inverted, hat)
}
if (param.has("axis")) {
val axis = param.get("axis", "")
return context.getString(
R.string.qualified_button_stick_axis,
toggle,
inverted,
invert,
axis
)
}
if (param.has("button")) {
val button = param.get("button", "")
return context.getString(R.string.qualified_button, turbo, toggle, inverted, button)
}
}
return context.getString(R.string.unknown)
}
protected fun analogToText(param: ParamPackage, direction: String): String {
if (!param.has("engine")) {
return context.getString(R.string.not_set)
}
if (param.get("engine", "") == "analog_from_button") {
return buttonToText(ParamPackage(param.get(direction, "")))
}
if (!param.has("axis_x") || !param.has("axis_y")) {
return context.getString(R.string.unknown)
}
val xAxis = param.get("axis_x", "")
val yAxis = param.get("axis_y", "")
val xInvert = param.get("invert_x", "+") == "-"
val yInvert = param.get("invert_y", "+") == "-"
if (direction == "modifier") {
return context.getString(R.string.unused)
}
when (direction) {
"up" -> {
val yInvertString = if (yInvert) "+" else "-"
return context.getString(R.string.qualified_axis, yAxis, yInvertString)
}
"down" -> {
val yInvertString = if (yInvert) "-" else "+"
return context.getString(R.string.qualified_axis, yAxis, yInvertString)
}
"left" -> {
val xInvertString = if (xInvert) "+" else "-"
return context.getString(R.string.qualified_axis, xAxis, xInvertString)
}
"right" -> {
val xInvertString = if (xInvert) "-" else "+"
return context.getString(R.string.qualified_axis, xAxis, xInvertString)
}
}
return context.getString(R.string.unknown)
}
}

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
class IntSingleChoiceSetting(
private val intSetting: AbstractIntSetting,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
val choices: Array<String>,
val values: Array<Int>
) : SettingsItem(intSetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_INT_SINGLE_CHOICE
fun getValueAt(index: Int): Int =
if (values.indices.contains(index)) values[index] else -1
fun getChoiceAt(index: Int): String =
if (choices.indices.contains(index)) choices[index] else ""
fun getSelectedValue(needsGlobal: Boolean = false) = intSetting.getInt(needsGlobal)
fun setSelectedValue(value: Int) = intSetting.setInt(value)
val selectedValueIndex: Int
get() {
for (i in values.indices) {
if (values[i] == getSelectedValue()) {
return i
}
}
return -1
}
}

View File

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.InputType
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
import org.yuzu.yuzu_emu.utils.ParamPackage
class ModifierInputSetting(
override val playerIndex: Int,
val nativeAnalog: NativeAnalog,
@StringRes titleId: Int = 0,
titleString: String = ""
) : InputSetting(titleId, titleString) {
override val inputType = InputType.Button
override fun getSelectedValue(): String {
val analogParam = NativeInput.getStickParam(playerIndex, nativeAnalog)
val modifierParam = ParamPackage(analogParam.get("modifier", ""))
return buttonToText(modifierParam)
}
override fun setSelectedValue(param: ParamPackage) {
val newParam = NativeInput.getStickParam(playerIndex, nativeAnalog)
newParam.set("modifier", param.serialize())
NativeInput.setStickParam(playerIndex, nativeAnalog, newParam)
}
}

View File

@ -4,13 +4,16 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
class RunnableSetting(
titleId: Int,
descriptionId: Int,
val isRuntimeRunnable: Boolean,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
val isRunnable: Boolean,
@DrawableRes val iconId: Int = 0,
val runnable: () -> Unit
) : SettingsItem(emptySetting, titleId, descriptionId) {
) : SettingsItem(emptySetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_RUNNABLE
}

View File

@ -3,8 +3,12 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
@ -12,6 +16,7 @@ import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.utils.NativeConfig
/**
@ -23,13 +28,34 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
*/
abstract class SettingsItem(
val setting: AbstractSetting,
val nameId: Int,
val descriptionId: Int
@StringRes val titleId: Int,
val titleString: String,
@StringRes val descriptionId: Int,
val descriptionString: String
) {
abstract val type: Int
val title: String by lazy {
if (titleId != 0) {
return@lazy YuzuApplication.appContext.getString(titleId)
}
return@lazy titleString
}
val description: String by lazy {
if (descriptionId != 0) {
return@lazy YuzuApplication.appContext.getString(descriptionId)
}
return@lazy descriptionString
}
val isEditable: Boolean
get() {
// Can't change docked mode toggle when using handheld mode
if (setting.key == BooleanSetting.USE_DOCKED_MODE.key) {
return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld
}
// Can't edit settings that aren't saveable in per-game config even if they are switchable
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
return false
@ -50,6 +76,9 @@ abstract class SettingsItem(
get() = NativeLibrary.isRunning() && !setting.global &&
!NativeConfig.isPerGameConfigLoaded()
val clearable: Boolean
get() = !setting.global && NativeConfig.isPerGameConfigLoaded()
companion object {
const val TYPE_HEADER = 0
const val TYPE_SWITCH = 1
@ -59,6 +88,10 @@ abstract class SettingsItem(
const val TYPE_STRING_SINGLE_CHOICE = 5
const val TYPE_DATETIME_SETTING = 6
const val TYPE_RUNNABLE = 7
const val TYPE_INPUT = 8
const val TYPE_INT_SINGLE_CHOICE = 9
const val TYPE_INPUT_PROFILE = 10
const val TYPE_STRING_INPUT = 11
const val FASTMEM_COMBINED = "fastmem_combined"
@ -77,221 +110,246 @@ abstract class SettingsItem(
// List of all general
val settingsItems = HashMap<String, SettingsItem>().apply {
put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name))
put(
SwitchSetting(
BooleanSetting.RENDERER_USE_SPEED_LIMIT,
R.string.frame_limit_enable,
R.string.frame_limit_enable_description
titleId = R.string.frame_limit_enable,
descriptionId = R.string.frame_limit_enable_description
)
)
put(
SliderSetting(
ShortSetting.RENDERER_SPEED_LIMIT,
R.string.frame_limit_slider,
R.string.frame_limit_slider_description,
1,
400,
"%"
titleId = R.string.frame_limit_slider,
descriptionId = R.string.frame_limit_slider_description,
min = 1,
max = 400,
units = "%"
)
)
put(
SingleChoiceSetting(
IntSetting.CPU_BACKEND,
R.string.cpu_backend,
0,
R.array.cpuBackendArm64Names,
R.array.cpuBackendArm64Values
titleId = R.string.cpu_backend,
choicesId = R.array.cpuBackendArm64Names,
valuesId = R.array.cpuBackendArm64Values
)
)
put(
SingleChoiceSetting(
IntSetting.CPU_ACCURACY,
R.string.cpu_accuracy,
0,
R.array.cpuAccuracyNames,
R.array.cpuAccuracyValues
titleId = R.string.cpu_accuracy,
choicesId = R.array.cpuAccuracyNames,
valuesId = R.array.cpuAccuracyValues
)
)
put(
SwitchSetting(
BooleanSetting.PICTURE_IN_PICTURE,
R.string.picture_in_picture,
R.string.picture_in_picture_description
titleId = R.string.picture_in_picture,
descriptionId = R.string.picture_in_picture_description
)
)
val dockedModeSetting = object : AbstractBooleanSetting {
override val key = BooleanSetting.USE_DOCKED_MODE.key
override fun getBoolean(needsGlobal: Boolean): Boolean {
if (NativeInput.getStyleIndex(0) == NpadStyleIndex.Handheld) {
return false
}
return BooleanSetting.USE_DOCKED_MODE.getBoolean(needsGlobal)
}
override fun setBoolean(value: Boolean) =
BooleanSetting.USE_DOCKED_MODE.setBoolean(value)
override val defaultValue = BooleanSetting.USE_DOCKED_MODE.defaultValue
override fun getValueAsString(needsGlobal: Boolean): String =
BooleanSetting.USE_DOCKED_MODE.getValueAsString(needsGlobal)
override fun reset() = BooleanSetting.USE_DOCKED_MODE.reset()
}
put(
SwitchSetting(
BooleanSetting.USE_DOCKED_MODE,
R.string.use_docked_mode,
R.string.use_docked_mode_description
dockedModeSetting,
titleId = R.string.use_docked_mode,
descriptionId = R.string.use_docked_mode_description
)
)
put(
SingleChoiceSetting(
IntSetting.REGION_INDEX,
R.string.emulated_region,
0,
R.array.regionNames,
R.array.regionValues
titleId = R.string.emulated_region,
choicesId = R.array.regionNames,
valuesId = R.array.regionValues
)
)
put(
SingleChoiceSetting(
IntSetting.LANGUAGE_INDEX,
R.string.emulated_language,
0,
R.array.languageNames,
R.array.languageValues
titleId = R.string.emulated_language,
choicesId = R.array.languageNames,
valuesId = R.array.languageValues
)
)
put(
SwitchSetting(
BooleanSetting.USE_CUSTOM_RTC,
R.string.use_custom_rtc,
R.string.use_custom_rtc_description
titleId = R.string.use_custom_rtc,
descriptionId = R.string.use_custom_rtc_description
)
)
put(DateTimeSetting(LongSetting.CUSTOM_RTC, R.string.set_custom_rtc, 0))
put(DateTimeSetting(LongSetting.CUSTOM_RTC, titleId = R.string.set_custom_rtc))
put(
SingleChoiceSetting(
IntSetting.RENDERER_ACCURACY,
R.string.renderer_accuracy,
0,
R.array.rendererAccuracyNames,
R.array.rendererAccuracyValues
titleId = R.string.renderer_accuracy,
choicesId = R.array.rendererAccuracyNames,
valuesId = R.array.rendererAccuracyValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_RESOLUTION,
R.string.renderer_resolution,
0,
R.array.rendererResolutionNames,
R.array.rendererResolutionValues
titleId = R.string.renderer_resolution,
choicesId = R.array.rendererResolutionNames,
valuesId = R.array.rendererResolutionValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_VSYNC,
R.string.renderer_vsync,
0,
R.array.rendererVSyncNames,
R.array.rendererVSyncValues
titleId = R.string.renderer_vsync,
choicesId = R.array.rendererVSyncNames,
valuesId = R.array.rendererVSyncValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_SCALING_FILTER,
R.string.renderer_scaling_filter,
0,
R.array.rendererScalingFilterNames,
R.array.rendererScalingFilterValues
titleId = R.string.renderer_scaling_filter,
choicesId = R.array.rendererScalingFilterNames,
valuesId = R.array.rendererScalingFilterValues
)
)
put(
SliderSetting(
IntSetting.FSR_SHARPENING_SLIDER,
titleId = R.string.fsr_sharpness,
descriptionId = R.string.fsr_sharpness_description,
units = "%"
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_ANTI_ALIASING,
R.string.renderer_anti_aliasing,
0,
R.array.rendererAntiAliasingNames,
R.array.rendererAntiAliasingValues
titleId = R.string.renderer_anti_aliasing,
choicesId = R.array.rendererAntiAliasingNames,
valuesId = R.array.rendererAntiAliasingValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_SCREEN_LAYOUT,
R.string.renderer_screen_layout,
0,
R.array.rendererScreenLayoutNames,
R.array.rendererScreenLayoutValues
titleId = R.string.renderer_screen_layout,
choicesId = R.array.rendererScreenLayoutNames,
valuesId = R.array.rendererScreenLayoutValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_ASPECT_RATIO,
R.string.renderer_aspect_ratio,
0,
R.array.rendererAspectRatioNames,
R.array.rendererAspectRatioValues
titleId = R.string.renderer_aspect_ratio,
choicesId = R.array.rendererAspectRatioNames,
valuesId = R.array.rendererAspectRatioValues
)
)
put(
SingleChoiceSetting(
IntSetting.VERTICAL_ALIGNMENT,
titleId = R.string.vertical_alignment,
descriptionId = 0,
choicesId = R.array.verticalAlignmentEntries,
valuesId = R.array.verticalAlignmentValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE,
R.string.use_disk_shader_cache,
R.string.use_disk_shader_cache_description
titleId = R.string.use_disk_shader_cache,
descriptionId = R.string.use_disk_shader_cache_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FORCE_MAX_CLOCK,
R.string.renderer_force_max_clock,
R.string.renderer_force_max_clock_description
titleId = R.string.renderer_force_max_clock,
descriptionId = R.string.renderer_force_max_clock_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS,
R.string.renderer_asynchronous_shaders,
R.string.renderer_asynchronous_shaders_description
titleId = R.string.renderer_asynchronous_shaders,
descriptionId = R.string.renderer_asynchronous_shaders_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_REACTIVE_FLUSHING,
R.string.renderer_reactive_flushing,
R.string.renderer_reactive_flushing_description
titleId = R.string.renderer_reactive_flushing,
descriptionId = R.string.renderer_reactive_flushing_description
)
)
put(
SingleChoiceSetting(
IntSetting.MAX_ANISOTROPY,
R.string.anisotropic_filtering,
R.string.anisotropic_filtering_description,
R.array.anisoEntries,
R.array.anisoValues
titleId = R.string.anisotropic_filtering,
descriptionId = R.string.anisotropic_filtering_description,
choicesId = R.array.anisoEntries,
valuesId = R.array.anisoValues
)
)
put(
SingleChoiceSetting(
IntSetting.AUDIO_OUTPUT_ENGINE,
R.string.audio_output_engine,
0,
R.array.outputEngineEntries,
R.array.outputEngineValues
titleId = R.string.audio_output_engine,
choicesId = R.array.outputEngineEntries,
valuesId = R.array.outputEngineValues
)
)
put(
SliderSetting(
ByteSetting.AUDIO_VOLUME,
R.string.audio_volume,
R.string.audio_volume_description,
0,
100,
"%"
titleId = R.string.audio_volume,
descriptionId = R.string.audio_volume_description,
units = "%"
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_BACKEND,
R.string.renderer_api,
0,
R.array.rendererApiNames,
R.array.rendererApiValues
titleId = R.string.renderer_api,
choicesId = R.array.rendererApiNames,
valuesId = R.array.rendererApiValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_DEBUG,
R.string.renderer_debug,
R.string.renderer_debug_description
titleId = R.string.renderer_debug,
descriptionId = R.string.renderer_debug_description
)
)
put(
SwitchSetting(
BooleanSetting.CPU_DEBUG_MODE,
R.string.cpu_debug_mode,
R.string.cpu_debug_mode_description
titleId = R.string.cpu_debug_mode,
descriptionId = R.string.cpu_debug_mode_description
)
)
@ -327,7 +385,7 @@ abstract class SettingsItem(
override fun reset() = setBoolean(defaultValue)
}
put(SwitchSetting(fastmem, R.string.fastmem, 0))
put(SwitchSetting(fastmem, R.string.fastmem))
}
}
}

View File

@ -3,16 +3,20 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.ArrayRes
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
class SingleChoiceSetting(
setting: AbstractSetting,
titleId: Int,
descriptionId: Int,
val choicesId: Int,
val valuesId: Int
) : SettingsItem(setting, titleId, descriptionId) {
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
@ArrayRes val choicesId: Int,
@ArrayRes val valuesId: Int
) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_SINGLE_CHOICE
fun getSelectedValue(needsGlobal: Boolean = false) =

View File

@ -3,6 +3,7 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractByteSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractFloatSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
@ -12,12 +13,14 @@ import kotlin.math.roundToInt
class SliderSetting(
setting: AbstractSetting,
titleId: Int,
descriptionId: Int,
val min: Int,
val max: Int,
val units: String
) : SettingsItem(setting, titleId, descriptionId) {
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
val min: Int = 0,
val max: Int = 100,
val units: String = ""
) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_SLIDER
fun getSelectedValue(needsGlobal: Boolean = false) =

View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting
class StringInputSetting(
setting: AbstractStringSetting,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = ""
) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_STRING_INPUT
fun getSelectedValue(needsGlobal: Boolean = false) = setting.getValueAsString(needsGlobal)
fun setSelectedValue(selection: String) =
(setting as AbstractStringSetting).setString(selection)
}

View File

@ -3,15 +3,18 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting
class StringSingleChoiceSetting(
private val stringSetting: AbstractStringSetting,
titleId: Int,
descriptionId: Int,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
val choices: Array<String>,
val values: Array<String>
) : SettingsItem(stringSetting, titleId, descriptionId) {
) : SettingsItem(stringSetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_STRING_SINGLE_CHOICE
fun getValueAt(index: Int): String =
@ -20,7 +23,7 @@ class StringSingleChoiceSetting(
fun getSelectedValue(needsGlobal: Boolean = false) = stringSetting.getString(needsGlobal)
fun setSelectedValue(value: String) = stringSetting.setString(value)
val selectValueIndex: Int
val selectedValueIndex: Int
get() {
for (i in values.indices) {
if (values[i] == getSelectedValue()) {

View File

@ -8,10 +8,12 @@ import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.Settings
class SubmenuSetting(
@StringRes titleId: Int,
@StringRes descriptionId: Int,
@DrawableRes val iconId: Int,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
@DrawableRes val iconId: Int = 0,
val menuKey: Settings.MenuTag
) : SettingsItem(emptySetting, titleId, descriptionId) {
) : SettingsItem(emptySetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_SUBMENU
}

View File

@ -3,15 +3,18 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
class SwitchSetting(
setting: AbstractSetting,
titleId: Int,
descriptionId: Int
) : SettingsItem(setting, titleId, descriptionId) {
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = ""
) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_SWITCH
fun getIsChecked(needsGlobal: Boolean = false): Boolean {

View File

@ -0,0 +1,300 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui
import android.app.Dialog
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.InputDevice
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.DialogMappingBinding
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
import org.yuzu.yuzu_emu.features.input.model.NativeButton
import org.yuzu.yuzu_emu.features.settings.model.view.AnalogInputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.ButtonInputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.InputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.ModifierInputSetting
import org.yuzu.yuzu_emu.utils.InputHandler
import org.yuzu.yuzu_emu.utils.ParamPackage
class InputDialogFragment : DialogFragment() {
private var inputAccepted = false
private var position: Int = 0
private lateinit var inputSetting: InputSetting
private lateinit var binding: DialogMappingBinding
private val settingsViewModel: SettingsViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (settingsViewModel.clickedItem == null) dismiss()
position = requireArguments().getInt(POSITION)
InputHandler.updateControllerData()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
inputSetting = settingsViewModel.clickedItem as InputSetting
binding = DialogMappingBinding.inflate(layoutInflater)
val builder = MaterialAlertDialogBuilder(requireContext())
.setPositiveButton(android.R.string.cancel) { _, _ ->
NativeInput.stopMapping()
dismiss()
}
.setView(binding.root)
val playButtonMapAnimation = { twoDirections: Boolean ->
val stickAnimation: AnimatedVectorDrawable
val buttonAnimation: AnimatedVectorDrawable
binding.imageStickAnimation.apply {
val anim = if (twoDirections) {
R.drawable.stick_two_direction_anim
} else {
R.drawable.stick_one_direction_anim
}
setBackgroundResource(anim)
stickAnimation = background as AnimatedVectorDrawable
}
binding.imageButtonAnimation.apply {
setBackgroundResource(R.drawable.button_anim)
buttonAnimation = background as AnimatedVectorDrawable
}
stickAnimation.registerAnimationCallback(object : Animatable2.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
buttonAnimation.start()
}
})
buttonAnimation.registerAnimationCallback(object : Animatable2.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
stickAnimation.start()
}
})
stickAnimation.start()
}
when (val setting = inputSetting) {
is AnalogInputSetting -> {
when (setting.nativeAnalog) {
NativeAnalog.LStick -> builder.setTitle(
getString(R.string.map_control, getString(R.string.left_stick))
)
NativeAnalog.RStick -> builder.setTitle(
getString(R.string.map_control, getString(R.string.right_stick))
)
}
builder.setMessage(R.string.stick_map_description)
playButtonMapAnimation.invoke(true)
}
is ModifierInputSetting -> {
builder.setTitle(getString(R.string.map_control, setting.title))
.setMessage(R.string.button_map_description)
playButtonMapAnimation.invoke(false)
}
is ButtonInputSetting -> {
if (setting.nativeButton == NativeButton.DUp ||
setting.nativeButton == NativeButton.DDown ||
setting.nativeButton == NativeButton.DLeft ||
setting.nativeButton == NativeButton.DRight
) {
builder.setTitle(getString(R.string.map_dpad_direction, setting.title))
} else {
builder.setTitle(getString(R.string.map_control, setting.title))
}
builder.setMessage(R.string.button_map_description)
playButtonMapAnimation.invoke(false)
}
}
return builder.create()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.requestFocus()
view.setOnFocusChangeListener { v, hasFocus -> if (!hasFocus) v.requestFocus() }
dialog?.setOnKeyListener { _, _, keyEvent -> onKeyEvent(keyEvent) }
binding.root.setOnGenericMotionListener { _, motionEvent -> onMotionEvent(motionEvent) }
NativeInput.beginMapping(inputSetting.inputType.int)
}
private fun onKeyEvent(event: KeyEvent): Boolean {
if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK &&
event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD
) {
return false
}
val action = when (event.action) {
KeyEvent.ACTION_DOWN -> NativeInput.ButtonState.PRESSED
KeyEvent.ACTION_UP -> NativeInput.ButtonState.RELEASED
else -> return false
}
val controllerData =
InputHandler.androidControllers[event.device.controllerNumber] ?: return false
NativeInput.onGamePadButtonEvent(
controllerData.getGUID(),
controllerData.getPort(),
event.keyCode,
action
)
onInputReceived(event.device)
return true
}
private fun onMotionEvent(event: MotionEvent): Boolean {
if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK &&
event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD
) {
return false
}
// Temp workaround for DPads that give both axis and button input. The input system can't
// take in a specific axis direction for a binding so you lose half of the directions for a DPad.
val controllerData =
InputHandler.androidControllers[event.device.controllerNumber] ?: return false
event.device.motionRanges.forEach {
NativeInput.onGamePadAxisEvent(
controllerData.getGUID(),
controllerData.getPort(),
it.axis,
event.getAxisValue(it.axis)
)
onInputReceived(event.device)
}
return true
}
private fun onInputReceived(device: InputDevice) {
val params = ParamPackage(NativeInput.getNextInput())
if (params.has("engine") && isInputAcceptable(params) && !inputAccepted) {
inputAccepted = true
setResult(params, device)
}
}
private fun setResult(params: ParamPackage, device: InputDevice) {
NativeInput.stopMapping()
params.set("display", "${device.name} ${params.get("port", 0)}")
when (val item = settingsViewModel.clickedItem as InputSetting) {
is ModifierInputSetting,
is ButtonInputSetting -> {
// Invert DPad up and left bindings by default
val tempSetting = inputSetting as? ButtonInputSetting
if (tempSetting != null) {
if (tempSetting.nativeButton == NativeButton.DUp ||
tempSetting.nativeButton == NativeButton.DLeft &&
params.has("axis")
) {
params.set("invert", "-")
}
}
item.setSelectedValue(params)
settingsViewModel.setAdapterItemChanged(position)
}
is AnalogInputSetting -> {
var analogParam = NativeInput.getStickParam(item.playerIndex, item.nativeAnalog)
analogParam = adjustAnalogParam(params, analogParam, item.analogDirection.param)
// Invert Y-Axis by default
analogParam.set("invert_y", "-")
item.setSelectedValue(analogParam)
settingsViewModel.setReloadListAndNotifyDataset(true)
}
}
dismiss()
}
private fun adjustAnalogParam(
inputParam: ParamPackage,
analogParam: ParamPackage,
buttonName: String
): ParamPackage {
// The poller returned a complete axis, so set all the buttons
if (inputParam.has("axis_x") && inputParam.has("axis_y")) {
return inputParam
}
// Check if the current configuration has either no engine or an axis binding.
// Clears out the old binding and adds one with analog_from_button.
if (!analogParam.has("engine") || analogParam.has("axis_x") || analogParam.has("axis_y")) {
analogParam.clear()
analogParam.set("engine", "analog_from_button")
}
analogParam.set(buttonName, inputParam.serialize())
return analogParam
}
private fun isInputAcceptable(params: ParamPackage): Boolean {
if (InputHandler.registeredControllers.size == 1) {
return true
}
if (params.has("motion")) {
return true
}
val currentDevice = settingsViewModel.getCurrentDeviceParams(params)
if (currentDevice.get("engine", "any") == "any") {
return true
}
val guidMatch = params.get("guid", "") == currentDevice.get("guid", "") ||
params.get("guid", "") == currentDevice.get("guid2", "")
return params.get("engine", "") == currentDevice.get("engine", "") &&
guidMatch &&
params.get("port", 0) == currentDevice.get("port", 0)
}
companion object {
const val TAG = "InputDialogFragment"
const val POSITION = "Position"
fun newInstance(
inputMappingViewModel: SettingsViewModel,
setting: InputSetting,
position: Int
): InputDialogFragment {
inputMappingViewModel.clickedItem = setting
val args = Bundle()
args.putInt(POSITION, position)
val fragment = InputDialogFragment()
fragment.arguments = args
return fragment
}
}
}

View File

@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.adapters.AbstractListAdapter
import org.yuzu.yuzu_emu.databinding.ListItemInputProfileBinding
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
import org.yuzu.yuzu_emu.R
class InputProfileAdapter(options: List<ProfileItem>) :
AbstractListAdapter<ProfileItem, AbstractViewHolder<ProfileItem>>(options) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): AbstractViewHolder<ProfileItem> {
ListItemInputProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
.also { return InputProfileViewHolder(it) }
}
inner class InputProfileViewHolder(val binding: ListItemInputProfileBinding) :
AbstractViewHolder<ProfileItem>(binding) {
override fun bind(model: ProfileItem) {
when (model) {
is ExistingProfileItem -> {
binding.title.text = model.name
binding.buttonNew.visibility = View.GONE
binding.buttonDelete.visibility = View.VISIBLE
binding.buttonDelete.setOnClickListener { model.deleteProfile.invoke() }
binding.buttonSave.visibility = View.VISIBLE
binding.buttonSave.setOnClickListener { model.saveProfile.invoke() }
binding.buttonLoad.visibility = View.VISIBLE
binding.buttonLoad.setOnClickListener { model.loadProfile.invoke() }
}
is NewProfileItem -> {
binding.title.text = model.name
binding.buttonNew.visibility = View.VISIBLE
binding.buttonNew.setOnClickListener { model.createNewProfile.invoke() }
binding.buttonSave.visibility = View.GONE
binding.buttonDelete.visibility = View.GONE
binding.buttonLoad.visibility = View.GONE
}
}
}
}
}
sealed interface ProfileItem {
val name: String
}
data class NewProfileItem(
val createNewProfile: () -> Unit
) : ProfileItem {
override val name: String = YuzuApplication.appContext.getString(R.string.create_new_profile)
}
data class ExistingProfileItem(
override val name: String,
val deleteProfile: () -> Unit,
val saveProfile: () -> Unit,
val loadProfile: () -> Unit
) : ProfileItem

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