summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Franco M2023-11-04 21:28:16 -0300
committerGravatar GitHub2023-11-04 21:28:16 -0300
commit728aca770317b3f86961c8669ba9ae5c68570d3f (patch)
tree29adffcb1d264cc16cacb478a8f6645ef6259b3b /src
parentWe dont need that (diff)
parentMerge pull request #11952 from liamwhite/opus_stereo_count (diff)
downloadyuzu-728aca770317b3f86961c8669ba9ae5c68570d3f.tar.gz
yuzu-728aca770317b3f86961c8669ba9ae5c68570d3f.tar.xz
yuzu-728aca770317b3f86961c8669ba9ae5c68570d3f.zip
Merge branch 'master' into new-shortcut
Diffstat (limited to 'src')
-rw-r--r--src/android/app/build.gradle.kts4
-rw-r--r--src/android/app/src/main/AndroidManifest.xml1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt98
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt20
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AppletAdapter.kt90
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/CabinetLauncherDialogAdapter.kt72
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt113
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/CabinetLauncherDialogFragment.kt41
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt37
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt90
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt5
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Applet.kt55
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt21
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt46
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ControllerMappingHelper.kt70
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt17
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt6
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt17
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt20
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt55
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt45
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt34
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt3
-rw-r--r--src/android/app/src/main/jni/game_metadata.cpp112
-rw-r--r--src/android/app/src/main/jni/native.cpp824
-rw-r--r--src/android/app/src/main/jni/native.h85
-rw-r--r--src/android/app/src/main/jni/native_log.cpp31
-rw-r--r--src/android/app/src/main/res/drawable/ic_album.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_applet.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_edit.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_mii.xml18
-rw-r--r--src/android/app/src/main/res/drawable/ic_refresh.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_restore.xml9
-rw-r--r--src/android/app/src/main/res/layout/card_applet_option.xml57
-rw-r--r--src/android/app/src/main/res/layout/card_game.xml45
-rw-r--r--src/android/app/src/main/res/layout/card_home_option.xml3
-rw-r--r--src/android/app/src/main/res/layout/dialog_list.xml15
-rw-r--r--src/android/app/src/main/res/layout/dialog_list_item.xml30
-rw-r--r--src/android/app/src/main/res/layout/fragment_applet_launcher.xml31
-rw-r--r--src/android/app/src/main/res/navigation/home_navigation.xml15
-rw-r--r--src/android/app/src/main/res/resources.properties1
-rw-r--r--src/android/app/src/main/res/values-ar/strings.xml385
-rw-r--r--src/android/app/src/main/res/values-ckb/strings.xml336
-rw-r--r--src/android/app/src/main/res/values-de/strings.xml119
-rw-r--r--src/android/app/src/main/res/values-es/strings.xml180
-rw-r--r--src/android/app/src/main/res/values-fr/strings.xml180
-rw-r--r--src/android/app/src/main/res/values-he/strings.xml367
-rw-r--r--src/android/app/src/main/res/values-hu/strings.xml402
-rw-r--r--src/android/app/src/main/res/values-it/strings.xml192
-rw-r--r--src/android/app/src/main/res/values-ja/strings.xml218
-rw-r--r--src/android/app/src/main/res/values-ko/strings.xml273
-rw-r--r--src/android/app/src/main/res/values-nb/strings.xml113
-rw-r--r--src/android/app/src/main/res/values-pl/strings.xml81
-rw-r--r--src/android/app/src/main/res/values-pt-rBR/strings.xml210
-rw-r--r--src/android/app/src/main/res/values-pt-rPT/strings.xml192
-rw-r--r--src/android/app/src/main/res/values-ru/strings.xml159
-rw-r--r--src/android/app/src/main/res/values-uk/strings.xml90
-rw-r--r--src/android/app/src/main/res/values-vi/strings.xml340
-rw-r--r--src/android/app/src/main/res/values-zh-rCN/strings.xml138
-rw-r--r--src/android/app/src/main/res/values-zh-rTW/strings.xml137
-rw-r--r--src/android/app/src/main/res/values/strings.xml20
-rw-r--r--src/android/app/src/main/res/xml/locales_config.xml17
-rw-r--r--src/audio_core/adsp/apps/opus/opus_decoder.cpp4
-rw-r--r--src/audio_core/opus/decoder_manager.cpp2
-rw-r--r--src/common/arm64/native_clock.cpp21
-rw-r--r--src/common/fs/fs_android.cpp33
-rw-r--r--src/common/fs/fs_android.h15
-rw-r--r--src/common/fs/fs_paths.h1
-rw-r--r--src/common/fs/path_util.cpp11
-rw-r--r--src/common/fs/path_util.h1
-rw-r--r--src/common/nvidia_flags.cpp1
-rw-r--r--src/common/settings.h1
-rw-r--r--src/common/string_util.cpp12
-rw-r--r--src/core/arm/arm_interface.cpp6
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/debugger/debugger.cpp24
-rw-r--r--src/core/debugger/gdbstub.cpp42
-rw-r--r--src/core/file_sys/program_metadata.cpp10
-rw-r--r--src/core/file_sys/program_metadata.h15
-rw-r--r--src/core/file_sys/romfs.cpp44
-rw-r--r--src/core/file_sys/romfs.h9
-rw-r--r--src/core/hid/emulated_controller.cpp14
-rw-r--r--src/core/hid/hid_types.h15
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp59
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.h13
-rw-r--r--src/core/hle/kernel/k_capabilities.h4
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp22
-rw-r--r--src/core/hle/kernel/k_condition_variable.h9
-rw-r--r--src/core/hle/kernel/k_interrupt_manager.cpp2
-rw-r--r--src/core/hle/kernel/k_memory_manager.cpp125
-rw-r--r--src/core/hle/kernel/k_memory_manager.h12
-rw-r--r--src/core/hle/kernel/k_page_table.cpp14
-rw-r--r--src/core/hle/kernel/k_page_table.h4
-rw-r--r--src/core/hle/kernel/k_process.cpp1442
-rw-r--r--src/core/hle/kernel/k_process.h724
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp4
-rw-r--r--src/core/hle/kernel/k_system_resource.cpp87
-rw-r--r--src/core/hle/kernel/k_thread.cpp28
-rw-r--r--src/core/hle/kernel/k_thread.h1
-rw-r--r--src/core/hle/kernel/kernel.cpp53
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp28
-rw-r--r--src/core/hle/kernel/svc/svc_lock.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_physical_memory.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp7
-rw-r--r--src/core/hle/kernel/svc_generator.py2
-rw-r--r--src/core/hle/kernel/svc_types.h46
-rw-r--r--src/core/hle/service/am/am.cpp100
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp4
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp3
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp16
-rw-r--r--src/core/hle/service/caps/caps_manager.h9
-rw-r--r--src/core/hle/service/caps/caps_ss.cpp10
-rw-r--r--src/core/hle/service/caps/caps_su.cpp42
-rw-r--r--src/core/hle/service/caps/caps_su.h9
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp6
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp4
-rw-r--r--src/core/hle/service/hid/hid.cpp16
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.cpp5
-rw-r--r--src/core/hle/service/hid/ring_lifo.h6
-rw-r--r--src/core/hle/service/kernel_helpers.cpp6
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_core.cpp6
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_producer.cpp5
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp15
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.h3
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp6
-rw-r--r--src/core/hle/service/pm/pm.cpp2
-rw-r--r--src/core/hle/service/sockets/bsd.cpp77
-rw-r--r--src/core/hle/service/sockets/bsd.h2
-rw-r--r--src/core/reporter.cpp2
-rw-r--r--src/input_common/helpers/joycon_driver.cpp16
-rw-r--r--src/input_common/helpers/joycon_driver.h5
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h13
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp6
-rw-r--r--src/yuzu/CMakeLists.txt10
-rw-r--r--src/yuzu/applets/qt_controller.cpp52
-rw-r--r--src/yuzu/applets/qt_controller.h4
-rw-r--r--src/yuzu/breakpad.cpp77
-rw-r--r--src/yuzu/breakpad.h10
-rw-r--r--src/yuzu/configuration/configure_debug.cpp18
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_input.cpp59
-rw-r--r--src/yuzu/configuration/configure_input.h7
-rw-r--r--src/yuzu/configuration/configure_input_player.h5
-rw-r--r--src/yuzu/configuration/shared_translation.cpp1
-rw-r--r--src/yuzu/debugger/wait_tree.cpp2
-rw-r--r--src/yuzu/game_list.cpp26
-rw-r--r--src/yuzu/game_list.h10
-rw-r--r--src/yuzu/game_list_worker.cpp102
-rw-r--r--src/yuzu/game_list_worker.h35
-rw-r--r--src/yuzu/main.cpp127
-rw-r--r--src/yuzu/main.h25
-rw-r--r--src/yuzu/mini_dump.cpp202
-rw-r--r--src/yuzu/mini_dump.h19
-rw-r--r--src/yuzu/uisettings.h4
166 files changed, 7647 insertions, 2990 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index ac43d84b7..021b070e0 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -47,6 +47,10 @@ android {
47 jniLibs.useLegacyPackaging = true 47 jniLibs.useLegacyPackaging = true
48 } 48 }
49 49
50 androidResources {
51 generateLocaleConfig = true
52 }
53
50 defaultConfig { 54 defaultConfig {
51 // TODO If this is ever modified, change application_id in strings.xml 55 // TODO If this is ever modified, change application_id in strings.xml
52 applicationId = "org.yuzu.yuzu_emu" 56 applicationId = "org.yuzu.yuzu_emu"
diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml
index a67351727..f10131b24 100644
--- a/src/android/app/src/main/AndroidManifest.xml
+++ b/src/android/app/src/main/AndroidManifest.xml
@@ -26,7 +26,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
26 android:supportsRtl="true" 26 android:supportsRtl="true"
27 android:isGame="true" 27 android:isGame="true"
28 android:appCategory="game" 28 android:appCategory="game"
29 android:localeConfig="@xml/locales_config"
30 android:banner="@drawable/tv_banner" 29 android:banner="@drawable/tv_banner"
31 android:fullBackupContent="@xml/data_extraction_rules" 30 android:fullBackupContent="@xml/data_extraction_rules"
32 android:dataExtractionRules="@xml/data_extraction_rules_api_31" 31 android:dataExtractionRules="@xml/data_extraction_rules_api_31"
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
index 115f72710..9ebd6c732 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
@@ -5,6 +5,7 @@ package org.yuzu.yuzu_emu
5 5
6import android.app.Dialog 6import android.app.Dialog
7import android.content.DialogInterface 7import android.content.DialogInterface
8import android.net.Uri
8import android.os.Bundle 9import android.os.Bundle
9import android.text.Html 10import android.text.Html
10import android.text.method.LinkMovementMethod 11import android.text.method.LinkMovementMethod
@@ -16,7 +17,7 @@ import androidx.fragment.app.DialogFragment
16import com.google.android.material.dialog.MaterialAlertDialogBuilder 17import com.google.android.material.dialog.MaterialAlertDialogBuilder
17import java.lang.ref.WeakReference 18import java.lang.ref.WeakReference
18import org.yuzu.yuzu_emu.activities.EmulationActivity 19import org.yuzu.yuzu_emu.activities.EmulationActivity
19import org.yuzu.yuzu_emu.utils.DocumentsTree.Companion.isNativePath 20import org.yuzu.yuzu_emu.utils.DocumentsTree
20import org.yuzu.yuzu_emu.utils.FileUtil 21import org.yuzu.yuzu_emu.utils.FileUtil
21import org.yuzu.yuzu_emu.utils.Log 22import org.yuzu.yuzu_emu.utils.Log
22import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable 23import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
@@ -68,7 +69,7 @@ object NativeLibrary {
68 @Keep 69 @Keep
69 @JvmStatic 70 @JvmStatic
70 fun openContentUri(path: String?, openmode: String?): Int { 71 fun openContentUri(path: String?, openmode: String?): Int {
71 return if (isNativePath(path!!)) { 72 return if (DocumentsTree.isNativePath(path!!)) {
72 YuzuApplication.documentsTree!!.openContentUri(path, openmode) 73 YuzuApplication.documentsTree!!.openContentUri(path, openmode)
73 } else { 74 } else {
74 FileUtil.openContentUri(path, openmode) 75 FileUtil.openContentUri(path, openmode)
@@ -78,7 +79,7 @@ object NativeLibrary {
78 @Keep 79 @Keep
79 @JvmStatic 80 @JvmStatic
80 fun getSize(path: String?): Long { 81 fun getSize(path: String?): Long {
81 return if (isNativePath(path!!)) { 82 return if (DocumentsTree.isNativePath(path!!)) {
82 YuzuApplication.documentsTree!!.getFileSize(path) 83 YuzuApplication.documentsTree!!.getFileSize(path)
83 } else { 84 } else {
84 FileUtil.getFileSize(path) 85 FileUtil.getFileSize(path)
@@ -88,23 +89,41 @@ object NativeLibrary {
88 @Keep 89 @Keep
89 @JvmStatic 90 @JvmStatic
90 fun exists(path: String?): Boolean { 91 fun exists(path: String?): Boolean {
91 return if (isNativePath(path!!)) { 92 return if (DocumentsTree.isNativePath(path!!)) {
92 YuzuApplication.documentsTree!!.exists(path) 93 YuzuApplication.documentsTree!!.exists(path)
93 } else { 94 } else {
94 FileUtil.exists(path) 95 FileUtil.exists(path, suppressLog = true)
95 } 96 }
96 } 97 }
97 98
98 @Keep 99 @Keep
99 @JvmStatic 100 @JvmStatic
100 fun isDirectory(path: String?): Boolean { 101 fun isDirectory(path: String?): Boolean {
101 return if (isNativePath(path!!)) { 102 return if (DocumentsTree.isNativePath(path!!)) {
102 YuzuApplication.documentsTree!!.isDirectory(path) 103 YuzuApplication.documentsTree!!.isDirectory(path)
103 } else { 104 } else {
104 FileUtil.isDirectory(path) 105 FileUtil.isDirectory(path)
105 } 106 }
106 } 107 }
107 108
109 @Keep
110 @JvmStatic
111 fun getParentDirectory(path: String): String =
112 if (DocumentsTree.isNativePath(path)) {
113 YuzuApplication.documentsTree!!.getParentDirectory(path)
114 } else {
115 path
116 }
117
118 @Keep
119 @JvmStatic
120 fun getFilename(path: String): String =
121 if (DocumentsTree.isNativePath(path)) {
122 YuzuApplication.documentsTree!!.getFilename(path)
123 } else {
124 FileUtil.getFilename(Uri.parse(path))
125 }
126
108 /** 127 /**
109 * Returns true if pro controller isn't available and handheld is 128 * Returns true if pro controller isn't available and handheld is
110 */ 129 */
@@ -215,32 +234,6 @@ object NativeLibrary {
215 234
216 external fun initGameIni(gameID: String?) 235 external fun initGameIni(gameID: String?)
217 236
218 /**
219 * Gets the embedded icon within the given ROM.
220 *
221 * @param filename the file path to the ROM.
222 * @return a byte array containing the JPEG data for the icon.
223 */
224 external fun getIcon(filename: String): ByteArray
225
226 /**
227 * Gets the embedded title of the given ISO/ROM.
228 *
229 * @param filename The file path to the ISO/ROM.
230 * @return the embedded title of the ISO/ROM.
231 */
232 external fun getTitle(filename: String): String
233
234 external fun getDescription(filename: String): String
235
236 external fun getGameId(filename: String): String
237
238 external fun getRegions(filename: String): String
239
240 external fun getCompany(filename: String): String
241
242 external fun isHomebrew(filename: String): Boolean
243
244 external fun setAppDirectory(directory: String) 237 external fun setAppDirectory(directory: String)
245 238
246 /** 239 /**
@@ -259,7 +252,7 @@ object NativeLibrary {
259 252
260 external fun reloadKeys(): Boolean 253 external fun reloadKeys(): Boolean
261 254
262 external fun initializeEmulation() 255 external fun initializeSystem(reload: Boolean)
263 256
264 external fun defaultCPUCore(): Int 257 external fun defaultCPUCore(): Int
265 258
@@ -294,11 +287,6 @@ object NativeLibrary {
294 external fun stopEmulation() 287 external fun stopEmulation()
295 288
296 /** 289 /**
297 * Resets the in-memory ROM metadata cache.
298 */
299 external fun resetRomMetadata()
300
301 /**
302 * Returns true if emulation is running (or is paused). 290 * Returns true if emulation is running (or is paused).
303 */ 291 */
304 external fun isRunning(): Boolean 292 external fun isRunning(): Boolean
@@ -474,12 +462,12 @@ object NativeLibrary {
474 } 462 }
475 463
476 fun setEmulationActivity(emulationActivity: EmulationActivity?) { 464 fun setEmulationActivity(emulationActivity: EmulationActivity?) {
477 Log.verbose("[NativeLibrary] Registering EmulationActivity.") 465 Log.debug("[NativeLibrary] Registering EmulationActivity.")
478 sEmulationActivity = WeakReference(emulationActivity) 466 sEmulationActivity = WeakReference(emulationActivity)
479 } 467 }
480 468
481 fun clearEmulationActivity() { 469 fun clearEmulationActivity() {
482 Log.verbose("[NativeLibrary] Unregistering EmulationActivity.") 470 Log.debug("[NativeLibrary] Unregistering EmulationActivity.")
483 sEmulationActivity.clear() 471 sEmulationActivity.clear()
484 } 472 }
485 473
@@ -518,6 +506,36 @@ object NativeLibrary {
518 external fun initializeEmptyUserDirectory() 506 external fun initializeEmptyUserDirectory()
519 507
520 /** 508 /**
509 * Gets the launch path for a given applet. It is the caller's responsibility to also
510 * set the system's current applet ID before trying to launch the nca given by this function.
511 *
512 * @param id The applet entry ID
513 * @return The applet's launch path
514 */
515 external fun getAppletLaunchPath(id: Long): String
516
517 /**
518 * Sets the system's current applet ID before launching.
519 *
520 * @param appletId One of the ids in the Service::AM::Applets::AppletId enum
521 */
522 external fun setCurrentAppletId(appletId: Int)
523
524 /**
525 * Sets the cabinet mode for launching the cabinet applet.
526 *
527 * @param cabinetMode One of the modes that corresponds to the enum in Service::NFP::CabinetMode
528 */
529 external fun setCabinetMode(cabinetMode: Int)
530
531 /**
532 * Checks whether NAND contents are available and valid.
533 *
534 * @return 'true' if firmware is available
535 */
536 external fun isFirmwareAvailable(): Boolean
537
538 /**
521 * Button type for use in onTouchEvent 539 * Button type for use in onTouchEvent
522 */ 540 */
523 object ButtonType { 541 object ButtonType {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
index 8c053670c..d114bd53d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
@@ -11,6 +11,7 @@ import java.io.File
11import org.yuzu.yuzu_emu.utils.DirectoryInitialization 11import org.yuzu.yuzu_emu.utils.DirectoryInitialization
12import org.yuzu.yuzu_emu.utils.DocumentsTree 12import org.yuzu.yuzu_emu.utils.DocumentsTree
13import org.yuzu.yuzu_emu.utils.GpuDriverHelper 13import org.yuzu.yuzu_emu.utils.GpuDriverHelper
14import org.yuzu.yuzu_emu.utils.Log
14 15
15fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir 16fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
16 17
@@ -49,6 +50,7 @@ class YuzuApplication : Application() {
49 DirectoryInitialization.start() 50 DirectoryInitialization.start()
50 GpuDriverHelper.initializeDriverParameters() 51 GpuDriverHelper.initializeDriverParameters()
51 NativeLibrary.logDeviceInfo() 52 NativeLibrary.logDeviceInfo()
53 Log.logDeviceInfo()
52 54
53 createNotificationChannels() 55 createNotificationChannels()
54 } 56 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index e96a2059b..054e4b755 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -45,9 +45,9 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting
45import org.yuzu.yuzu_emu.features.settings.model.Settings 45import org.yuzu.yuzu_emu.features.settings.model.Settings
46import org.yuzu.yuzu_emu.model.EmulationViewModel 46import org.yuzu.yuzu_emu.model.EmulationViewModel
47import org.yuzu.yuzu_emu.model.Game 47import org.yuzu.yuzu_emu.model.Game
48import org.yuzu.yuzu_emu.utils.ControllerMappingHelper
49import org.yuzu.yuzu_emu.utils.ForegroundService 48import org.yuzu.yuzu_emu.utils.ForegroundService
50import org.yuzu.yuzu_emu.utils.InputHandler 49import org.yuzu.yuzu_emu.utils.InputHandler
50import org.yuzu.yuzu_emu.utils.Log
51import org.yuzu.yuzu_emu.utils.MemoryUtil 51import org.yuzu.yuzu_emu.utils.MemoryUtil
52import org.yuzu.yuzu_emu.utils.NfcReader 52import org.yuzu.yuzu_emu.utils.NfcReader
53import org.yuzu.yuzu_emu.utils.ThemeHelper 53import org.yuzu.yuzu_emu.utils.ThemeHelper
@@ -57,17 +57,16 @@ import kotlin.math.roundToInt
57class EmulationActivity : AppCompatActivity(), SensorEventListener { 57class EmulationActivity : AppCompatActivity(), SensorEventListener {
58 private lateinit var binding: ActivityEmulationBinding 58 private lateinit var binding: ActivityEmulationBinding
59 59
60 private var controllerMappingHelper: ControllerMappingHelper? = null
61
62 var isActivityRecreated = false 60 var isActivityRecreated = false
63 private lateinit var nfcReader: NfcReader 61 private lateinit var nfcReader: NfcReader
64 private lateinit var inputHandler: InputHandler
65 62
66 private val gyro = FloatArray(3) 63 private val gyro = FloatArray(3)
67 private val accel = FloatArray(3) 64 private val accel = FloatArray(3)
68 private var motionTimestamp: Long = 0 65 private var motionTimestamp: Long = 0
69 private var flipMotionOrientation: Boolean = false 66 private var flipMotionOrientation: Boolean = false
70 67
68 private var controllerIds = InputHandler.getGameControllerIds()
69
71 private val actionPause = "ACTION_EMULATOR_PAUSE" 70 private val actionPause = "ACTION_EMULATOR_PAUSE"
72 private val actionPlay = "ACTION_EMULATOR_PLAY" 71 private val actionPlay = "ACTION_EMULATOR_PLAY"
73 private val actionMute = "ACTION_EMULATOR_MUTE" 72 private val actionMute = "ACTION_EMULATOR_MUTE"
@@ -82,6 +81,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
82 } 81 }
83 82
84 override fun onCreate(savedInstanceState: Bundle?) { 83 override fun onCreate(savedInstanceState: Bundle?) {
84 Log.gameLaunched = true
85 ThemeHelper.setTheme(this) 85 ThemeHelper.setTheme(this)
86 86
87 super.onCreate(savedInstanceState) 87 super.onCreate(savedInstanceState)
@@ -95,8 +95,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
95 95
96 isActivityRecreated = savedInstanceState != null 96 isActivityRecreated = savedInstanceState != null
97 97
98 controllerMappingHelper = ControllerMappingHelper()
99
100 // Set these options now so that the SurfaceView the game renders into is the right size. 98 // Set these options now so that the SurfaceView the game renders into is the right size.
101 enableFullscreenImmersive() 99 enableFullscreenImmersive()
102 100
@@ -105,12 +103,11 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
105 nfcReader = NfcReader(this) 103 nfcReader = NfcReader(this)
106 nfcReader.initialize() 104 nfcReader.initialize()
107 105
108 inputHandler = InputHandler() 106 InputHandler.initialize()
109 inputHandler.initialize()
110 107
111 val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) 108 val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
112 if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) { 109 if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) {
113 if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.Gb)) { 110 if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.totalMemory)) {
114 Toast.makeText( 111 Toast.makeText(
115 this, 112 this,
116 getString( 113 getString(
@@ -162,6 +159,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
162 super.onResume() 159 super.onResume()
163 nfcReader.startScanning() 160 nfcReader.startScanning()
164 startMotionSensorListener() 161 startMotionSensorListener()
162 InputHandler.updateControllerIds()
165 163
166 buildPictureInPictureParams() 164 buildPictureInPictureParams()
167 } 165 }
@@ -195,7 +193,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
195 return super.dispatchKeyEvent(event) 193 return super.dispatchKeyEvent(event)
196 } 194 }
197 195
198 return inputHandler.dispatchKeyEvent(event) 196 return InputHandler.dispatchKeyEvent(event)
199 } 197 }
200 198
201 override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean { 199 override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
@@ -210,7 +208,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
210 return true 208 return true
211 } 209 }
212 210
213 return inputHandler.dispatchGenericMotionEvent(event) 211 return InputHandler.dispatchGenericMotionEvent(event)
214 } 212 }
215 213
216 override fun onSensorChanged(event: SensorEvent) { 214 override fun onSensorChanged(event: SensorEvent) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AppletAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AppletAdapter.kt
new file mode 100644
index 000000000..a21a705c1
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AppletAdapter.kt
@@ -0,0 +1,90 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.adapters
5
6import android.view.LayoutInflater
7import android.view.View
8import android.view.ViewGroup
9import android.widget.Toast
10import androidx.core.content.res.ResourcesCompat
11import androidx.fragment.app.FragmentActivity
12import androidx.navigation.findNavController
13import androidx.recyclerview.widget.RecyclerView
14import org.yuzu.yuzu_emu.HomeNavigationDirections
15import org.yuzu.yuzu_emu.NativeLibrary
16import org.yuzu.yuzu_emu.R
17import org.yuzu.yuzu_emu.YuzuApplication
18import org.yuzu.yuzu_emu.databinding.CardAppletOptionBinding
19import org.yuzu.yuzu_emu.model.Applet
20import org.yuzu.yuzu_emu.model.AppletInfo
21import org.yuzu.yuzu_emu.model.Game
22
23class AppletAdapter(val activity: FragmentActivity, var applets: List<Applet>) :
24 RecyclerView.Adapter<AppletAdapter.AppletViewHolder>(),
25 View.OnClickListener {
26
27 override fun onCreateViewHolder(
28 parent: ViewGroup,
29 viewType: Int
30 ): AppletAdapter.AppletViewHolder {
31 CardAppletOptionBinding.inflate(LayoutInflater.from(parent.context), parent, false)
32 .apply { root.setOnClickListener(this@AppletAdapter) }
33 .also { return AppletViewHolder(it) }
34 }
35
36 override fun onBindViewHolder(holder: AppletViewHolder, position: Int) =
37 holder.bind(applets[position])
38
39 override fun getItemCount(): Int = applets.size
40
41 override fun onClick(view: View) {
42 val applet = (view.tag as AppletViewHolder).applet
43 val appletPath = NativeLibrary.getAppletLaunchPath(applet.appletInfo.entryId)
44 if (appletPath.isEmpty()) {
45 Toast.makeText(
46 YuzuApplication.appContext,
47 R.string.applets_error_applet,
48 Toast.LENGTH_SHORT
49 ).show()
50 return
51 }
52
53 if (applet.appletInfo == AppletInfo.Cabinet) {
54 view.findNavController()
55 .navigate(R.id.action_appletLauncherFragment_to_cabinetLauncherDialogFragment)
56 return
57 }
58
59 NativeLibrary.setCurrentAppletId(applet.appletInfo.appletId)
60 val appletGame = Game(
61 title = YuzuApplication.appContext.getString(applet.titleId),
62 path = appletPath
63 )
64 val action = HomeNavigationDirections.actionGlobalEmulationActivity(appletGame)
65 view.findNavController().navigate(action)
66 }
67
68 inner class AppletViewHolder(val binding: CardAppletOptionBinding) :
69 RecyclerView.ViewHolder(binding.root) {
70 lateinit var applet: Applet
71
72 init {
73 itemView.tag = this
74 }
75
76 fun bind(applet: Applet) {
77 this.applet = applet
78
79 binding.title.setText(applet.titleId)
80 binding.description.setText(applet.descriptionId)
81 binding.icon.setImageDrawable(
82 ResourcesCompat.getDrawable(
83 binding.icon.context.resources,
84 applet.iconId,
85 binding.icon.context.theme
86 )
87 )
88 }
89 }
90}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/CabinetLauncherDialogAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/CabinetLauncherDialogAdapter.kt
new file mode 100644
index 000000000..e7b7c0f2f
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/CabinetLauncherDialogAdapter.kt
@@ -0,0 +1,72 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.adapters
5
6import android.view.LayoutInflater
7import android.view.View
8import android.view.ViewGroup
9import androidx.core.content.res.ResourcesCompat
10import androidx.fragment.app.Fragment
11import androidx.navigation.fragment.findNavController
12import androidx.recyclerview.widget.RecyclerView
13import org.yuzu.yuzu_emu.HomeNavigationDirections
14import org.yuzu.yuzu_emu.NativeLibrary
15import org.yuzu.yuzu_emu.R
16import org.yuzu.yuzu_emu.YuzuApplication
17import org.yuzu.yuzu_emu.databinding.DialogListItemBinding
18import org.yuzu.yuzu_emu.model.CabinetMode
19import org.yuzu.yuzu_emu.adapters.CabinetLauncherDialogAdapter.CabinetModeViewHolder
20import org.yuzu.yuzu_emu.model.AppletInfo
21import org.yuzu.yuzu_emu.model.Game
22
23class CabinetLauncherDialogAdapter(val fragment: Fragment) :
24 RecyclerView.Adapter<CabinetModeViewHolder>(),
25 View.OnClickListener {
26 private val cabinetModes = CabinetMode.values().copyOfRange(1, CabinetMode.values().size)
27
28 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CabinetModeViewHolder {
29 DialogListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
30 .apply { root.setOnClickListener(this@CabinetLauncherDialogAdapter) }
31 .also { return CabinetModeViewHolder(it) }
32 }
33
34 override fun getItemCount(): Int = cabinetModes.size
35
36 override fun onBindViewHolder(holder: CabinetModeViewHolder, position: Int) =
37 holder.bind(cabinetModes[position])
38
39 override fun onClick(view: View) {
40 val mode = (view.tag as CabinetModeViewHolder).cabinetMode
41 val appletPath = NativeLibrary.getAppletLaunchPath(AppletInfo.Cabinet.entryId)
42 NativeLibrary.setCurrentAppletId(AppletInfo.Cabinet.appletId)
43 NativeLibrary.setCabinetMode(mode.id)
44 val appletGame = Game(
45 title = YuzuApplication.appContext.getString(R.string.cabinet_applet),
46 path = appletPath
47 )
48 val action = HomeNavigationDirections.actionGlobalEmulationActivity(appletGame)
49 fragment.findNavController().navigate(action)
50 }
51
52 inner class CabinetModeViewHolder(val binding: DialogListItemBinding) :
53 RecyclerView.ViewHolder(binding.root) {
54 lateinit var cabinetMode: CabinetMode
55
56 init {
57 itemView.tag = this
58 }
59
60 fun bind(cabinetMode: CabinetMode) {
61 this.cabinetMode = cabinetMode
62 binding.icon.setImageDrawable(
63 ResourcesCompat.getDrawable(
64 binding.icon.context.resources,
65 cabinetMode.iconId,
66 binding.icon.context.theme
67 )
68 )
69 binding.title.setText(cabinetMode.titleId)
70 }
71 }
72}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index f9f88a1d2..0c82cdba8 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -147,7 +147,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
147 147
148 private class DiffCallback : DiffUtil.ItemCallback<Game>() { 148 private class DiffCallback : DiffUtil.ItemCallback<Game>() {
149 override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean { 149 override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
150 return oldItem.gameId == newItem.gameId 150 return oldItem.programId == newItem.programId
151 } 151 }
152 152
153 override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean { 153 override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt
new file mode 100644
index 000000000..1f66b440d
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt
@@ -0,0 +1,113 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.fragments
5
6import android.os.Bundle
7import android.view.LayoutInflater
8import android.view.View
9import android.view.ViewGroup
10import androidx.core.view.ViewCompat
11import androidx.core.view.WindowInsetsCompat
12import androidx.core.view.updatePadding
13import androidx.fragment.app.Fragment
14import androidx.fragment.app.activityViewModels
15import androidx.navigation.findNavController
16import androidx.recyclerview.widget.GridLayoutManager
17import com.google.android.material.transition.MaterialSharedAxis
18import org.yuzu.yuzu_emu.R
19import org.yuzu.yuzu_emu.adapters.AppletAdapter
20import org.yuzu.yuzu_emu.databinding.FragmentAppletLauncherBinding
21import org.yuzu.yuzu_emu.model.Applet
22import org.yuzu.yuzu_emu.model.AppletInfo
23import org.yuzu.yuzu_emu.model.HomeViewModel
24
25class AppletLauncherFragment : Fragment() {
26 private var _binding: FragmentAppletLauncherBinding? = null
27 private val binding get() = _binding!!
28
29 private val homeViewModel: HomeViewModel by activityViewModels()
30
31 override fun onCreate(savedInstanceState: Bundle?) {
32 super.onCreate(savedInstanceState)
33 enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
34 returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
35 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
36 }
37
38 override fun onCreateView(
39 inflater: LayoutInflater,
40 container: ViewGroup?,
41 savedInstanceState: Bundle?
42 ): View {
43 _binding = FragmentAppletLauncherBinding.inflate(inflater)
44 return binding.root
45 }
46
47 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
48 super.onViewCreated(view, savedInstanceState)
49 homeViewModel.setNavigationVisibility(visible = false, animated = true)
50 homeViewModel.setStatusBarShadeVisibility(visible = false)
51
52 binding.toolbarApplets.setNavigationOnClickListener {
53 binding.root.findNavController().popBackStack()
54 }
55
56 val applets = listOf(
57 Applet(
58 R.string.album_applet,
59 R.string.album_applet_description,
60 R.drawable.ic_album,
61 AppletInfo.PhotoViewer
62 ),
63 Applet(
64 R.string.cabinet_applet,
65 R.string.cabinet_applet_description,
66 R.drawable.ic_nfc,
67 AppletInfo.Cabinet
68 ),
69 Applet(
70 R.string.mii_edit_applet,
71 R.string.mii_edit_applet_description,
72 R.drawable.ic_mii,
73 AppletInfo.MiiEdit
74 )
75 )
76
77 binding.listApplets.apply {
78 layoutManager = GridLayoutManager(
79 requireContext(),
80 resources.getInteger(R.integer.grid_columns)
81 )
82 adapter = AppletAdapter(requireActivity(), applets)
83 }
84
85 setInsets()
86 }
87
88 private fun setInsets() =
89 ViewCompat.setOnApplyWindowInsetsListener(
90 binding.root
91 ) { _: View, windowInsets: WindowInsetsCompat ->
92 val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
93 val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
94
95 val leftInsets = barInsets.left + cutoutInsets.left
96 val rightInsets = barInsets.right + cutoutInsets.right
97
98 val mlpAppBar = binding.toolbarApplets.layoutParams as ViewGroup.MarginLayoutParams
99 mlpAppBar.leftMargin = leftInsets
100 mlpAppBar.rightMargin = rightInsets
101 binding.toolbarApplets.layoutParams = mlpAppBar
102
103 val mlpListApplets =
104 binding.listApplets.layoutParams as ViewGroup.MarginLayoutParams
105 mlpListApplets.leftMargin = leftInsets
106 mlpListApplets.rightMargin = rightInsets
107 binding.listApplets.layoutParams = mlpListApplets
108
109 binding.listApplets.updatePadding(bottom = barInsets.bottom)
110
111 windowInsets
112 }
113}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/CabinetLauncherDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/CabinetLauncherDialogFragment.kt
new file mode 100644
index 000000000..5933677fd
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/CabinetLauncherDialogFragment.kt
@@ -0,0 +1,41 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.fragments
5
6import android.app.Dialog
7import android.os.Bundle
8import android.view.LayoutInflater
9import android.view.View
10import android.view.ViewGroup
11import androidx.fragment.app.DialogFragment
12import androidx.recyclerview.widget.LinearLayoutManager
13import com.google.android.material.dialog.MaterialAlertDialogBuilder
14import org.yuzu.yuzu_emu.R
15import org.yuzu.yuzu_emu.adapters.CabinetLauncherDialogAdapter
16import org.yuzu.yuzu_emu.databinding.DialogListBinding
17
18class CabinetLauncherDialogFragment : DialogFragment() {
19 private lateinit var binding: DialogListBinding
20
21 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
22 binding = DialogListBinding.inflate(layoutInflater)
23 binding.dialogList.apply {
24 layoutManager = LinearLayoutManager(requireContext())
25 adapter = CabinetLauncherDialogAdapter(this@CabinetLauncherDialogFragment)
26 }
27
28 return MaterialAlertDialogBuilder(requireContext())
29 .setTitle(R.string.cabinet_launcher)
30 .setView(binding.root)
31 .create()
32 }
33
34 override fun onCreateView(
35 inflater: LayoutInflater,
36 container: ViewGroup?,
37 savedInstanceState: Bundle?
38 ): View {
39 return binding.root
40 }
41}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 598a9d42b..c456c0592 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -15,6 +15,7 @@ import android.net.Uri
15import android.os.Bundle 15import android.os.Bundle
16import android.os.Handler 16import android.os.Handler
17import android.os.Looper 17import android.os.Looper
18import android.os.SystemClock
18import android.view.* 19import android.view.*
19import android.widget.TextView 20import android.widget.TextView
20import android.widget.Toast 21import android.widget.Toast
@@ -25,6 +26,7 @@ import androidx.core.graphics.Insets
25import androidx.core.view.ViewCompat 26import androidx.core.view.ViewCompat
26import androidx.core.view.WindowInsetsCompat 27import androidx.core.view.WindowInsetsCompat
27import androidx.drawerlayout.widget.DrawerLayout 28import androidx.drawerlayout.widget.DrawerLayout
29import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
28import androidx.fragment.app.Fragment 30import androidx.fragment.app.Fragment
29import androidx.fragment.app.activityViewModels 31import androidx.fragment.app.activityViewModels
30import androidx.lifecycle.Lifecycle 32import androidx.lifecycle.Lifecycle
@@ -156,6 +158,32 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
156 binding.showFpsText.setTextColor(Color.YELLOW) 158 binding.showFpsText.setTextColor(Color.YELLOW)
157 binding.doneControlConfig.setOnClickListener { stopConfiguringControls() } 159 binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
158 160
161 binding.drawerLayout.addDrawerListener(object : DrawerListener {
162 override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
163 binding.surfaceInputOverlay.dispatchTouchEvent(
164 MotionEvent.obtain(
165 SystemClock.uptimeMillis(),
166 SystemClock.uptimeMillis() + 100,
167 MotionEvent.ACTION_UP,
168 0f,
169 0f,
170 0
171 )
172 )
173 }
174
175 override fun onDrawerOpened(drawerView: View) {
176 // No op
177 }
178
179 override fun onDrawerClosed(drawerView: View) {
180 // No op
181 }
182
183 override fun onDrawerStateChanged(newState: Int) {
184 // No op
185 }
186 })
159 binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) 187 binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
160 binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text = 188 binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
161 game.title 189 game.title
@@ -284,6 +312,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
284 ViewUtils.showView(binding.surfaceInputOverlay) 312 ViewUtils.showView(binding.surfaceInputOverlay)
285 ViewUtils.hideView(binding.loadingIndicator) 313 ViewUtils.hideView(binding.loadingIndicator)
286 314
315 emulationState.updateSurface()
316
287 // Setup overlay 317 // Setup overlay
288 updateShowFpsOverlay() 318 updateShowFpsOverlay()
289 } 319 }
@@ -777,6 +807,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
777 } 807 }
778 808
779 @Synchronized 809 @Synchronized
810 fun updateSurface() {
811 if (surface != null) {
812 NativeLibrary.surfaceChanged(surface)
813 }
814 }
815
816 @Synchronized
780 fun clearSurface() { 817 fun clearSurface() {
781 if (surface == null) { 818 if (surface == null) {
782 Log.warning("[EmulationFragment] clearSurface called, but surface already null.") 819 Log.warning("[EmulationFragment] clearSurface called, but surface already null.")
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
index fd9785075..4720daec4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
@@ -26,10 +26,11 @@ import androidx.fragment.app.Fragment
26import androidx.fragment.app.activityViewModels 26import androidx.fragment.app.activityViewModels
27import androidx.navigation.findNavController 27import androidx.navigation.findNavController
28import androidx.navigation.fragment.findNavController 28import androidx.navigation.fragment.findNavController
29import androidx.recyclerview.widget.LinearLayoutManager 29import androidx.recyclerview.widget.GridLayoutManager
30import com.google.android.material.transition.MaterialSharedAxis 30import com.google.android.material.transition.MaterialSharedAxis
31import org.yuzu.yuzu_emu.BuildConfig 31import org.yuzu.yuzu_emu.BuildConfig
32import org.yuzu.yuzu_emu.HomeNavigationDirections 32import org.yuzu.yuzu_emu.HomeNavigationDirections
33import org.yuzu.yuzu_emu.NativeLibrary
33import org.yuzu.yuzu_emu.R 34import org.yuzu.yuzu_emu.R
34import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter 35import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
35import org.yuzu.yuzu_emu.databinding.FragmentHomeSettingsBinding 36import org.yuzu.yuzu_emu.databinding.FragmentHomeSettingsBinding
@@ -41,6 +42,7 @@ import org.yuzu.yuzu_emu.model.HomeViewModel
41import org.yuzu.yuzu_emu.ui.main.MainActivity 42import org.yuzu.yuzu_emu.ui.main.MainActivity
42import org.yuzu.yuzu_emu.utils.FileUtil 43import org.yuzu.yuzu_emu.utils.FileUtil
43import org.yuzu.yuzu_emu.utils.GpuDriverHelper 44import org.yuzu.yuzu_emu.utils.GpuDriverHelper
45import org.yuzu.yuzu_emu.utils.Log
44 46
45class HomeSettingsFragment : Fragment() { 47class HomeSettingsFragment : Fragment() {
46 private var _binding: FragmentHomeSettingsBinding? = null 48 private var _binding: FragmentHomeSettingsBinding? = null
@@ -85,28 +87,6 @@ class HomeSettingsFragment : Fragment() {
85 ) 87 )
86 add( 88 add(
87 HomeSetting( 89 HomeSetting(
88 R.string.open_user_folder,
89 R.string.open_user_folder_description,
90 R.drawable.ic_folder_open,
91 { openFileManager() }
92 )
93 )
94 add(
95 HomeSetting(
96 R.string.preferences_theme,
97 R.string.theme_and_color_description,
98 R.drawable.ic_palette,
99 {
100 val action = HomeNavigationDirections.actionGlobalSettingsActivity(
101 null,
102 Settings.MenuTag.SECTION_THEME
103 )
104 binding.root.findNavController().navigate(action)
105 }
106 )
107 )
108 add(
109 HomeSetting(
110 R.string.gpu_driver_manager, 90 R.string.gpu_driver_manager,
111 R.string.install_gpu_driver_description, 91 R.string.install_gpu_driver_description,
112 R.drawable.ic_build, 92 R.drawable.ic_build,
@@ -122,6 +102,20 @@ class HomeSettingsFragment : Fragment() {
122 ) 102 )
123 add( 103 add(
124 HomeSetting( 104 HomeSetting(
105 R.string.applets,
106 R.string.applets_description,
107 R.drawable.ic_applet,
108 {
109 binding.root.findNavController()
110 .navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
111 },
112 { NativeLibrary.isFirmwareAvailable() },
113 R.string.applets_error_firmware,
114 R.string.applets_error_description
115 )
116 )
117 add(
118 HomeSetting(
125 R.string.manage_yuzu_data, 119 R.string.manage_yuzu_data,
126 R.string.manage_yuzu_data_description, 120 R.string.manage_yuzu_data_description,
127 R.drawable.ic_install, 121 R.drawable.ic_install,
@@ -157,6 +151,28 @@ class HomeSettingsFragment : Fragment() {
157 ) 151 )
158 add( 152 add(
159 HomeSetting( 153 HomeSetting(
154 R.string.open_user_folder,
155 R.string.open_user_folder_description,
156 R.drawable.ic_folder_open,
157 { openFileManager() }
158 )
159 )
160 add(
161 HomeSetting(
162 R.string.preferences_theme,
163 R.string.theme_and_color_description,
164 R.drawable.ic_palette,
165 {
166 val action = HomeNavigationDirections.actionGlobalSettingsActivity(
167 null,
168 Settings.MenuTag.SECTION_THEME
169 )
170 binding.root.findNavController().navigate(action)
171 }
172 )
173 )
174 add(
175 HomeSetting(
160 R.string.about, 176 R.string.about,
161 R.string.about_description, 177 R.string.about_description,
162 R.drawable.ic_info_outline, 178 R.drawable.ic_info_outline,
@@ -186,7 +202,8 @@ class HomeSettingsFragment : Fragment() {
186 } 202 }
187 203
188 binding.homeSettingsList.apply { 204 binding.homeSettingsList.apply {
189 layoutManager = LinearLayoutManager(requireContext()) 205 layoutManager =
206 GridLayoutManager(requireContext(), resources.getInteger(R.integer.grid_columns))
190 adapter = HomeSettingAdapter( 207 adapter = HomeSettingAdapter(
191 requireActivity() as AppCompatActivity, 208 requireActivity() as AppCompatActivity,
192 viewLifecycleOwner, 209 viewLifecycleOwner,
@@ -296,19 +313,32 @@ class HomeSettingsFragment : Fragment() {
296 } 313 }
297 } 314 }
298 315
316 // Share the current log if we just returned from a game but share the old log
317 // if we just started the app and the old log exists.
299 private fun shareLog() { 318 private fun shareLog() {
300 val file = DocumentFile.fromSingleUri( 319 val currentLog = DocumentFile.fromSingleUri(
301 mainActivity, 320 mainActivity,
302 DocumentsContract.buildDocumentUri( 321 DocumentsContract.buildDocumentUri(
303 DocumentProvider.AUTHORITY, 322 DocumentProvider.AUTHORITY,
304 "${DocumentProvider.ROOT_ID}/log/yuzu_log.txt" 323 "${DocumentProvider.ROOT_ID}/log/yuzu_log.txt"
305 ) 324 )
306 )!! 325 )!!
307 if (file.exists()) { 326 val oldLog = DocumentFile.fromSingleUri(
308 val intent = Intent(Intent.ACTION_SEND) 327 mainActivity,
309 .setDataAndType(file.uri, FileUtil.TEXT_PLAIN) 328 DocumentsContract.buildDocumentUri(
310 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 329 DocumentProvider.AUTHORITY,
311 .putExtra(Intent.EXTRA_STREAM, file.uri) 330 "${DocumentProvider.ROOT_ID}/log/yuzu_log.txt.old.txt"
331 )
332 )!!
333
334 val intent = Intent(Intent.ACTION_SEND)
335 .setDataAndType(currentLog.uri, FileUtil.TEXT_PLAIN)
336 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
337 if (!Log.gameLaunched && oldLog.exists()) {
338 intent.putExtra(Intent.EXTRA_STREAM, oldLog.uri)
339 startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
340 } else if (currentLog.exists()) {
341 intent.putExtra(Intent.EXTRA_STREAM, currentLog.uri)
312 startActivity(Intent.createChooser(intent, getText(R.string.share_log))) 342 startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
313 } else { 343 } else {
314 Toast.makeText( 344 Toast.makeText(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt
index 541b22f47..a6183d19e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt
@@ -8,6 +8,7 @@ import android.content.DialogInterface
8import android.content.Intent 8import android.content.Intent
9import android.net.Uri 9import android.net.Uri
10import android.os.Bundle 10import android.os.Bundle
11import android.text.Html
11import androidx.fragment.app.DialogFragment 12import androidx.fragment.app.DialogFragment
12import androidx.fragment.app.FragmentActivity 13import androidx.fragment.app.FragmentActivity
13import androidx.fragment.app.activityViewModels 14import androidx.fragment.app.activityViewModels
@@ -32,7 +33,9 @@ class MessageDialogFragment : DialogFragment() {
32 if (titleId != 0) dialog.setTitle(titleId) 33 if (titleId != 0) dialog.setTitle(titleId)
33 if (titleString.isNotEmpty()) dialog.setTitle(titleString) 34 if (titleString.isNotEmpty()) dialog.setTitle(titleString)
34 35
35 if (descriptionId != 0) dialog.setMessage(descriptionId) 36 if (descriptionId != 0) {
37 dialog.setMessage(Html.fromHtml(getString(descriptionId), Html.FROM_HTML_MODE_LEGACY))
38 }
36 if (descriptionString.isNotEmpty()) dialog.setMessage(descriptionString) 39 if (descriptionString.isNotEmpty()) dialog.setMessage(descriptionString)
37 40
38 if (helpLinkId != 0) { 41 if (helpLinkId != 0) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Applet.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Applet.kt
new file mode 100644
index 000000000..8677674a3
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Applet.kt
@@ -0,0 +1,55 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.model
5
6import androidx.annotation.DrawableRes
7import androidx.annotation.StringRes
8import org.yuzu.yuzu_emu.R
9
10data class Applet(
11 @StringRes val titleId: Int,
12 @StringRes val descriptionId: Int,
13 @DrawableRes val iconId: Int,
14 val appletInfo: AppletInfo,
15 val cabinetMode: CabinetMode = CabinetMode.None
16)
17
18// Combination of Common::AM::Applets::AppletId enum and the entry id
19enum class AppletInfo(val appletId: Int, val entryId: Long = 0) {
20 None(0x00),
21 Application(0x01),
22 OverlayDisplay(0x02),
23 QLaunch(0x03),
24 Starter(0x04),
25 Auth(0x0A),
26 Cabinet(0x0B, 0x0100000000001002),
27 Controller(0x0C),
28 DataErase(0x0D),
29 Error(0x0E),
30 NetConnect(0x0F),
31 ProfileSelect(0x10),
32 SoftwareKeyboard(0x11),
33 MiiEdit(0x12, 0x0100000000001009),
34 Web(0x13),
35 Shop(0x14),
36 PhotoViewer(0x015, 0x010000000000100D),
37 Settings(0x16),
38 OfflineWeb(0x17),
39 LoginShare(0x18),
40 WebAuth(0x19),
41 MyPage(0x1A)
42}
43
44// Matches enum in Service::NFP::CabinetMode with extra metadata
45enum class CabinetMode(
46 val id: Int,
47 @StringRes val titleId: Int = 0,
48 @DrawableRes val iconId: Int = 0
49) {
50 None(-1),
51 StartNicknameAndOwnerSettings(0, R.string.cabinet_nickname_and_owner, R.drawable.ic_edit),
52 StartGameDataEraser(1, R.string.cabinet_game_data_eraser, R.drawable.ic_refresh),
53 StartRestorer(2, R.string.cabinet_restorer, R.drawable.ic_restore),
54 StartFormatter(3, R.string.cabinet_formatter, R.drawable.ic_clear)
55}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
index 6527c64ab..de84b2adb 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
@@ -11,16 +11,15 @@ import kotlinx.serialization.Serializable
11@Parcelize 11@Parcelize
12@Serializable 12@Serializable
13class Game( 13class Game(
14 val title: String, 14 val title: String = "",
15 val description: String,
16 val regions: String,
17 val path: String, 15 val path: String,
18 val gameId: String, 16 val programId: String = "",
19 val company: String, 17 val developer: String = "",
20 val isHomebrew: Boolean 18 val version: String = "",
19 val isHomebrew: Boolean = false
21) : Parcelable { 20) : Parcelable {
22 val keyAddedToLibraryTime get() = "${gameId}_AddedToLibraryTime" 21 val keyAddedToLibraryTime get() = "${programId}_AddedToLibraryTime"
23 val keyLastPlayedTime get() = "${gameId}_LastPlayed" 22 val keyLastPlayedTime get() = "${programId}_LastPlayed"
24 23
25 override fun equals(other: Any?): Boolean { 24 override fun equals(other: Any?): Boolean {
26 if (other !is Game) { 25 if (other !is Game) {
@@ -32,11 +31,9 @@ class Game(
32 31
33 override fun hashCode(): Int { 32 override fun hashCode(): Int {
34 var result = title.hashCode() 33 var result = title.hashCode()
35 result = 31 * result + description.hashCode()
36 result = 31 * result + regions.hashCode()
37 result = 31 * result + path.hashCode() 34 result = 31 * result + path.hashCode()
38 result = 31 * result + gameId.hashCode() 35 result = 31 * result + programId.hashCode()
39 result = 31 * result + company.hashCode() 36 result = 31 * result + developer.hashCode()
40 result = 31 * result + isHomebrew.hashCode() 37 result = 31 * result + isHomebrew.hashCode()
41 return result 38 return result
42 } 39 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
index 6e09fa81d..8512ed17c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
@@ -14,15 +14,13 @@ import kotlinx.coroutines.flow.MutableStateFlow
14import kotlinx.coroutines.flow.StateFlow 14import kotlinx.coroutines.flow.StateFlow
15import kotlinx.coroutines.launch 15import kotlinx.coroutines.launch
16import kotlinx.coroutines.withContext 16import kotlinx.coroutines.withContext
17import kotlinx.serialization.ExperimentalSerializationApi
18import kotlinx.serialization.MissingFieldException
19import kotlinx.serialization.decodeFromString 17import kotlinx.serialization.decodeFromString
20import kotlinx.serialization.json.Json 18import kotlinx.serialization.json.Json
21import org.yuzu.yuzu_emu.NativeLibrary 19import org.yuzu.yuzu_emu.NativeLibrary
22import org.yuzu.yuzu_emu.YuzuApplication 20import org.yuzu.yuzu_emu.YuzuApplication
23import org.yuzu.yuzu_emu.utils.GameHelper 21import org.yuzu.yuzu_emu.utils.GameHelper
22import org.yuzu.yuzu_emu.utils.GameMetadata
24 23
25@OptIn(ExperimentalSerializationApi::class)
26class GamesViewModel : ViewModel() { 24class GamesViewModel : ViewModel() {
27 val games: StateFlow<List<Game>> get() = _games 25 val games: StateFlow<List<Game>> get() = _games
28 private val _games = MutableStateFlow(emptyList<Game>()) 26 private val _games = MutableStateFlow(emptyList<Game>())
@@ -49,26 +47,34 @@ class GamesViewModel : ViewModel() {
49 // Retrieve list of cached games 47 // Retrieve list of cached games
50 val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) 48 val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
51 .getStringSet(GameHelper.KEY_GAMES, emptySet()) 49 .getStringSet(GameHelper.KEY_GAMES, emptySet())
52 if (storedGames!!.isNotEmpty()) {
53 val deserializedGames = mutableSetOf<Game>()
54 storedGames.forEach {
55 val game: Game
56 try {
57 game = Json.decodeFromString(it)
58 } catch (e: MissingFieldException) {
59 return@forEach
60 }
61 50
62 val gameExists = 51 viewModelScope.launch {
63 DocumentFile.fromSingleUri(YuzuApplication.appContext, Uri.parse(game.path)) 52 withContext(Dispatchers.IO) {
64 ?.exists() 53 if (storedGames!!.isNotEmpty()) {
65 if (gameExists == true) { 54 val deserializedGames = mutableSetOf<Game>()
66 deserializedGames.add(game) 55 storedGames.forEach {
56 val game: Game
57 try {
58 game = Json.decodeFromString(it)
59 } catch (e: Exception) {
60 // We don't care about any errors related to parsing the game cache
61 return@forEach
62 }
63
64 val gameExists =
65 DocumentFile.fromSingleUri(
66 YuzuApplication.appContext,
67 Uri.parse(game.path)
68 )?.exists()
69 if (gameExists == true) {
70 deserializedGames.add(game)
71 }
72 }
73 setGames(deserializedGames.toList())
67 } 74 }
75 reloadGames(false)
68 } 76 }
69 setGames(deserializedGames.toList())
70 } 77 }
71 reloadGames(false)
72 } 78 }
73 79
74 fun setGames(games: List<Game>) { 80 fun setGames(games: List<Game>) {
@@ -106,7 +112,7 @@ class GamesViewModel : ViewModel() {
106 112
107 viewModelScope.launch { 113 viewModelScope.launch {
108 withContext(Dispatchers.IO) { 114 withContext(Dispatchers.IO) {
109 NativeLibrary.resetRomMetadata() 115 GameMetadata.resetMetadata()
110 setGames(GameHelper.getGames()) 116 setGames(GameHelper.getGames())
111 _isReloading.value = false 117 _isReloading.value = false
112 118
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index 233aa4101..211b7cf69 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -403,6 +403,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
403 } else { 403 } else {
404 firmwarePath.deleteRecursively() 404 firmwarePath.deleteRecursively()
405 cacheFirmwareDir.copyRecursively(firmwarePath, true) 405 cacheFirmwareDir.copyRecursively(firmwarePath, true)
406 NativeLibrary.initializeSystem(true)
406 getString(R.string.save_file_imported_success) 407 getString(R.string.save_file_imported_success)
407 } 408 }
408 } catch (e: Exception) { 409 } catch (e: Exception) {
@@ -648,7 +649,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
648 } 649 }
649 650
650 // Reinitialize relevant data 651 // Reinitialize relevant data
651 NativeLibrary.initializeEmulation() 652 NativeLibrary.initializeSystem(true)
652 gamesViewModel.reloadGames(false) 653 gamesViewModel.reloadGames(false)
653 654
654 return@newInstance getString(R.string.user_data_import_success) 655 return@newInstance getString(R.string.user_data_import_success)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ControllerMappingHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ControllerMappingHelper.kt
deleted file mode 100644
index eeefcdf20..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ControllerMappingHelper.kt
+++ /dev/null
@@ -1,70 +0,0 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.utils
5
6import android.view.InputDevice
7import android.view.KeyEvent
8import android.view.MotionEvent
9
10/**
11 * Some controllers have incorrect mappings. This class has special-case fixes for them.
12 */
13class ControllerMappingHelper {
14 /**
15 * Some controllers report extra button presses that can be ignored.
16 */
17 fun shouldKeyBeIgnored(inputDevice: InputDevice, keyCode: Int): Boolean {
18 return if (isDualShock4(inputDevice)) {
19 // The two analog triggers generate analog motion events as well as a keycode.
20 // We always prefer to use the analog values, so throw away the button press
21 keyCode == KeyEvent.KEYCODE_BUTTON_L2 || keyCode == KeyEvent.KEYCODE_BUTTON_R2
22 } else {
23 false
24 }
25 }
26
27 /**
28 * Scale an axis to be zero-centered with a proper range.
29 */
30 fun scaleAxis(inputDevice: InputDevice, axis: Int, value: Float): Float {
31 if (isDualShock4(inputDevice)) {
32 // Android doesn't have correct mappings for this controller's triggers. It reports them
33 // as RX & RY, centered at -1.0, and with a range of [-1.0, 1.0]
34 // Scale them to properly zero-centered with a range of [0.0, 1.0].
35 if (axis == MotionEvent.AXIS_RX || axis == MotionEvent.AXIS_RY) {
36 return (value + 1) / 2.0f
37 }
38 } else if (isXboxOneWireless(inputDevice)) {
39 // Same as the DualShock 4, the mappings are missing.
40 if (axis == MotionEvent.AXIS_Z || axis == MotionEvent.AXIS_RZ) {
41 return (value + 1) / 2.0f
42 }
43 if (axis == MotionEvent.AXIS_GENERIC_1) {
44 // This axis is stuck at ~.5. Ignore it.
45 return 0.0f
46 }
47 } else if (isMogaPro2Hid(inputDevice)) {
48 // This controller has a broken axis that reports a constant value. Ignore it.
49 if (axis == MotionEvent.AXIS_GENERIC_1) {
50 return 0.0f
51 }
52 }
53 return value
54 }
55
56 // Sony DualShock 4 controller
57 private fun isDualShock4(inputDevice: InputDevice): Boolean {
58 return inputDevice.vendorId == 0x54c && inputDevice.productId == 0x9cc
59 }
60
61 // Microsoft Xbox One controller
62 private fun isXboxOneWireless(inputDevice: InputDevice): Boolean {
63 return inputDevice.vendorId == 0x45e && inputDevice.productId == 0x2e0
64 }
65
66 // Moga Pro 2 HID
67 private fun isMogaPro2Hid(inputDevice: InputDevice): Boolean {
68 return inputDevice.vendorId == 0x20d6 && inputDevice.productId == 0x6271
69 }
70}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
index 3c9f6bad0..5e9a1176a 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
@@ -15,7 +15,7 @@ object DirectoryInitialization {
15 fun start() { 15 fun start() {
16 if (!areDirectoriesReady) { 16 if (!areDirectoriesReady) {
17 initializeInternalStorage() 17 initializeInternalStorage()
18 NativeLibrary.initializeEmulation() 18 NativeLibrary.initializeSystem(false)
19 areDirectoriesReady = true 19 areDirectoriesReady = true
20 } 20 }
21 } 21 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
index eafcf9e42..738275297 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
@@ -42,6 +42,23 @@ class DocumentsTree {
42 return node != null && node.isDirectory 42 return node != null && node.isDirectory
43 } 43 }
44 44
45 fun getParentDirectory(filepath: String): String {
46 val node = resolvePath(filepath)!!
47 val parentNode = node.parent
48 if (parentNode != null && parentNode.isDirectory) {
49 return parentNode.uri!!.toString()
50 }
51 return node.uri!!.toString()
52 }
53
54 fun getFilename(filepath: String): String {
55 val node = resolvePath(filepath)
56 if (node != null) {
57 return node.name!!
58 }
59 return filepath
60 }
61
45 private fun resolvePath(filepath: String): DocumentsNode? { 62 private fun resolvePath(filepath: String): DocumentsNode? {
46 val tokens = StringTokenizer(filepath, File.separator, false) 63 val tokens = StringTokenizer(filepath, File.separator, false)
47 var iterator = root 64 var iterator = root
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
index 5ee74a52c..8c3268e9c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
@@ -144,7 +144,7 @@ object FileUtil {
144 * @param path Native content uri path 144 * @param path Native content uri path
145 * @return bool 145 * @return bool
146 */ 146 */
147 fun exists(path: String?): Boolean { 147 fun exists(path: String?, suppressLog: Boolean = false): Boolean {
148 var c: Cursor? = null 148 var c: Cursor? = null
149 try { 149 try {
150 val mUri = Uri.parse(path) 150 val mUri = Uri.parse(path)
@@ -152,7 +152,9 @@ object FileUtil {
152 c = context.contentResolver.query(mUri, columns, null, null, null) 152 c = context.contentResolver.query(mUri, columns, null, null, null)
153 return c!!.count > 0 153 return c!!.count > 0
154 } catch (e: Exception) { 154 } catch (e: Exception) {
155 Log.info("[FileUtil] Cannot find file from given path, error: " + e.message) 155 if (!suppressLog) {
156 Log.info("[FileUtil] Cannot find file from given path, error: " + e.message)
157 }
156 } finally { 158 } finally {
157 closeQuietly(c) 159 closeQuietly(c)
158 } 160 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
index 9001ca9ab..e6aca6b44 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
@@ -71,27 +71,26 @@ object GameHelper {
71 71
72 fun getGame(uri: Uri, addedToLibrary: Boolean): Game { 72 fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
73 val filePath = uri.toString() 73 val filePath = uri.toString()
74 var name = NativeLibrary.getTitle(filePath) 74 var name = GameMetadata.getTitle(filePath)
75 75
76 // If the game's title field is empty, use the filename. 76 // If the game's title field is empty, use the filename.
77 if (name.isEmpty()) { 77 if (name.isEmpty()) {
78 name = FileUtil.getFilename(uri) 78 name = FileUtil.getFilename(uri)
79 } 79 }
80 var gameId = NativeLibrary.getGameId(filePath) 80 var programId = GameMetadata.getProgramId(filePath)
81 81
82 // If the game's ID field is empty, use the filename without extension. 82 // If the game's ID field is empty, use the filename without extension.
83 if (gameId.isEmpty()) { 83 if (programId.isEmpty()) {
84 gameId = name.substring(0, name.lastIndexOf(".")) 84 programId = name.substring(0, name.lastIndexOf("."))
85 } 85 }
86 86
87 val newGame = Game( 87 val newGame = Game(
88 name, 88 name,
89 NativeLibrary.getDescription(filePath).replace("\n", " "),
90 NativeLibrary.getRegions(filePath),
91 filePath, 89 filePath,
92 gameId, 90 programId,
93 NativeLibrary.getCompany(filePath), 91 GameMetadata.getDeveloper(filePath),
94 NativeLibrary.isHomebrew(filePath) 92 GameMetadata.getVersion(filePath),
93 GameMetadata.getIsHomebrew(filePath)
95 ) 94 )
96 95
97 if (addedToLibrary) { 96 if (addedToLibrary) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
index 9fe99fab1..654d62f52 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
@@ -18,7 +18,6 @@ import coil.key.Keyer
18import coil.memory.MemoryCache 18import coil.memory.MemoryCache
19import coil.request.ImageRequest 19import coil.request.ImageRequest
20import coil.request.Options 20import coil.request.Options
21import org.yuzu.yuzu_emu.NativeLibrary
22import org.yuzu.yuzu_emu.R 21import org.yuzu.yuzu_emu.R
23import org.yuzu.yuzu_emu.YuzuApplication 22import org.yuzu.yuzu_emu.YuzuApplication
24import org.yuzu.yuzu_emu.model.Game 23import org.yuzu.yuzu_emu.model.Game
@@ -36,7 +35,7 @@ class GameIconFetcher(
36 } 35 }
37 36
38 private fun decodeGameIcon(uri: String): Bitmap? { 37 private fun decodeGameIcon(uri: String): Bitmap? {
39 val data = NativeLibrary.getIcon(uri) 38 val data = GameMetadata.getIcon(uri)
40 return BitmapFactory.decodeByteArray( 39 return BitmapFactory.decodeByteArray(
41 data, 40 data,
42 0, 41 0,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt
new file mode 100644
index 000000000..0f3542ac6
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.utils
5
6object GameMetadata {
7 external fun getTitle(path: String): String
8
9 external fun getProgramId(path: String): String
10
11 external fun getDeveloper(path: String): String
12
13 external fun getVersion(path: String): String
14
15 external fun getIcon(path: String): ByteArray
16
17 external fun getIsHomebrew(path: String): Boolean
18
19 external fun resetMetadata()
20}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
index e963dfbc1..47bde5081 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
@@ -3,17 +3,24 @@
3 3
4package org.yuzu.yuzu_emu.utils 4package org.yuzu.yuzu_emu.utils
5 5
6import android.view.InputDevice
6import android.view.KeyEvent 7import android.view.KeyEvent
7import android.view.MotionEvent 8import android.view.MotionEvent
8import kotlin.math.sqrt 9import kotlin.math.sqrt
9import org.yuzu.yuzu_emu.NativeLibrary 10import org.yuzu.yuzu_emu.NativeLibrary
10 11
11class InputHandler { 12object InputHandler {
13 private var controllerIds = getGameControllerIds()
14
12 fun initialize() { 15 fun initialize() {
13 // Connect first controller 16 // Connect first controller
14 NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device)) 17 NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device))
15 } 18 }
16 19
20 fun updateControllerIds() {
21 controllerIds = getGameControllerIds()
22 }
23
17 fun dispatchKeyEvent(event: KeyEvent): Boolean { 24 fun dispatchKeyEvent(event: KeyEvent): Boolean {
18 val button: Int = when (event.device.vendorId) { 25 val button: Int = when (event.device.vendorId) {
19 0x045E -> getInputXboxButtonKey(event.keyCode) 26 0x045E -> getInputXboxButtonKey(event.keyCode)
@@ -35,7 +42,7 @@ class InputHandler {
35 } 42 }
36 43
37 return NativeLibrary.onGamePadButtonEvent( 44 return NativeLibrary.onGamePadButtonEvent(
38 getPlayerNumber(event.device.controllerNumber), 45 getPlayerNumber(event.device.controllerNumber, event.deviceId),
39 button, 46 button,
40 action 47 action
41 ) 48 )
@@ -58,9 +65,14 @@ class InputHandler {
58 return true 65 return true
59 } 66 }
60 67
61 private fun getPlayerNumber(index: Int): Int { 68 private fun getPlayerNumber(index: Int, deviceId: Int = -1): Int {
69 var deviceIndex = index
70 if (deviceId != -1) {
71 deviceIndex = controllerIds[deviceId] ?: 0
72 }
73
62 // TODO: Joycons are handled as different controllers. Find a way to merge them. 74 // TODO: Joycons are handled as different controllers. Find a way to merge them.
63 return when (index) { 75 return when (deviceIndex) {
64 2 -> NativeLibrary.Player2Device 76 2 -> NativeLibrary.Player2Device
65 3 -> NativeLibrary.Player3Device 77 3 -> NativeLibrary.Player3Device
66 4 -> NativeLibrary.Player4Device 78 4 -> NativeLibrary.Player4Device
@@ -238,7 +250,7 @@ class InputHandler {
238 } 250 }
239 251
240 private fun setGenericAxisInput(event: MotionEvent, axis: Int) { 252 private fun setGenericAxisInput(event: MotionEvent, axis: Int) {
241 val playerNumber = getPlayerNumber(event.device.controllerNumber) 253 val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
242 254
243 when (axis) { 255 when (axis) {
244 MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> 256 MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -297,7 +309,7 @@ class InputHandler {
297 309
298 private fun setJoyconAxisInput(event: MotionEvent, axis: Int) { 310 private fun setJoyconAxisInput(event: MotionEvent, axis: Int) {
299 // Joycon support is half dead. Right joystick doesn't work 311 // Joycon support is half dead. Right joystick doesn't work
300 val playerNumber = getPlayerNumber(event.device.controllerNumber) 312 val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
301 313
302 when (axis) { 314 when (axis) {
303 MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> 315 MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -325,7 +337,7 @@ class InputHandler {
325 } 337 }
326 338
327 private fun setRazerAxisInput(event: MotionEvent, axis: Int) { 339 private fun setRazerAxisInput(event: MotionEvent, axis: Int) {
328 val playerNumber = getPlayerNumber(event.device.controllerNumber) 340 val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
329 341
330 when (axis) { 342 when (axis) {
331 MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> 343 MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -362,4 +374,33 @@ class InputHandler {
362 ) 374 )
363 } 375 }
364 } 376 }
377
378 fun getGameControllerIds(): Map<Int, Int> {
379 val gameControllerDeviceIds = mutableMapOf<Int, Int>()
380 val deviceIds = InputDevice.getDeviceIds()
381 var controllerSlot = 1
382 deviceIds.forEach { deviceId ->
383 InputDevice.getDevice(deviceId)?.apply {
384 // Don't over-assign controllers
385 if (controllerSlot >= 8) {
386 return gameControllerDeviceIds
387 }
388
389 // Verify that the device has gamepad buttons, control sticks, or both.
390 if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD ||
391 sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK
392 ) {
393 // This device is a game controller. Store its device ID.
394 if (deviceId and id and vendorId and productId != 0) {
395 // Additionally filter out devices that have no ID
396 gameControllerDeviceIds
397 .takeIf { !it.contains(deviceId) }
398 ?.put(deviceId, controllerSlot)
399 controllerSlot++
400 }
401 }
402 }
403 }
404 return gameControllerDeviceIds
405 }
365} 406}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
index a193e82a4..aebe84b0f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
@@ -3,38 +3,29 @@
3 3
4package org.yuzu.yuzu_emu.utils 4package org.yuzu.yuzu_emu.utils
5 5
6import android.util.Log 6import android.os.Build
7import org.yuzu.yuzu_emu.BuildConfig 7
8
9/**
10 * Contains methods that call through to [android.util.Log], but
11 * with the same TAG automatically provided. Also no-ops VERBOSE and DEBUG log
12 * levels in release builds.
13 */
14object Log { 8object Log {
15 private const val TAG = "Yuzu Frontend" 9 // Tracks whether we should share the old log or the current log
10 var gameLaunched = false
16 11
17 fun verbose(message: String) { 12 external fun debug(message: String)
18 if (BuildConfig.DEBUG) {
19 Log.v(TAG, message)
20 }
21 }
22 13
23 fun debug(message: String) { 14 external fun warning(message: String)
24 if (BuildConfig.DEBUG) {
25 Log.d(TAG, message)
26 }
27 }
28 15
29 fun info(message: String) { 16 external fun info(message: String)
30 Log.i(TAG, message)
31 }
32 17
33 fun warning(message: String) { 18 external fun error(message: String)
34 Log.w(TAG, message)
35 }
36 19
37 fun error(message: String) { 20 external fun critical(message: String)
38 Log.e(TAG, message) 21
22 fun logDeviceInfo() {
23 info("Device Manufacturer - ${Build.MANUFACTURER}")
24 info("Device Model - ${Build.MODEL}")
25 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
26 info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}")
27 info("SoC Model - ${Build.SOC_MODEL}")
28 }
29 info("Total System Memory - ${MemoryUtil.getDeviceRAM()}")
39 } 30 }
40} 31}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
index aa4a5539a..9076a86c4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
@@ -27,7 +27,7 @@ object MemoryUtil {
27 const val Pb = Tb * 1024 27 const val Pb = Tb * 1024
28 const val Eb = Pb * 1024 28 const val Eb = Pb * 1024
29 29
30 private fun bytesToSizeUnit(size: Float): String = 30 private fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String =
31 when { 31 when {
32 size < Kb -> { 32 size < Kb -> {
33 context.getString( 33 context.getString(
@@ -39,63 +39,59 @@ object MemoryUtil {
39 size < Mb -> { 39 size < Mb -> {
40 context.getString( 40 context.getString(
41 R.string.memory_formatted, 41 R.string.memory_formatted,
42 (size / Kb).hundredths, 42 if (roundUp) ceil(size / Kb) else (size / Kb).hundredths,
43 context.getString(R.string.memory_kilobyte) 43 context.getString(R.string.memory_kilobyte)
44 ) 44 )
45 } 45 }
46 size < Gb -> { 46 size < Gb -> {
47 context.getString( 47 context.getString(
48 R.string.memory_formatted, 48 R.string.memory_formatted,
49 (size / Mb).hundredths, 49 if (roundUp) ceil(size / Mb) else (size / Mb).hundredths,
50 context.getString(R.string.memory_megabyte) 50 context.getString(R.string.memory_megabyte)
51 ) 51 )
52 } 52 }
53 size < Tb -> { 53 size < Tb -> {
54 context.getString( 54 context.getString(
55 R.string.memory_formatted, 55 R.string.memory_formatted,
56 (size / Gb).hundredths, 56 if (roundUp) ceil(size / Gb) else (size / Gb).hundredths,
57 context.getString(R.string.memory_gigabyte) 57 context.getString(R.string.memory_gigabyte)
58 ) 58 )
59 } 59 }
60 size < Pb -> { 60 size < Pb -> {
61 context.getString( 61 context.getString(
62 R.string.memory_formatted, 62 R.string.memory_formatted,
63 (size / Tb).hundredths, 63 if (roundUp) ceil(size / Tb) else (size / Tb).hundredths,
64 context.getString(R.string.memory_terabyte) 64 context.getString(R.string.memory_terabyte)
65 ) 65 )
66 } 66 }
67 size < Eb -> { 67 size < Eb -> {
68 context.getString( 68 context.getString(
69 R.string.memory_formatted, 69 R.string.memory_formatted,
70 (size / Pb).hundredths, 70 if (roundUp) ceil(size / Pb) else (size / Pb).hundredths,
71 context.getString(R.string.memory_petabyte) 71 context.getString(R.string.memory_petabyte)
72 ) 72 )
73 } 73 }
74 else -> { 74 else -> {
75 context.getString( 75 context.getString(
76 R.string.memory_formatted, 76 R.string.memory_formatted,
77 (size / Eb).hundredths, 77 if (roundUp) ceil(size / Eb) else (size / Eb).hundredths,
78 context.getString(R.string.memory_exabyte) 78 context.getString(R.string.memory_exabyte)
79 ) 79 )
80 } 80 }
81 } 81 }
82 82
83 // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for 83 val totalMemory: Float
84 // the potential error created by memInfo.totalMem
85 private val totalMemory: Float
86 get() { 84 get() {
87 val memInfo = ActivityManager.MemoryInfo() 85 val memInfo = ActivityManager.MemoryInfo()
88 with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { 86 with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) {
89 getMemoryInfo(memInfo) 87 getMemoryInfo(memInfo)
90 } 88 }
91 89
92 return ceil( 90 return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
93 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { 91 memInfo.advertisedMem.toFloat()
94 memInfo.advertisedMem.toFloat() 92 } else {
95 } else { 93 memInfo.totalMem.toFloat()
96 memInfo.totalMem.toFloat() 94 }
97 }
98 )
99 } 95 }
100 96
101 fun isLessThan(minimum: Int, size: Float): Boolean = 97 fun isLessThan(minimum: Int, size: Float): Boolean =
@@ -109,5 +105,7 @@ object MemoryUtil {
109 else -> totalMemory < Kb && totalMemory < minimum 105 else -> totalMemory < Kb && totalMemory < minimum
110 } 106 }
111 107
112 fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory) 108 // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
109 // the potential error created by memInfo.totalMem
110 fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true)
113} 111}
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt
index e15d1480b..88a570f68 100644
--- a/src/android/app/src/main/jni/CMakeLists.txt
+++ b/src/android/app/src/main/jni/CMakeLists.txt
@@ -14,8 +14,11 @@ add_library(yuzu-android SHARED
14 id_cache.cpp 14 id_cache.cpp
15 id_cache.h 15 id_cache.h
16 native.cpp 16 native.cpp
17 native.h
17 native_config.cpp 18 native_config.cpp
18 uisettings.cpp 19 uisettings.cpp
20 game_metadata.cpp
21 native_log.cpp
19) 22)
20 23
21set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) 24set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
diff --git a/src/android/app/src/main/jni/game_metadata.cpp b/src/android/app/src/main/jni/game_metadata.cpp
new file mode 100644
index 000000000..24d9df702
--- /dev/null
+++ b/src/android/app/src/main/jni/game_metadata.cpp
@@ -0,0 +1,112 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <core/core.h>
5#include <core/file_sys/patch_manager.h>
6#include <core/loader/nro.h>
7#include <jni.h>
8#include "core/loader/loader.h"
9#include "jni/android_common/android_common.h"
10#include "native.h"
11
12struct RomMetadata {
13 std::string title;
14 u64 programId;
15 std::string developer;
16 std::string version;
17 std::vector<u8> icon;
18 bool isHomebrew;
19};
20
21std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
22
23RomMetadata CacheRomMetadata(const std::string& path) {
24 const auto file =
25 Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
26 auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
27
28 RomMetadata entry;
29 loader->ReadTitle(entry.title);
30 loader->ReadProgramId(entry.programId);
31 loader->ReadIcon(entry.icon);
32
33 const FileSys::PatchManager pm{
34 entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(),
35 EmulationSession::GetInstance().System().GetContentProvider()};
36 const auto control = pm.GetControlMetadata();
37
38 if (control.first != nullptr) {
39 entry.developer = control.first->GetDeveloperName();
40 entry.version = control.first->GetVersionString();
41 } else {
42 FileSys::NACP nacp;
43 if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) {
44 entry.developer = nacp.GetDeveloperName();
45 } else {
46 entry.developer = "";
47 }
48
49 entry.version = "1.0.0";
50 }
51
52 if (loader->GetFileType() == Loader::FileType::NRO) {
53 auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
54 entry.isHomebrew = loader_nro->IsHomebrew();
55 } else {
56 entry.isHomebrew = false;
57 }
58
59 m_rom_metadata_cache[path] = entry;
60
61 return entry;
62}
63
64RomMetadata GetRomMetadata(const std::string& path) {
65 if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
66 return search->second;
67 }
68
69 return CacheRomMetadata(path);
70}
71
72extern "C" {
73
74jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
75 jstring jpath) {
76 return ToJString(env, GetRomMetadata(GetJString(env, jpath)).title);
77}
78
79jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj,
80 jstring jpath) {
81 return ToJString(env, std::to_string(GetRomMetadata(GetJString(env, jpath)).programId));
82}
83
84jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj,
85 jstring jpath) {
86 return ToJString(env, GetRomMetadata(GetJString(env, jpath)).developer);
87}
88
89jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
90 jstring jpath) {
91 return ToJString(env, GetRomMetadata(GetJString(env, jpath)).version);
92}
93
94jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
95 jstring jpath) {
96 auto icon_data = GetRomMetadata(GetJString(env, jpath)).icon;
97 jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
98 env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
99 reinterpret_cast<jbyte*>(icon_data.data()));
100 return icon;
101}
102
103jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj,
104 jstring jpath) {
105 return static_cast<jboolean>(GetRomMetadata(GetJString(env, jpath)).isHomebrew);
106}
107
108void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
109 return m_rom_metadata_cache.clear();
110}
111
112} // extern "C"
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 598f4e8bf..46438906e 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -33,7 +33,6 @@
33#include "core/crypto/key_manager.h" 33#include "core/crypto/key_manager.h"
34#include "core/file_sys/card_image.h" 34#include "core/file_sys/card_image.h"
35#include "core/file_sys/content_archive.h" 35#include "core/file_sys/content_archive.h"
36#include "core/file_sys/registered_cache.h"
37#include "core/file_sys/submission_package.h" 36#include "core/file_sys/submission_package.h"
38#include "core/file_sys/vfs.h" 37#include "core/file_sys/vfs.h"
39#include "core/file_sys/vfs_real.h" 38#include "core/file_sys/vfs_real.h"
@@ -48,520 +47,428 @@
48#include "core/hid/emulated_controller.h" 47#include "core/hid/emulated_controller.h"
49#include "core/hid/hid_core.h" 48#include "core/hid/hid_core.h"
50#include "core/hid/hid_types.h" 49#include "core/hid/hid_types.h"
51#include "core/hle/service/acc/profile_manager.h"
52#include "core/hle/service/am/applet_ae.h" 50#include "core/hle/service/am/applet_ae.h"
53#include "core/hle/service/am/applet_oe.h" 51#include "core/hle/service/am/applet_oe.h"
54#include "core/hle/service/am/applets/applets.h" 52#include "core/hle/service/am/applets/applets.h"
55#include "core/hle/service/filesystem/filesystem.h" 53#include "core/hle/service/filesystem/filesystem.h"
56#include "core/loader/loader.h" 54#include "core/loader/loader.h"
57#include "core/perf_stats.h"
58#include "jni/android_common/android_common.h" 55#include "jni/android_common/android_common.h"
59#include "jni/applets/software_keyboard.h"
60#include "jni/config.h" 56#include "jni/config.h"
61#include "jni/emu_window/emu_window.h"
62#include "jni/id_cache.h" 57#include "jni/id_cache.h"
63#include "video_core/rasterizer_interface.h" 58#include "jni/native.h"
64#include "video_core/renderer_base.h" 59#include "video_core/renderer_base.h"
65 60
66#define jconst [[maybe_unused]] const auto 61#define jconst [[maybe_unused]] const auto
67#define jauto [[maybe_unused]] auto 62#define jauto [[maybe_unused]] auto
68 63
69namespace { 64static EmulationSession s_instance;
70 65
71class EmulationSession final { 66EmulationSession::EmulationSession() {
72public: 67 m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
73 EmulationSession() { 68}
74 m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
75 }
76
77 ~EmulationSession() = default;
78
79 static EmulationSession& GetInstance() {
80 return s_instance;
81 }
82
83 const Core::System& System() const {
84 return m_system;
85 }
86 69
87 Core::System& System() { 70EmulationSession& EmulationSession::GetInstance() {
88 return m_system; 71 return s_instance;
89 } 72}
90 73
91 const EmuWindow_Android& Window() const { 74const Core::System& EmulationSession::System() const {
92 return *m_window; 75 return m_system;
93 } 76}
94 77
95 EmuWindow_Android& Window() { 78Core::System& EmulationSession::System() {
96 return *m_window; 79 return m_system;
97 } 80}
98 81
99 ANativeWindow* NativeWindow() const { 82const EmuWindow_Android& EmulationSession::Window() const {
100 return m_native_window; 83 return *m_window;
101 } 84}
102 85
103 void SetNativeWindow(ANativeWindow* native_window) { 86EmuWindow_Android& EmulationSession::Window() {
104 m_native_window = native_window; 87 return *m_window;
105 } 88}
106 89
107 int InstallFileToNand(std::string filename, std::string file_extension) { 90ANativeWindow* EmulationSession::NativeWindow() const {
108 jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest, 91 return m_native_window;
109 std::size_t block_size) { 92}
110 if (src == nullptr || dest == nullptr) {
111 return false;
112 }
113 if (!dest->Resize(src->GetSize())) {
114 return false;
115 }
116 93
117 using namespace Common::Literals; 94void EmulationSession::SetNativeWindow(ANativeWindow* native_window) {
118 [[maybe_unused]] std::vector<u8> buffer(1_MiB); 95 m_native_window = native_window;
96}
119 97
120 for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { 98int EmulationSession::InstallFileToNand(std::string filename, std::string file_extension) {
121 jconst read = src->Read(buffer.data(), buffer.size(), i); 99 jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest,
122 dest->Write(buffer.data(), read, i); 100 std::size_t block_size) {
123 } 101 if (src == nullptr || dest == nullptr) {
124 return true; 102 return false;
125 };
126
127 enum InstallResult {
128 Success = 0,
129 SuccessFileOverwritten = 1,
130 InstallError = 2,
131 ErrorBaseGame = 3,
132 ErrorFilenameExtension = 4,
133 };
134
135 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
136 m_system.GetFileSystemController().CreateFactories(*m_vfs);
137
138 [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp;
139 if (file_extension == "nsp") {
140 nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
141 if (nsp->IsExtractedType()) {
142 return InstallError;
143 }
144 } else {
145 return ErrorFilenameExtension;
146 } 103 }
147 104 if (!dest->Resize(src->GetSize())) {
148 if (!nsp) { 105 return false;
149 return InstallError;
150 } 106 }
151 107
152 if (nsp->GetStatus() != Loader::ResultStatus::Success) { 108 using namespace Common::Literals;
153 return InstallError; 109 [[maybe_unused]] std::vector<u8> buffer(1_MiB);
154 }
155 110
156 jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry( 111 for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) {
157 *nsp, true, copy_func); 112 jconst read = src->Read(buffer.data(), buffer.size(), i);
158 113 dest->Write(buffer.data(), read, i);
159 switch (res) {
160 case FileSys::InstallResult::Success:
161 return Success;
162 case FileSys::InstallResult::OverwriteExisting:
163 return SuccessFileOverwritten;
164 case FileSys::InstallResult::ErrorBaseInstall:
165 return ErrorBaseGame;
166 default:
167 return InstallError;
168 } 114 }
169 } 115 return true;
116 };
170 117
171 void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir, 118 enum InstallResult {
172 const std::string& custom_driver_name, 119 Success = 0,
173 const std::string& file_redirect_dir) { 120 SuccessFileOverwritten = 1,
174#ifdef ARCHITECTURE_arm64 121 InstallError = 2,
175 void* handle{}; 122 ErrorBaseGame = 3,
176 const char* file_redirect_dir_{}; 123 ErrorFilenameExtension = 4,
177 int featureFlags{}; 124 };
178
179 // Enable driver file redirection when renderer debugging is enabled.
180 if (Settings::values.renderer_debug && file_redirect_dir.size()) {
181 featureFlags |= ADRENOTOOLS_DRIVER_FILE_REDIRECT;
182 file_redirect_dir_ = file_redirect_dir.c_str();
183 }
184 125
185 // Try to load a custom driver. 126 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
186 if (custom_driver_name.size()) { 127 m_system.GetFileSystemController().CreateFactories(*m_vfs);
187 handle = adrenotools_open_libvulkan(
188 RTLD_NOW, featureFlags | ADRENOTOOLS_DRIVER_CUSTOM, nullptr, hook_lib_dir.c_str(),
189 custom_driver_dir.c_str(), custom_driver_name.c_str(), file_redirect_dir_, nullptr);
190 }
191 128
192 // Try to load the system driver. 129 [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp;
193 if (!handle) { 130 if (file_extension == "nsp") {
194 handle = 131 nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
195 adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(), 132 if (nsp->IsExtractedType()) {
196 nullptr, nullptr, file_redirect_dir_, nullptr); 133 return InstallError;
197 } 134 }
198 135 } else {
199 m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle); 136 return ErrorFilenameExtension;
200#endif
201 } 137 }
202 138
203 bool IsRunning() const { 139 if (!nsp) {
204 return m_is_running; 140 return InstallError;
205 } 141 }
206 142
207 bool IsPaused() const { 143 if (nsp->GetStatus() != Loader::ResultStatus::Success) {
208 return m_is_running && m_is_paused; 144 return InstallError;
209 } 145 }
210 146
211 const Core::PerfStatsResults& PerfStats() const { 147 jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry(*nsp, true,
212 std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex); 148 copy_func);
213 return m_perf_stats;
214 }
215 149
216 void SurfaceChanged() { 150 switch (res) {
217 if (!IsRunning()) { 151 case FileSys::InstallResult::Success:
218 return; 152 return Success;
219 } 153 case FileSys::InstallResult::OverwriteExisting:
220 m_window->OnSurfaceChanged(m_native_window); 154 return SuccessFileOverwritten;
155 case FileSys::InstallResult::ErrorBaseInstall:
156 return ErrorBaseGame;
157 default:
158 return InstallError;
221 } 159 }
160}
222 161
223 void ConfigureFilesystemProvider(const std::string& filepath) { 162void EmulationSession::InitializeGpuDriver(const std::string& hook_lib_dir,
224 const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read); 163 const std::string& custom_driver_dir,
225 if (!file) { 164 const std::string& custom_driver_name,
226 return; 165 const std::string& file_redirect_dir) {
227 } 166#ifdef ARCHITECTURE_arm64
228 167 void* handle{};
229 auto loader = Loader::GetLoader(m_system, file); 168 const char* file_redirect_dir_{};
230 if (!loader) { 169 int featureFlags{};
231 return;
232 }
233
234 const auto file_type = loader->GetFileType();
235 if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
236 return;
237 }
238 170
239 u64 program_id = 0; 171 // Enable driver file redirection when renderer debugging is enabled.
240 const auto res2 = loader->ReadProgramId(program_id); 172 if (Settings::values.renderer_debug && file_redirect_dir.size()) {
241 if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) { 173 featureFlags |= ADRENOTOOLS_DRIVER_FILE_REDIRECT;
242 m_manual_provider->AddEntry(FileSys::TitleType::Application, 174 file_redirect_dir_ = file_redirect_dir.c_str();
243 FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
244 program_id, file);
245 } else if (res2 == Loader::ResultStatus::Success &&
246 (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
247 const auto nsp = file_type == Loader::FileType::NSP
248 ? std::make_shared<FileSys::NSP>(file)
249 : FileSys::XCI{file}.GetSecurePartitionNSP();
250 for (const auto& title : nsp->GetNCAs()) {
251 for (const auto& entry : title.second) {
252 m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
253 entry.second->GetBaseFile());
254 }
255 }
256 }
257 } 175 }
258 176
259 Core::SystemResultStatus InitializeEmulation(const std::string& filepath) { 177 // Try to load a custom driver.
260 std::scoped_lock lock(m_mutex); 178 if (custom_driver_name.size()) {
261 179 handle = adrenotools_open_libvulkan(
262 // Create the render window. 180 RTLD_NOW, featureFlags | ADRENOTOOLS_DRIVER_CUSTOM, nullptr, hook_lib_dir.c_str(),
263 m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, 181 custom_driver_dir.c_str(), custom_driver_name.c_str(), file_redirect_dir_, nullptr);
264 m_vulkan_library); 182 }
265
266 m_system.SetFilesystem(m_vfs);
267 m_system.GetUserChannel().clear();
268
269 // Initialize system.
270 jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
271 m_software_keyboard = android_keyboard.get();
272 m_system.SetShuttingDown(false);
273 m_system.ApplySettings();
274 Settings::LogSettings();
275 m_system.HIDCore().ReloadInputDevices();
276 m_system.SetAppletFrontendSet({
277 nullptr, // Amiibo Settings
278 nullptr, // Controller Selector
279 nullptr, // Error Display
280 nullptr, // Mii Editor
281 nullptr, // Parental Controls
282 nullptr, // Photo Viewer
283 nullptr, // Profile Selector
284 std::move(android_keyboard), // Software Keyboard
285 nullptr, // Web Browser
286 });
287
288 // Initialize filesystem.
289 m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
290 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
291 m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
292 m_manual_provider.get());
293 m_system.GetFileSystemController().CreateFactories(*m_vfs);
294 ConfigureFilesystemProvider(filepath);
295
296 // Initialize account manager
297 m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
298
299 // Load the ROM.
300 m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
301 if (m_load_result != Core::SystemResultStatus::Success) {
302 return m_load_result;
303 }
304
305 // Complete initialization.
306 m_system.GPU().Start();
307 m_system.GetCpuManager().OnGpuReady();
308 m_system.RegisterExitCallback([&] { HaltEmulation(); });
309 183
310 return Core::SystemResultStatus::Success; 184 // Try to load the system driver.
185 if (!handle) {
186 handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
187 nullptr, nullptr, file_redirect_dir_, nullptr);
311 } 188 }
312 189
313 void ShutdownEmulation() { 190 m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle);
314 std::scoped_lock lock(m_mutex); 191#endif
192}
315 193
316 m_is_running = false; 194bool EmulationSession::IsRunning() const {
195 return m_is_running;
196}
317 197
318 // Unload user input. 198bool EmulationSession::IsPaused() const {
319 m_system.HIDCore().UnloadInputDevices(); 199 return m_is_running && m_is_paused;
200}
320 201
321 // Shutdown the main emulated process 202const Core::PerfStatsResults& EmulationSession::PerfStats() const {
322 if (m_load_result == Core::SystemResultStatus::Success) { 203 std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
323 m_system.DetachDebugger(); 204 return m_perf_stats;
324 m_system.ShutdownMainProcess(); 205}
325 m_detached_tasks.WaitForAllTasks();
326 m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
327 m_window.reset();
328 OnEmulationStopped(Core::SystemResultStatus::Success);
329 return;
330 }
331 206
332 // Tear down the render window. 207void EmulationSession::SurfaceChanged() {
333 m_window.reset(); 208 if (!IsRunning()) {
209 return;
334 } 210 }
211 m_window->OnSurfaceChanged(m_native_window);
212}
335 213
336 void PauseEmulation() { 214void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
337 std::scoped_lock lock(m_mutex); 215 const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
338 m_system.Pause(); 216 if (!file) {
339 m_is_paused = true; 217 return;
340 } 218 }
341 219
342 void UnPauseEmulation() { 220 auto loader = Loader::GetLoader(m_system, file);
343 std::scoped_lock lock(m_mutex); 221 if (!loader) {
344 m_system.Run(); 222 return;
345 m_is_paused = false;
346 } 223 }
347 224
348 void HaltEmulation() { 225 const auto file_type = loader->GetFileType();
349 std::scoped_lock lock(m_mutex); 226 if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
350 m_is_running = false; 227 return;
351 m_cv.notify_one();
352 } 228 }
353 229
354 void RunEmulation() { 230 u64 program_id = 0;
355 { 231 const auto res2 = loader->ReadProgramId(program_id);
356 std::scoped_lock lock(m_mutex); 232 if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
357 m_is_running = true; 233 m_manual_provider->AddEntry(FileSys::TitleType::Application,
358 } 234 FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
359 235 program_id, file);
360 // Load the disk shader cache. 236 } else if (res2 == Loader::ResultStatus::Success &&
361 if (Settings::values.use_disk_shader_cache.GetValue()) { 237 (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
362 LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); 238 const auto nsp = file_type == Loader::FileType::NSP
363 m_system.Renderer().ReadRasterizer()->LoadDiskResources( 239 ? std::make_shared<FileSys::NSP>(file)
364 m_system.GetApplicationProcessProgramID(), std::stop_token{}, 240 : FileSys::XCI{file}.GetSecurePartitionNSP();
365 LoadDiskCacheProgress); 241 for (const auto& title : nsp->GetNCAs()) {
366 LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); 242 for (const auto& entry : title.second) {
243 m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
244 entry.second->GetBaseFile());
245 }
367 } 246 }
247 }
248}
368 249
369 void(m_system.Run()); 250void EmulationSession::InitializeSystem(bool reload) {
251 if (!reload) {
252 // Initialize logging system
253 Common::Log::Initialize();
254 Common::Log::SetColorConsoleBackendEnabled(true);
255 Common::Log::Start();
256 }
257
258 // Initialize filesystem.
259 m_system.SetFilesystem(m_vfs);
260 m_system.GetUserChannel().clear();
261 m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
262 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
263 m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
264 m_manual_provider.get());
265 m_system.GetFileSystemController().CreateFactories(*m_vfs);
266}
267
268Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
269 std::scoped_lock lock(m_mutex);
270
271 // Create the render window.
272 m_window =
273 std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, m_vulkan_library);
274
275 // Initialize system.
276 jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
277 m_software_keyboard = android_keyboard.get();
278 m_system.SetShuttingDown(false);
279 m_system.ApplySettings();
280 Settings::LogSettings();
281 m_system.HIDCore().ReloadInputDevices();
282 m_system.SetAppletFrontendSet({
283 nullptr, // Amiibo Settings
284 nullptr, // Controller Selector
285 nullptr, // Error Display
286 nullptr, // Mii Editor
287 nullptr, // Parental Controls
288 nullptr, // Photo Viewer
289 nullptr, // Profile Selector
290 std::move(android_keyboard), // Software Keyboard
291 nullptr, // Web Browser
292 });
293
294 // Initialize filesystem.
295 ConfigureFilesystemProvider(filepath);
296
297 // Initialize account manager
298 m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
299
300 // Load the ROM.
301 m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
302 if (m_load_result != Core::SystemResultStatus::Success) {
303 return m_load_result;
304 }
305
306 // Complete initialization.
307 m_system.GPU().Start();
308 m_system.GetCpuManager().OnGpuReady();
309 m_system.RegisterExitCallback([&] { HaltEmulation(); });
370 310
371 if (m_system.DebuggerEnabled()) { 311 return Core::SystemResultStatus::Success;
372 m_system.InitializeDebugger(); 312}
373 }
374
375 OnEmulationStarted();
376 313
377 while (true) { 314void EmulationSession::ShutdownEmulation() {
378 { 315 std::scoped_lock lock(m_mutex);
379 [[maybe_unused]] std::unique_lock lock(m_mutex);
380 if (m_cv.wait_for(lock, std::chrono::milliseconds(800),
381 [&]() { return !m_is_running; })) {
382 // Emulation halted.
383 break;
384 }
385 }
386 {
387 // Refresh performance stats.
388 std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
389 m_perf_stats = m_system.GetAndResetPerfStats();
390 }
391 }
392 }
393 316
394 std::string GetRomTitle(const std::string& path) { 317 m_is_running = false;
395 return GetRomMetadata(path).title;
396 }
397 318
398 std::vector<u8> GetRomIcon(const std::string& path) { 319 // Unload user input.
399 return GetRomMetadata(path).icon; 320 m_system.HIDCore().UnloadInputDevices();
400 }
401 321
402 bool GetIsHomebrew(const std::string& path) { 322 // Shutdown the main emulated process
403 return GetRomMetadata(path).isHomebrew; 323 if (m_load_result == Core::SystemResultStatus::Success) {
324 m_system.DetachDebugger();
325 m_system.ShutdownMainProcess();
326 m_detached_tasks.WaitForAllTasks();
327 m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
328 m_window.reset();
329 OnEmulationStopped(Core::SystemResultStatus::Success);
330 return;
404 } 331 }
405 332
406 void ResetRomMetadata() { 333 // Tear down the render window.
407 m_rom_metadata_cache.clear(); 334 m_window.reset();
408 } 335}
409 336
410 bool IsHandheldOnly() { 337void EmulationSession::PauseEmulation() {
411 jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag(); 338 std::scoped_lock lock(m_mutex);
339 m_system.Pause();
340 m_is_paused = true;
341}
412 342
413 if (npad_style_set.fullkey == 1) { 343void EmulationSession::UnPauseEmulation() {
414 return false; 344 std::scoped_lock lock(m_mutex);
415 } 345 m_system.Run();
346 m_is_paused = false;
347}
416 348
417 if (npad_style_set.handheld == 0) { 349void EmulationSession::HaltEmulation() {
418 return false; 350 std::scoped_lock lock(m_mutex);
419 } 351 m_is_running = false;
352 m_cv.notify_one();
353}
420 354
421 return !Settings::IsDockedMode(); 355void EmulationSession::RunEmulation() {
356 {
357 std::scoped_lock lock(m_mutex);
358 m_is_running = true;
422 } 359 }
423 360
424 void SetDeviceType([[maybe_unused]] int index, int type) { 361 // Load the disk shader cache.
425 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); 362 if (Settings::values.use_disk_shader_cache.GetValue()) {
426 controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type)); 363 LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
364 m_system.Renderer().ReadRasterizer()->LoadDiskResources(
365 m_system.GetApplicationProcessProgramID(), std::stop_token{}, LoadDiskCacheProgress);
366 LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
427 } 367 }
428 368
429 void OnGamepadConnectEvent([[maybe_unused]] int index) { 369 void(m_system.Run());
430 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
431
432 // Ensure that player1 is configured correctly and handheld disconnected
433 if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
434 jauto handheld =
435 m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
436 370
437 if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) { 371 if (m_system.DebuggerEnabled()) {
438 handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); 372 m_system.InitializeDebugger();
439 controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController); 373 }
440 handheld->Disconnect();
441 }
442 }
443 374
444 // Ensure that handheld is configured correctly and player 1 disconnected 375 OnEmulationStarted();
445 if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
446 jauto player1 =
447 m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
448 376
449 if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) { 377 while (true) {
450 player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); 378 {
451 controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); 379 [[maybe_unused]] std::unique_lock lock(m_mutex);
452 player1->Disconnect(); 380 if (m_cv.wait_for(lock, std::chrono::milliseconds(800),
381 [&]() { return !m_is_running; })) {
382 // Emulation halted.
383 break;
453 } 384 }
454 } 385 }
455 386 {
456 if (!controller->IsConnected()) { 387 // Refresh performance stats.
457 controller->Connect(); 388 std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
389 m_perf_stats = m_system.GetAndResetPerfStats();
458 } 390 }
459 } 391 }
392}
393
394bool EmulationSession::IsHandheldOnly() {
395 jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
460 396
461 void OnGamepadDisconnectEvent([[maybe_unused]] int index) { 397 if (npad_style_set.fullkey == 1) {
462 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index); 398 return false;
463 controller->Disconnect();
464 } 399 }
465 400
466 SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard() { 401 if (npad_style_set.handheld == 0) {
467 return m_software_keyboard; 402 return false;
468 } 403 }
469 404
470private: 405 return !Settings::IsDockedMode();
471 struct RomMetadata { 406}
472 std::string title;
473 std::vector<u8> icon;
474 bool isHomebrew;
475 };
476 407
477 RomMetadata GetRomMetadata(const std::string& path) { 408void EmulationSession::SetDeviceType([[maybe_unused]] int index, int type) {
478 if (jauto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) { 409 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
479 return search->second; 410 controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
480 } 411}
481 412
482 return CacheRomMetadata(path); 413void EmulationSession::OnGamepadConnectEvent([[maybe_unused]] int index) {
483 } 414 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
484 415
485 RomMetadata CacheRomMetadata(const std::string& path) { 416 // Ensure that player1 is configured correctly and handheld disconnected
486 jconst file = Core::GetGameFileFromPath(m_vfs, path); 417 if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
487 jauto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0); 418 jauto handheld = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
488 419
489 RomMetadata entry; 420 if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
490 loader->ReadTitle(entry.title); 421 handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
491 loader->ReadIcon(entry.icon); 422 controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
492 if (loader->GetFileType() == Loader::FileType::NRO) { 423 handheld->Disconnect();
493 jauto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
494 entry.isHomebrew = loader_nro->IsHomebrew();
495 } else {
496 entry.isHomebrew = false;
497 } 424 }
498
499 m_rom_metadata_cache[path] = entry;
500
501 return entry;
502 } 425 }
503 426
504private: 427 // Ensure that handheld is configured correctly and player 1 disconnected
505 static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max) { 428 if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
506 JNIEnv* env = IDCache::GetEnvForThread(); 429 jauto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
507 env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
508 IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
509 static_cast<jint>(progress), static_cast<jint>(max));
510 }
511 430
512 static void OnEmulationStarted() { 431 if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
513 JNIEnv* env = IDCache::GetEnvForThread(); 432 player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
514 env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), 433 controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
515 IDCache::GetOnEmulationStarted()); 434 player1->Disconnect();
435 }
516 } 436 }
517 437
518 static void OnEmulationStopped(Core::SystemResultStatus result) { 438 if (!controller->IsConnected()) {
519 JNIEnv* env = IDCache::GetEnvForThread(); 439 controller->Connect();
520 env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
521 IDCache::GetOnEmulationStopped(), static_cast<jint>(result));
522 } 440 }
441}
523 442
524private: 443void EmulationSession::OnGamepadDisconnectEvent([[maybe_unused]] int index) {
525 static EmulationSession s_instance; 444 jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
526 445 controller->Disconnect();
527 // Frontend management 446}
528 std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
529
530 // Window management
531 std::unique_ptr<EmuWindow_Android> m_window;
532 ANativeWindow* m_native_window{};
533
534 // Core emulation
535 Core::System m_system;
536 InputCommon::InputSubsystem m_input_subsystem;
537 Common::DetachedTasks m_detached_tasks;
538 Core::PerfStatsResults m_perf_stats{};
539 std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
540 Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
541 std::atomic<bool> m_is_running = false;
542 std::atomic<bool> m_is_paused = false;
543 SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
544 std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
545 std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
546 447
547 // GPU driver parameters 448SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
548 std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; 449 return m_software_keyboard;
450}
549 451
550 // Synchronization 452void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
551 std::condition_variable_any m_cv; 453 int max) {
552 mutable std::mutex m_perf_stats_mutex; 454 JNIEnv* env = IDCache::GetEnvForThread();
553 mutable std::mutex m_mutex; 455 env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
554}; 456 IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
457 static_cast<jint>(progress), static_cast<jint>(max));
458}
555 459
556/*static*/ EmulationSession EmulationSession::s_instance; 460void EmulationSession::OnEmulationStarted() {
461 JNIEnv* env = IDCache::GetEnvForThread();
462 env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStarted());
463}
557 464
558} // Anonymous namespace 465void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
466 JNIEnv* env = IDCache::GetEnvForThread();
467 env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStopped(),
468 static_cast<jint>(result));
469}
559 470
560static Core::SystemResultStatus RunEmulation(const std::string& filepath) { 471static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
561 Common::Log::Initialize();
562 Common::Log::SetColorConsoleBackendEnabled(true);
563 Common::Log::Start();
564
565 MicroProfileOnThreadCreate("EmuThread"); 472 MicroProfileOnThreadCreate("EmuThread");
566 SCOPE_EXIT({ MicroProfileShutdown(); }); 473 SCOPE_EXIT({ MicroProfileShutdown(); });
567 474
@@ -657,10 +564,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_stopEmulation(JNIEnv* env, jclass cla
657 EmulationSession::GetInstance().HaltEmulation(); 564 EmulationSession::GetInstance().HaltEmulation();
658} 565}
659 566
660void Java_org_yuzu_yuzu_1emu_NativeLibrary_resetRomMetadata(JNIEnv* env, jclass clazz) {
661 EmulationSession::GetInstance().ResetRomMetadata();
662}
663
664jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isRunning(JNIEnv* env, jclass clazz) { 567jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isRunning(JNIEnv* env, jclass clazz) {
665 return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning()); 568 return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning());
666} 569}
@@ -766,51 +669,15 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c
766 } 669 }
767} 670}
768 671
769jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getIcon(JNIEnv* env, jclass clazz, 672void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz,
770 jstring j_filename) { 673 jboolean reload) {
771 jauto icon_data = EmulationSession::GetInstance().GetRomIcon(GetJString(env, j_filename));
772 jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
773 env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
774 reinterpret_cast<jbyte*>(icon_data.data()));
775 return icon;
776}
777
778jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getTitle(JNIEnv* env, jclass clazz,
779 jstring j_filename) {
780 jauto title = EmulationSession::GetInstance().GetRomTitle(GetJString(env, j_filename));
781 return env->NewStringUTF(title.c_str());
782}
783
784jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDescription(JNIEnv* env, jclass clazz,
785 jstring j_filename) {
786 return j_filename;
787}
788
789jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGameId(JNIEnv* env, jclass clazz,
790 jstring j_filename) {
791 return j_filename;
792}
793
794jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRegions(JNIEnv* env, jclass clazz,
795 jstring j_filename) {
796 return env->NewStringUTF("");
797}
798
799jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCompany(JNIEnv* env, jclass clazz,
800 jstring j_filename) {
801 return env->NewStringUTF("");
802}
803
804jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew(JNIEnv* env, jclass clazz,
805 jstring j_filename) {
806 return EmulationSession::GetInstance().GetIsHomebrew(GetJString(env, j_filename));
807}
808
809void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation(JNIEnv* env, jclass clazz) {
810 // Create the default config.ini. 674 // Create the default config.ini.
811 Config{}; 675 Config{};
812 // Initialize the emulated system. 676 // Initialize the emulated system.
813 EmulationSession::GetInstance().System().Initialize(); 677 if (!reload) {
678 EmulationSession::GetInstance().System().Initialize();
679 }
680 EmulationSession::GetInstance().InitializeSystem(reload);
814} 681}
815 682
816jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) { 683jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) {
@@ -898,4 +765,49 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
898 } 765 }
899} 766}
900 767
768jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, jclass clazz,
769 jlong jid) {
770 auto bis_system =
771 EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
772 if (!bis_system) {
773 return ToJString(env, "");
774 }
775
776 auto applet_nca =
777 bis_system->GetEntry(static_cast<u64>(jid), FileSys::ContentRecordType::Program);
778 if (!applet_nca) {
779 return ToJString(env, "");
780 }
781
782 return ToJString(env, applet_nca->GetFullPath());
783}
784
785void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
786 jint jappletId) {
787 EmulationSession::GetInstance().System().GetAppletManager().SetCurrentAppletId(
788 static_cast<Service::AM::Applets::AppletId>(jappletId));
789}
790
791void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz,
792 jint jcabinetMode) {
793 EmulationSession::GetInstance().System().GetAppletManager().SetCabinetMode(
794 static_cast<Service::NFP::CabinetMode>(jcabinetMode));
795}
796
797jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
798 auto bis_system =
799 EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
800 if (!bis_system) {
801 return false;
802 }
803
804 // Query an applet to see if it's available
805 auto applet_nca =
806 bis_system->GetEntry(0x010000000000100Dull, FileSys::ContentRecordType::Program);
807 if (!applet_nca) {
808 return false;
809 }
810 return true;
811}
812
901} // extern "C" 813} // extern "C"
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h
new file mode 100644
index 000000000..3b9596459
--- /dev/null
+++ b/src/android/app/src/main/jni/native.h
@@ -0,0 +1,85 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <android/native_window_jni.h>
5#include "common/detached_tasks.h"
6#include "core/core.h"
7#include "core/file_sys/registered_cache.h"
8#include "core/hle/service/acc/profile_manager.h"
9#include "core/perf_stats.h"
10#include "jni/applets/software_keyboard.h"
11#include "jni/emu_window/emu_window.h"
12#include "video_core/rasterizer_interface.h"
13
14#pragma once
15
16class EmulationSession final {
17public:
18 explicit EmulationSession();
19 ~EmulationSession() = default;
20
21 static EmulationSession& GetInstance();
22 const Core::System& System() const;
23 Core::System& System();
24
25 const EmuWindow_Android& Window() const;
26 EmuWindow_Android& Window();
27 ANativeWindow* NativeWindow() const;
28 void SetNativeWindow(ANativeWindow* native_window);
29 void SurfaceChanged();
30
31 int InstallFileToNand(std::string filename, std::string file_extension);
32 void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
33 const std::string& custom_driver_name,
34 const std::string& file_redirect_dir);
35
36 bool IsRunning() const;
37 bool IsPaused() const;
38 void PauseEmulation();
39 void UnPauseEmulation();
40 void HaltEmulation();
41 void RunEmulation();
42 void ShutdownEmulation();
43
44 const Core::PerfStatsResults& PerfStats() const;
45 void ConfigureFilesystemProvider(const std::string& filepath);
46 void InitializeSystem(bool reload);
47 Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
48
49 bool IsHandheldOnly();
50 void SetDeviceType([[maybe_unused]] int index, int type);
51 void OnGamepadConnectEvent([[maybe_unused]] int index);
52 void OnGamepadDisconnectEvent([[maybe_unused]] int index);
53 SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
54
55private:
56 static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
57 static void OnEmulationStarted();
58 static void OnEmulationStopped(Core::SystemResultStatus result);
59
60private:
61 // Window management
62 std::unique_ptr<EmuWindow_Android> m_window;
63 ANativeWindow* m_native_window{};
64
65 // Core emulation
66 Core::System m_system;
67 InputCommon::InputSubsystem m_input_subsystem;
68 Common::DetachedTasks m_detached_tasks;
69 Core::PerfStatsResults m_perf_stats{};
70 std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
71 Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
72 std::atomic<bool> m_is_running = false;
73 std::atomic<bool> m_is_paused = false;
74 SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
75 std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
76 std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
77
78 // GPU driver parameters
79 std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
80
81 // Synchronization
82 std::condition_variable_any m_cv;
83 mutable std::mutex m_perf_stats_mutex;
84 mutable std::mutex m_mutex;
85};
diff --git a/src/android/app/src/main/jni/native_log.cpp b/src/android/app/src/main/jni/native_log.cpp
new file mode 100644
index 000000000..33d691dc8
--- /dev/null
+++ b/src/android/app/src/main/jni/native_log.cpp
@@ -0,0 +1,31 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <common/logging/log.h>
5#include <jni.h>
6
7#include "android_common/android_common.h"
8
9extern "C" {
10
11void Java_org_yuzu_yuzu_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
12 LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage));
13}
14
15void Java_org_yuzu_yuzu_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
16 LOG_WARNING(Frontend, "{}", GetJString(env, jmessage));
17}
18
19void Java_org_yuzu_yuzu_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
20 LOG_INFO(Frontend, "{}", GetJString(env, jmessage));
21}
22
23void Java_org_yuzu_yuzu_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
24 LOG_ERROR(Frontend, "{}", GetJString(env, jmessage));
25}
26
27void Java_org_yuzu_yuzu_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
28 LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
29}
30
31} // extern "C"
diff --git a/src/android/app/src/main/res/drawable/ic_album.xml b/src/android/app/src/main/res/drawable/ic_album.xml
new file mode 100644
index 000000000..f2b63813f
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_album.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_applet.xml b/src/android/app/src/main/res/drawable/ic_applet.xml
new file mode 100644
index 000000000..b154e6f56
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_applet.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M17,16l-4,-4V8.82C14.16,8.4 15,7.3 15,6c0,-1.66 -1.34,-3 -3,-3S9,4.34 9,6c0,1.3 0.84,2.4 2,2.82V12l-4,4H3v5h5v-3.05l4,-4.2 4,4.2V21h5v-5h-4z" />
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_edit.xml b/src/android/app/src/main/res/drawable/ic_edit.xml
new file mode 100644
index 000000000..ac22ce8a5
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_edit.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_mii.xml b/src/android/app/src/main/res/drawable/ic_mii.xml
new file mode 100644
index 000000000..1271ec401
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_mii.xml
@@ -0,0 +1,18 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M9,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0" />
9 <path
10 android:fillColor="?attr/colorControlNormal"
11 android:pathData="M20.77,8.58l-0.92,2.01c0.09,0.46 0.15,0.93 0.15,1.41 0,4.41 -3.59,8 -8,8s-8,-3.59 -8,-8c0,-0.05 0.01,-0.1 0,-0.14 2.6,-0.98 4.69,-2.99 5.74,-5.55C11.58,8.56 14.37,10 17.5,10c0.45,0 0.89,-0.04 1.33,-0.1l-0.6,-1.32 -0.88,-1.93 -1.93,-0.88 -2.79,-1.27 2.79,-1.27 0.71,-0.32C14.87,2.33 13.47,2 12,2 6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10c0,-1.47 -0.33,-2.87 -0.9,-4.13l-0.33,0.71z" />
12 <path
13 android:fillColor="?attr/colorControlNormal"
14 android:pathData="M15,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0" />
15 <path
16 android:fillColor="?attr/colorControlNormal"
17 android:pathData="M20.6,5.6L19.5,8l-1.1,-2.4L16,4.5l2.4,-1.1L19.5,1l1.1,2.4L23,4.5z" />
18</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_refresh.xml b/src/android/app/src/main/res/drawable/ic_refresh.xml
new file mode 100644
index 000000000..d0d87ecc2
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_refresh.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_restore.xml b/src/android/app/src/main/res/drawable/ic_restore.xml
new file mode 100644
index 000000000..d6d9d4017
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_restore.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="24"
5 android:viewportHeight="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" />
9</vector>
diff --git a/src/android/app/src/main/res/layout/card_applet_option.xml b/src/android/app/src/main/res/layout/card_applet_option.xml
new file mode 100644
index 000000000..19fbec9f1
--- /dev/null
+++ b/src/android/app/src/main/res/layout/card_applet_option.xml
@@ -0,0 +1,57 @@
1<?xml version="1.0" encoding="utf-8"?>
2<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 style="?attr/materialCardViewOutlinedStyle"
6 android:layout_width="match_parent"
7 android:layout_height="wrap_content"
8 android:layout_marginHorizontal="16dp"
9 android:layout_marginVertical="12dp"
10 android:background="?attr/selectableItemBackground"
11 android:clickable="true"
12 android:focusable="true">
13
14 <LinearLayout
15 android:layout_width="match_parent"
16 android:layout_height="wrap_content"
17 android:orientation="horizontal"
18 android:layout_gravity="center"
19 android:padding="24dp">
20
21 <ImageView
22 android:id="@+id/icon"
23 android:layout_width="24dp"
24 android:layout_height="24dp"
25 android:layout_marginEnd="20dp"
26 android:layout_gravity="center_vertical"
27 app:tint="?attr/colorOnSurface" />
28
29 <LinearLayout
30 android:layout_width="0dp"
31 android:layout_height="wrap_content"
32 android:layout_weight="1"
33 android:orientation="vertical"
34 android:layout_gravity="center_vertical">
35
36 <com.google.android.material.textview.MaterialTextView
37 android:id="@+id/title"
38 style="@style/TextAppearance.Material3.TitleMedium"
39 android:layout_width="match_parent"
40 android:layout_height="wrap_content"
41 android:textAlignment="viewStart"
42 tools:text="@string/applets" />
43
44 <com.google.android.material.textview.MaterialTextView
45 android:id="@+id/description"
46 style="@style/TextAppearance.Material3.BodyMedium"
47 android:layout_width="match_parent"
48 android:layout_height="wrap_content"
49 android:layout_marginTop="6dp"
50 android:textAlignment="viewStart"
51 tools:text="@string/applets_description" />
52
53 </LinearLayout>
54
55 </LinearLayout>
56
57</com.google.android.material.card.MaterialCardView>
diff --git a/src/android/app/src/main/res/layout/card_game.xml b/src/android/app/src/main/res/layout/card_game.xml
index 1f5de219b..6340171ec 100644
--- a/src/android/app/src/main/res/layout/card_game.xml
+++ b/src/android/app/src/main/res/layout/card_game.xml
@@ -1,63 +1,54 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<FrameLayout 2<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:app="http://schemas.android.com/apk/res-auto"
5 xmlns:tools="http://schemas.android.com/tools" 4 xmlns:tools="http://schemas.android.com/tools"
6 android:layout_width="match_parent" 5 android:layout_width="match_parent"
7 android:layout_height="wrap_content"> 6 android:layout_height="wrap_content">
8 7
9 <com.google.android.material.card.MaterialCardView 8 <com.google.android.material.card.MaterialCardView
10 style="?attr/materialCardViewElevatedStyle"
11 android:id="@+id/card_game" 9 android:id="@+id/card_game"
10 style="?attr/materialCardViewElevatedStyle"
12 android:layout_width="wrap_content" 11 android:layout_width="wrap_content"
13 android:layout_height="wrap_content" 12 android:layout_height="wrap_content"
13 android:layout_gravity="center"
14 android:background="?attr/selectableItemBackground" 14 android:background="?attr/selectableItemBackground"
15 android:clickable="true" 15 android:clickable="true"
16 android:clipToPadding="false" 16 android:clipToPadding="false"
17 android:focusable="true" 17 android:focusable="true"
18 android:transitionName="card_game" 18 android:transitionName="card_game"
19 android:layout_gravity="center" 19 app:cardCornerRadius="4dp"
20 app:cardElevation="0dp" 20 app:cardElevation="0dp">
21 app:cardCornerRadius="12dp">
22 21
23 <androidx.constraintlayout.widget.ConstraintLayout 22 <androidx.constraintlayout.widget.ConstraintLayout
24 android:layout_width="wrap_content" 23 android:layout_width="wrap_content"
25 android:layout_height="wrap_content" 24 android:layout_height="wrap_content"
26 android:padding="6dp"> 25 android:padding="6dp">
27 26
28 <com.google.android.material.card.MaterialCardView 27 <com.google.android.material.imageview.ShapeableImageView
29 style="?attr/materialCardViewElevatedStyle" 28 android:id="@+id/image_game_screen"
30 android:id="@+id/card_game_art"
31 android:layout_width="150dp" 29 android:layout_width="150dp"
32 android:layout_height="150dp" 30 android:layout_height="150dp"
33 app:cardCornerRadius="4dp"
34 app:layout_constraintEnd_toEndOf="parent" 31 app:layout_constraintEnd_toEndOf="parent"
35 app:layout_constraintStart_toStartOf="parent" 32 app:layout_constraintStart_toStartOf="parent"
36 app:layout_constraintTop_toTopOf="parent"> 33 app:layout_constraintTop_toTopOf="parent"
37 34 app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.ExtraSmall"
38 <ImageView 35 tools:src="@drawable/default_icon" />
39 android:id="@+id/image_game_screen"
40 android:layout_width="match_parent"
41 android:layout_height="match_parent"
42 tools:src="@drawable/default_icon" />
43
44 </com.google.android.material.card.MaterialCardView>
45 36
46 <com.google.android.material.textview.MaterialTextView 37 <com.google.android.material.textview.MaterialTextView
47 style="@style/TextAppearance.Material3.TitleMedium"
48 android:id="@+id/text_game_title" 38 android:id="@+id/text_game_title"
39 style="@style/TextAppearance.Material3.TitleMedium"
49 android:layout_width="0dp" 40 android:layout_width="0dp"
50 android:layout_height="wrap_content" 41 android:layout_height="wrap_content"
51 android:layout_marginTop="8dp" 42 android:layout_marginTop="8dp"
52 android:textAlignment="center"
53 android:textSize="14sp"
54 android:singleLine="true"
55 android:marqueeRepeatLimit="marquee_forever"
56 android:ellipsize="none" 43 android:ellipsize="none"
44 android:marqueeRepeatLimit="marquee_forever"
57 android:requiresFadingEdge="horizontal" 45 android:requiresFadingEdge="horizontal"
58 app:layout_constraintEnd_toEndOf="@+id/card_game_art" 46 android:singleLine="true"
59 app:layout_constraintStart_toStartOf="@+id/card_game_art" 47 android:textAlignment="center"
60 app:layout_constraintTop_toBottomOf="@+id/card_game_art" 48 android:textSize="14sp"
49 app:layout_constraintEnd_toEndOf="@+id/image_game_screen"
50 app:layout_constraintStart_toStartOf="@+id/image_game_screen"
51 app:layout_constraintTop_toBottomOf="@+id/image_game_screen"
61 tools:text="The Legend of Zelda: Skyward Sword" /> 52 tools:text="The Legend of Zelda: Skyward Sword" />
62 53
63 </androidx.constraintlayout.widget.ConstraintLayout> 54 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/src/android/app/src/main/res/layout/card_home_option.xml b/src/android/app/src/main/res/layout/card_home_option.xml
index f9f1d89fb..6e8a232f9 100644
--- a/src/android/app/src/main/res/layout/card_home_option.xml
+++ b/src/android/app/src/main/res/layout/card_home_option.xml
@@ -16,7 +16,8 @@
16 <LinearLayout 16 <LinearLayout
17 android:id="@+id/option_layout" 17 android:id="@+id/option_layout"
18 android:layout_width="match_parent" 18 android:layout_width="match_parent"
19 android:layout_height="wrap_content"> 19 android:layout_height="wrap_content"
20 android:layout_gravity="center_vertical">
20 21
21 <ImageView 22 <ImageView
22 android:id="@+id/option_icon" 23 android:id="@+id/option_icon"
diff --git a/src/android/app/src/main/res/layout/dialog_list.xml b/src/android/app/src/main/res/layout/dialog_list.xml
new file mode 100644
index 000000000..7de2b2c3a
--- /dev/null
+++ b/src/android/app/src/main/res/layout/dialog_list.xml
@@ -0,0 +1,15 @@
1<?xml version="1.0" encoding="utf-8"?>
2<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content">
5
6 <androidx.recyclerview.widget.RecyclerView
7 android:id="@+id/dialog_list"
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content"
10 android:clipToPadding="false"
11 android:fadeScrollbars="false"
12 android:paddingVertical="12dp"
13 android:scrollbars="vertical" />
14
15</androidx.appcompat.widget.LinearLayoutCompat>
diff --git a/src/android/app/src/main/res/layout/dialog_list_item.xml b/src/android/app/src/main/res/layout/dialog_list_item.xml
new file mode 100644
index 000000000..39f3558ff
--- /dev/null
+++ b/src/android/app/src/main/res/layout/dialog_list_item.xml
@@ -0,0 +1,30 @@
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="wrap_content"
6 android:background="?attr/selectableItemBackground"
7 android:clickable="true"
8 android:focusable="true"
9 android:orientation="horizontal"
10 android:paddingHorizontal="24dp"
11 android:paddingVertical="16dp">
12
13 <ImageView
14 android:id="@+id/icon"
15 android:layout_width="20dp"
16 android:layout_height="20dp"
17 android:layout_gravity="center"
18 tools:src="@drawable/ic_nfc" />
19
20 <com.google.android.material.textview.MaterialTextView
21 android:id="@+id/title"
22 style="@style/TextAppearance.Material3.BodyMedium"
23 android:layout_width="match_parent"
24 android:layout_height="wrap_content"
25 android:layout_marginStart="16dp"
26 android:layout_gravity="center_vertical|start"
27 android:textAlignment="viewStart"
28 tools:text="List option" />
29
30</LinearLayout>
diff --git a/src/android/app/src/main/res/layout/fragment_applet_launcher.xml b/src/android/app/src/main/res/layout/fragment_applet_launcher.xml
new file mode 100644
index 000000000..fe8fae40f
--- /dev/null
+++ b/src/android/app/src/main/res/layout/fragment_applet_launcher.xml
@@ -0,0 +1,31 @@
1<?xml version="1.0" encoding="utf-8"?>
2<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 android:id="@+id/coordinator_applets"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 android:background="?attr/colorSurface">
8
9 <com.google.android.material.appbar.AppBarLayout
10 android:id="@+id/appbar_applets"
11 android:layout_width="match_parent"
12 android:layout_height="wrap_content"
13 android:fitsSystemWindows="true">
14
15 <com.google.android.material.appbar.MaterialToolbar
16 android:id="@+id/toolbar_applets"
17 android:layout_width="match_parent"
18 android:layout_height="?attr/actionBarSize"
19 app:navigationIcon="@drawable/ic_back"
20 app:title="@string/applets" />
21
22 </com.google.android.material.appbar.AppBarLayout>
23
24 <androidx.recyclerview.widget.RecyclerView
25 android:id="@+id/list_applets"
26 android:layout_width="match_parent"
27 android:layout_height="match_parent"
28 android:clipToPadding="false"
29 app:layout_behavior="@string/appbar_scrolling_view_behavior" />
30
31</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/src/android/app/src/main/res/navigation/home_navigation.xml b/src/android/app/src/main/res/navigation/home_navigation.xml
index 82749359d..6d4c1f86d 100644
--- a/src/android/app/src/main/res/navigation/home_navigation.xml
+++ b/src/android/app/src/main/res/navigation/home_navigation.xml
@@ -25,6 +25,9 @@
25 <action 25 <action
26 android:id="@+id/action_homeSettingsFragment_to_driverManagerFragment" 26 android:id="@+id/action_homeSettingsFragment_to_driverManagerFragment"
27 app:destination="@id/driverManagerFragment" /> 27 app:destination="@id/driverManagerFragment" />
28 <action
29 android:id="@+id/action_homeSettingsFragment_to_appletLauncherFragment"
30 app:destination="@id/appletLauncherFragment" />
28 </fragment> 31 </fragment>
29 32
30 <fragment 33 <fragment
@@ -102,5 +105,17 @@
102 android:id="@+id/driverManagerFragment" 105 android:id="@+id/driverManagerFragment"
103 android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment" 106 android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment"
104 android:label="DriverManagerFragment" /> 107 android:label="DriverManagerFragment" />
108 <fragment
109 android:id="@+id/appletLauncherFragment"
110 android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
111 android:label="AppletLauncherFragment" >
112 <action
113 android:id="@+id/action_appletLauncherFragment_to_cabinetLauncherDialogFragment"
114 app:destination="@id/cabinetLauncherDialogFragment" />
115 </fragment>
116 <dialog
117 android:id="@+id/cabinetLauncherDialogFragment"
118 android:name="org.yuzu.yuzu_emu.fragments.CabinetLauncherDialogFragment"
119 android:label="CabinetLauncherDialogFragment" />
105 120
106</navigation> 121</navigation>
diff --git a/src/android/app/src/main/res/resources.properties b/src/android/app/src/main/res/resources.properties
new file mode 100644
index 000000000..467b3efec
--- /dev/null
+++ b/src/android/app/src/main/res/resources.properties
@@ -0,0 +1 @@
unqualifiedResLocale=en-US
diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml
new file mode 100644
index 000000000..07dffffe8
--- /dev/null
+++ b/src/android/app/src/main/res/values-ar/strings.xml
@@ -0,0 +1,385 @@
1<?xml version="1.0" encoding="utf-8"?>
2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3
4 <string name="emulation_notification_channel_name">المحاكي نشط</string>
5 <string name="emulation_notification_channel_description">اظهار اشعار دائم عندما يكون المحاكي نشطاً</string>
6 <string name="emulation_notification_running">يوزو يعمل</string>
7 <string name="notice_notification_channel_name">الإشعارات والأخطاء</string>
8 <string name="notice_notification_channel_description">اظهار اشعار عند حصول اي مشكلة.</string>
9 <string name="notification_permission_not_granted">لم يتم منح إذن الإشعار</string>
10
11 <!-- Setup strings -->
12 <string name="welcome">مرحبًا</string>
13 <string name="welcome_description">والانتقال إلى المحاكاة <b>يوزو</b> تعر٠على كيÙية إعداد.</string>
14 <string name="get_started">لنبدأ</string>
15 <string name="keys">Ø§Ù„Ù…ÙØ§ØªÙŠØ­</string>
16 <string name="keys_description">اختر مل٠&lt;b>prod.keys&lt;/b> من الزر ادناه</string>
17 <string name="select_keys">إختيار Ø§Ù„Ù…ÙØ§ØªÙŠØ­</string>
18 <string name="games">الألعاب</string>
19 <string name="games_description">اختر مجلد &lt;b>العابك&lt;/b> من الزر ادناه.</string>
20 <string name="done">إنهاء</string>
21 <string name="done_description">كل شيء جاهز./n استمتع بألعابك!</string>
22 <string name="text_continue">استمر</string>
23 <string name="next">التالي</string>
24 <string name="back">عودة</string>
25 <string name="add_games">Ø¥Ø¶Ø§ÙØ© ألعاب</string>
26 <string name="add_games_description">إختار مجلد ألعابك</string>
27 <string name="step_complete">مكتمل</string>
28
29 <!-- Home strings -->
30 <string name="home_games">الألعاب</string>
31 <string name="home_search">البحث</string>
32 <string name="home_settings">الإعدادات</string>
33 <string name="empty_gamelist">لم يتم العثور على Ù…Ù„ÙØ§Øª او لم يتم تحديد مسار العاب.</string>
34 <string name="search_and_filter_games">بحث وتصÙية الألعاب</string>
35 <string name="select_games_folder">تحديد مجلد الألعاب</string>
36 <string name="select_games_folder_description">يسمح لـ يوزو بملء قائمة الألعاب</string>
37 <string name="add_games_warning">تخط٠اختيار مجلد الالعاب؟</string>
38 <string name="add_games_warning_description">لن يتم عرض الألعاب ÙÙŠ قائمة الألعاب إذا لم يتم تحديد مجلد</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">البحث عن ألعاب</string>
41 <string name="search_settings">إعدادات البحث</string>
42 <string name="games_dir_selected">تم تحديد مجلد الألعاب</string>
43 <string name="install_prod_keys">تثبيت prod.keys</string>
44 <string name="install_prod_keys_description">مطلوب Ù„ÙÙƒ تشÙير ألعاب البيع بالتجزئة</string>
45 <string name="install_prod_keys_warning">تخطي Ø¥Ø¶Ø§ÙØ© Ø§Ù„Ù…ÙØ§ØªÙŠØ­ØŸ</string>
46 <string name="install_prod_keys_warning_description">مطلوب Ù…ÙØ§ØªÙŠØ­ صالحة لمحاكاة ألعاب البيع بالتجزئة. ستعمل تطبيقات البيرة المنزلية Ùقط إذا تابعت</string>
47 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
48 <string name="notifications">التنبيهات</string>
49 <string name="notifications_description">امنح إذن الإشعار باستخدام الزر أدناه</string>
50 <string name="give_permission">منح الإذن</string>
51 <string name="notification_warning">تخطي منح إذن الإشعارات؟</string>
52 <string name="notification_warning_description">لن يتمكن يوزو من إشعارك بالمعلومات المهمة</string>
53 <string name="permission_denied">تم Ø±ÙØ¶ الإذن</string>
54 <string name="permission_denied_description">لقد Ø±ÙØ¶Øª هذا الإذن عدة مرات ويتعين عليك الآن منحه يدويًا ÙÙŠ إعدادات النظام</string>
55 <string name="about">حول</string>
56 <string name="about_description">بناء الإصدار، والاعتمادات، وأكثر من ذلك</string>
57 <string name="warning_help">مساعدة</string>
58 <string name="warning_skip">تخطي</string>
59 <string name="warning_cancel">إلغاء</string>
60 <string name="install_amiibo_keys">تثبيت Ù…ÙØ§ØªÙŠØ­ أميبو</string>
61 <string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو ÙÙŠ اللعبة</string>
62 <string name="invalid_keys_file">تم تحديد Ù…Ù„Ù Ù…ÙØ§ØªÙŠØ­ غير صالح</string>
63 <string name="install_keys_success">تم تثبيت Ø§Ù„Ù…ÙØ§ØªÙŠØ­ بنجاح</string>
64 <string name="reading_keys_failure">خطأ ÙÙŠ قراءة Ù…ÙØ§ØªÙŠØ­ التشÙير</string>
65 <string name="invalid_keys_error">Ù…ÙØ§ØªÙŠØ­ التشÙير غير صالحة</string>
66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
67 <string name="install_keys_failure_description">المل٠المحدد غير صحيح أو تالÙ. يرجى إعادة Ø§Ù„Ù…ÙØ§ØªÙŠØ­ الخاصة بك</string>
68 <string name="install_gpu_driver">GPU تثبيت برنامج تشغيل</string>
69 <string name="install_gpu_driver_description">قم بتثبيت برامج تشغيل بديلة للحصول على أداء أو دقة Ø£ÙØ¶Ù„</string>
70 <string name="advanced_settings">إعدادات متقدمة</string>
71 <string name="advanced_settings_game">إعدادات متقدمة: %1$s</string>
72 <string name="settings_description">تكوين إعدادات المحاكي</string>
73 <string name="search_recently_played">لعبت مؤخرا</string>
74 <string name="search_recently_added">أضي٠مؤخرا</string>
75 <string name="search_retail">بيع بالتجزئة</string>
76 <string name="search_homebrew">البيرة المنزلية</string>
77 <string name="open_user_folder">ÙØªØ­ مجلد يوزو</string>
78 <string name="open_user_folder_description">إدارة Ù…Ù„ÙØ§Øª يوزو الداخلية</string>
79 <string name="theme_and_color_description">تعديل مظهر التطبيق</string>
80 <string name="no_file_manager">لم يتم العثور على مدير Ø§Ù„Ù…Ù„ÙØ§Øª</string>
81 <string name="notification_no_directory_link">لا يمكن ÙØªØ­ مجلد يوزو</string>
82 <string name="notification_no_directory_link_description">الرجاء تحديد موقع مجلد المستخدم باستخدام اللوحة الجانبية لمدير Ø§Ù„Ù…Ù„ÙØ§Øª يدويًا</string>
83 <string name="manage_save_data">إدارة Ø­ÙØ¸ البيانات</string>
84 <string name="manage_save_data_description">Ø­ÙØ¸ البيانات التي تم العثور عليها. يرجى اختيار أحد الخيارات التالية</string>
85 <string name="import_export_saves_description">استيراد أو تصدير Ù…Ù„ÙØ§Øª Ø§Ù„Ø­ÙØ¸</string>
86 <string name="save_file_imported_success">تم الاستيراد بنجاح</string>
87 <string name="save_file_invalid_zip_structure">بنية مجلد Ø§Ù„Ø­ÙØ¸ غير صالحة</string>
88 <string name="save_file_invalid_zip_structure_description">يجب أن يكون اسم المجلد Ø§Ù„ÙØ±Ø¹ÙŠ Ø§Ù„Ø£ÙˆÙ„ هو معر٠عنوان اللعبة.</string>
89 <string name="import_saves">استيراد</string>
90 <string name="export_saves">تصدير</string>
91 <string name="install_firmware">تثبيت البرامج الثابتة</string>
92 <string name="firmware_installing">تثبيت البرامج الثابتة</string>
93 <string name="firmware_installed_success">تم تثبيت البرامج الثابتة بنجاح</string>
94 <string name="firmware_installed_failure">ÙØ´Ù„ تثبيت البرامج الثابتة</string>
95 <string name="share_log">مشاركة سجلات التصحيح</string>
96 <string name="share_log_description">مشاركة مل٠سجل يوزو لتصحيح المشكلات</string>
97 <string name="share_log_missing">لم يتم العثور على مل٠السجل</string>
98 <string name="install_game_content">تثبيت محتوى اللعبة</string>
99 <string name="install_game_content_description">DLC قم بتثبيت تحديثات اللعبة أو</string>
100 <string name="installing_game_content">جار٠تثبيت المحتوى</string>
101 <string name="install_game_content_failure_base">لا ÙŠÙØ³Ù…Ø­ بتثبيت الألعاب الأساسية لتجنب التعارضات المحتملة.</string>
102 <string name="install_game_content_success_install">%1$d تم التثبيت بنجاح</string>
103 <string name="install_game_content_success_overwrite">%1$d تمت الكتابة Ùوقه بنجاح</string>
104 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
105 <string name="custom_driver_not_supported">برامج التشغيل المخصصة غير مدعومة</string>
106 <string name="custom_driver_not_supported_description">تحميل برنامج التشغيل المخصص غير معتمد حاليًا لهذا الجهاز.\nحدد هذا الخيار مرة أخرى ÙÙŠ المستقبل Ù„Ù…Ø¹Ø±ÙØ© ما إذا تمت Ø¥Ø¶Ø§ÙØ© الدعم!</string>
107 <string name="manage_yuzu_data">إدارة بيانات يوزو</string>
108 <string name="manage_yuzu_data_description">استيراد/تصدير البرامج الثابتة ÙˆØ§Ù„Ù…ÙØ§ØªÙŠØ­ وبيانات المستخدم والمزيد!</string>
109 <string name="share_save_file">مشاركة Ù…Ù„Ù Ø§Ù„Ø­ÙØ¸</string>
110 <string name="export_save_failed">ÙØ´Ù„ تصدير Ø§Ù„Ø­ÙØ¸</string>
111
112 <string name="copied_to_clipboard">نسخ إلى Ø§Ù„Ø­Ø§ÙØ¸Ø©</string>
113 <string name="about_app_description">محاكي سويتش Ù…ÙØªÙˆØ­ المصدر</string>
114 <string name="contributors">المساهمين</string>
115 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
116 <string name="licenses_description">المشاريع التي تجعل تطبيق يوزو لنظام أندرويد ممكنًا</string>
117 <string name="build">البناء</string>
118 <string name="user_data">بيانات المستخدم</string>
119 <string name="exporting_user_data">جار٠تصدير بيانات المستخدم</string>
120 <string name="importing_user_data">جار٠استيراد بيانات المستخدم</string>
121 <string name="import_user_data">استيراد بيانات المستخدم</string>
122 <string name="invalid_yuzu_backup">نسخة احتياطية يوزو غير صالحة</string>
123 <string name="user_data_export_success">تم تصدير بيانات المستخدم بنجاح</string>
124 <string name="user_data_import_success">تم استيراد بيانات المستخدم بنجاح</string>
125 <string name="user_data_export_cancelled">تم إلغاء التصدير</string>
126 <string name="support_link">https://discord.gg/u77vRWY</string>
127 <string name="website_link">https://yuzu-emu.org/</string>
128 <string name="github_link">https://github.com/yuzu-emu</string>
129
130 <!-- Early access upgrade strings -->
131 <string name="early_access">الوصول المبكر</string>
132 <string name="get_early_access">احصل على الوصول المبكر</string>
133 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
134 <string name="get_early_access_description">الميزات المتطورة، والوصول المبكر إلى التحديثات، وأكثر من ذلك</string>
135 <string name="early_access_benefits">مزايا الوصول المبكر</string>
136 <string name="cutting_edge_features">ميزات متطورة</string>
137 <string name="early_access_updates">الوصول المبكر إلى التحديثات</string>
138 <string name="no_manual_installation">لا يوجد التثبيت اليدوي</string>
139 <string name="prioritized_support">الدعم ذو الأولوية</string>
140 <string name="helping_game_preservation">المساعدة ÙÙŠ Ø§Ù„Ø­ÙØ§Ø¸ على اللعبة</string>
141 <string name="our_eternal_gratitude">امتناننا الأبدي</string>
142 <string name="are_you_interested">هل انت مهتم؟</string>
143
144 <!-- General settings strings -->
145 <string name="frame_limit_enable">الحد من السرعة</string>
146 <string name="frame_limit_enable_description">يحد من سرعة المحاكاة بنسبة محددة من السرعة العادية</string>
147 <string name="frame_limit_slider">الحد من السرعة ÙÙŠ المئة</string>
148 <string name="frame_limit_slider_description">يحدد النسبة المئوية للحد من سرعة المحاكاة. 100% هي السرعة الطبيعية. ستؤدي القيم الأعلى أو الأدنى إلى زيادة أو تقليل حد السرعة.</string>
149 <string name="cpu_accuracy">دقة وحدة المعالجة المركزية</string>
150 <string name="value_with_units">%1$s%2$s</string>
151
152 <!-- System settings strings -->
153 <string name="use_docked_mode">وضع الإرساء</string>
154 <string name="use_docked_mode_description">زيادة الدقة، ÙˆØ§Ù†Ø®ÙØ§Ø¶ الأداء. يتم استخدام الوضع المحمول عند تعطيله، مما يؤدي إلى Ø®ÙØ¶ الدقة وزيادة الأداء.</string>
155 <string name="emulated_region">المنطقة التي تمت محاكاتها</string>
156 <string name="emulated_language">لغة المحاكاه</string>
157 <string name="select_rtc_date">حدد التاريخ Ùˆ الساعة ÙÙŠ الوقت الحقيقي</string>
158 <string name="select_rtc_time">حدد وقت الساعة ÙÙŠ الوقت Ø§Ù„ÙØ¹Ù„ÙŠ</string>
159 <string name="use_custom_rtc">ساعة مخصصة ÙÙŠ الوقت الحقيقي</string>
160 <string name="use_custom_rtc_description">يسمح لك بتعيين ساعة مخصصة ÙÙŠ الوقت Ø§Ù„ÙØ¹Ù„ÙŠ Ù…Ù†ÙØµÙ„Ø© عن وقت النظام الحالي لديك</string>
161 <string name="set_custom_rtc">تعيين ساعة مخصصة ÙÙŠ الوقت الحقيقي</string>
162
163 <!-- Graphics settings strings -->
164 <string name="renderer_accuracy">مستوى الدقة</string>
165 <string name="renderer_resolution">(Handheld/Docked) الدقة</string>
166 <string name="renderer_vsync">VSync وضع</string>
167 <string name="renderer_screen_layout">الاتجاه</string>
168 <string name="renderer_aspect_ratio">تناسب الابعاد</string>
169 <string name="renderer_anti_aliasing">طريقة Ù…ÙƒØ§ÙØ­Ø© التعرج</string>
170 <string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
171 <string name="renderer_asynchronous_shaders_description">يجمع التظليل بشكل غير متزامن، مما يقلل من التأتأة ولكنه قد يؤدي إلى حدوث بعض الأخطاء.</string>
172 <string name="renderer_reactive_flushing">استخدم Ø§Ù„ØªÙ†Ø¸ÙŠÙ Ø§Ù„ØªÙØ§Ø¹Ù„ÙŠ</string>
173 <string name="renderer_reactive_flushing_description">تحسين دقة العرض ÙÙŠ بعض الألعاب على حساب الأداء</string>
174 <string name="use_disk_shader_cache_description">يقلل من التأتأة عن طريق تخزين وتحميل التظليلات التي تم إنشاؤها محليًا.</string>
175
176 <!-- Debug settings strings -->
177 <string name="cpu">وحدة المعالج المركزية</string>
178 <string name="cpu_debug_mode">تصحيح أخطاء وحدة المعالجة المركزية</string>
179 <string name="cpu_debug_mode_description">يضع وحدة المعالجة المركزية ÙÙŠ وضع التصحيح البطيء.</string>
180 <string name="gpu">GPU</string>
181 <string name="renderer_api">API</string>
182 <string name="renderer_debug">تصحيح الأخطاء الرسومية</string>
183 <string name="renderer_debug_description">يضبط واجهة برمجة تطبيقات الرسومات على وضع تصحيح الأخطاء البطيء.</string>
184 <string name="fastmem">Fastmem</string>
185
186 <!-- Audio settings strings -->
187 <string name="audio_output_engine">محرك الإخراج</string>
188 <string name="audio_volume">حجم</string>
189 <string name="audio_volume_description">يحدد حجم إخراج الصوت</string>
190
191 <!-- Miscellaneous -->
192 <string name="slider_default">Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
193 <string name="ini_saved">الإعدادات المحÙوظة</string>
194 <string name="gameid_saved">الإعدادات المحÙوظة لـ %1$s</string>
195 <string name="unimplemented_menu">القائمة غير Ø§Ù„Ù…Ù†ÙØ°Ø©</string>
196 <string name="loading">جاري تحميل</string>
197 <string name="shutting_down">إيقا٠تشغيل</string>
198 <string name="reset_setting_confirmation">هل تريد إعادة تعيين هذا الإعداد مرة أخرى إلى قيمته Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©ØŸ</string>
199 <string name="reset_to_default">إعادة تعيين إلى Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
200 <string name="reset_all_settings">إعادة تعيين جميع الإعدادات؟</string>
201 <string name="reset_all_settings_description">سيتم إعادة تعيين ÙƒØ§ÙØ© الإعدادات المتقدمة إلى تكوينها Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ. هذا لا يمكن التراجع عنها.</string>
202 <string name="settings_reset">إعادة تعيين الأعدادات</string>
203 <string name="close">إغلاق</string>
204 <string name="learn_more">Ù…Ø¹Ø±ÙØ© المزيد</string>
205 <string name="auto">تلقائي</string>
206 <string name="submit">إرسال</string>
207 <string name="string_null">قيمه خاليه</string>
208 <string name="string_import">استيراد</string>
209 <string name="export">تصدير</string>
210 <string name="export_failed">ÙØ´Ù„ التصدير</string>
211 <string name="import_failed">ÙØ´Ù„ الاستيراد</string>
212 <string name="cancelling">إلغاء</string>
213
214 <!-- GPU driver installation -->
215 <string name="select_gpu_driver">GPU حدد برنامج تشغيل</string>
216 <string name="select_gpu_driver_title">الحالي الخاص بك؟ GPU هل ترغب ÙÙŠ استبدال برنامج تشغيل</string>
217 <string name="select_gpu_driver_install">تثبيت</string>
218 <string name="select_gpu_driver_default">Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
219 <string name="select_gpu_driver_use_default">يستخدم تعري٠معالج الرسوميات Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
220 <string name="select_gpu_driver_error">تم تحديد برنامج تشغيل غير صالح ØŒ باستخدام النظام Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
221 <string name="system_gpu_driver">تعري٠معالج الرسوميات الخاص بالنظام</string>
222 <string name="installing_driver">جار٠تثبيت برنامج التشغيل…</string>
223
224 <!-- Preferences Screen -->
225 <string name="preferences_settings">إعدادات</string>
226 <string name="preferences_general">عام</string>
227 <string name="preferences_system">النظام</string>
228 <string name="preferences_graphics">الرسوميات</string>
229 <string name="preferences_audio">الصوت</string>
230 <string name="preferences_theme">السمة واللون</string>
231 <string name="preferences_debug">تصحيح الأخطاء</string>
232
233 <!-- ROM loading errors -->
234 <string name="loader_error_encrypted">الخاص بك ROM تم تشÙير</string>
235 <string name="loader_error_video_core">حدث خطأ أثناء تهيئة مركز الÙيديو</string>
236 <string name="loader_error_invalid_format">ROM غير قادر على تحميل</string>
237 <string name="loader_error_file_not_found">غير موجود ROM ملÙ</string>
238
239 <!-- Emulation Menu -->
240 <string name="emulation_exit">الخروج من المحاكاة</string>
241 <string name="emulation_done">منجز</string>
242 <string name="emulation_fps_counter">عداد إطار/ثانية</string>
243 <string name="emulation_toggle_controls">تبديل عناصر التحكم</string>
244 <string name="emulation_rel_stick_center">مركز العصا النسبي</string>
245 <string name="emulation_dpad_slide">مزلاق أزرار الاتجاهات</string>
246 <string name="emulation_haptics">الاهتزازات الديناميكية</string>
247 <string name="emulation_show_overlay">عرض التراكب</string>
248 <string name="emulation_toggle_all">تبديل الكل</string>
249 <string name="emulation_control_adjust">ضبط التراكب</string>
250 <string name="emulation_control_scale">حجم</string>
251 <string name="emulation_control_opacity">العتامه</string>
252 <string name="emulation_touch_overlay_reset">إعادة تعيين التراكب</string>
253 <string name="emulation_touch_overlay_edit">تحرير التراكب</string>
254 <string name="emulation_pause">إيقا٠المحاكاة مؤقتًا</string>
255 <string name="emulation_unpause">إلغاء الإيقا٠المؤقت للمضاهاة</string>
256 <string name="emulation_input_overlay">خيارات التراكب</string>
257
258 <string name="load_settings">جار٠تحميل الإعدادات</string>
259
260 <!-- Software keyboard -->
261 <string name="software_keyboard">لوحة Ø§Ù„Ù…ÙØ§ØªÙŠØ­ البرمجية</string>
262
263 <!-- Errors and warnings -->
264 <string name="abort_button">إلغاء</string>
265 <string name="continue_button">استمر</string>
266 <string name="system_archive_not_found">لم يتم العثور على أرشي٠النظام</string>
267 <string name="system_archive_general">أرشي٠النظام</string>
268 <string name="save_load_error">خطأ ÙÙŠ Ø§Ù„Ø­ÙØ¸/التحميل</string>
269 <string name="fatal_error">خطا ÙØ§Ø¯Ø­</string>
270 <string name="performance_warning">سيؤدي إيقا٠تشغيل هذا الإعداد إلى تقليل أداء المحاكاة بشكل ملحوظ! للحصول على Ø£ÙØ¶Ù„ تجربة، يوصى بترك هذا الإعداد ممكنًا.</string>
271 <string name="memory_formatted">%1$s %2$s</string>
272 <string name="no_game_present">لا توجد لعبة قابلة للتمهيد</string>
273
274 <!-- Region Names -->
275 <string name="region_japan">اليابان</string>
276 <string name="region_usa">الولايات المتحدة الأمريكية</string>
277 <string name="region_europe">أوروبا</string>
278 <string name="region_australia">أستراليا</string>
279 <string name="region_china">الصين</string>
280 <string name="region_korea">كوريا</string>
281 <string name="region_taiwan">تايوان</string>
282
283 <!-- Memory Sizes -->
284 <string name="memory_byte">Byte</string>
285 <string name="memory_kilobyte">KB</string>
286 <string name="memory_megabyte">MB</string>
287 <string name="memory_gigabyte">GB</string>
288 <string name="memory_terabyte">TB</string>
289 <string name="memory_petabyte">PB</string>
290 <string name="memory_exabyte">EB</string>
291
292 <!-- Renderer APIs -->
293 <string name="renderer_vulkan">Vulkan</string>
294 <string name="renderer_none">لاشيء</string>
295
296 <!-- Renderer Accuracy -->
297 <string name="renderer_accuracy_normal">عادي</string>
298 <string name="renderer_accuracy_high">عالي</string>
299 <string name="renderer_accuracy_extreme">Extreme (بطيء)</string>
300
301 <!-- Resolutions -->
302 <string name="resolution_half">0.5X (360p/540p)</string>
303 <string name="resolution_three_quarter">0.75X (540p/810p)</string>
304 <string name="resolution_one">1X (720p/1080p)</string>
305 <string name="resolution_two">2X (1440p/2160p) (بطيء)</string>
306 <string name="resolution_three">3X (2160p/3240p) (بطيء)</string>
307 <string name="resolution_four">4X (2880p/4320p) (بطيء)</string>
308
309 <!-- Renderer VSync -->
310 <string name="renderer_vsync_immediate">Immediate (Off)</string>
311 <string name="renderer_vsync_mailbox">Mailbox</string>
312 <string name="renderer_vsync_fifo">FIFO (On)</string>
313 <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
314
315 <!-- Scaling Filters -->
316 <string name="scaling_filter_nearest_neighbor">Nearest Neighbor</string>
317 <string name="scaling_filter_bilinear">Bilinear</string>
318 <string name="scaling_filter_bicubic">Bicubic</string>
319 <string name="scaling_filter_gaussian">Gaussian</string>
320 <string name="scaling_filter_scale_force">ScaleForce</string>
321 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ Super Resolution</string>
322
323 <!-- Anti-Aliasing -->
324 <string name="anti_aliasing_none">لا شيء</string>
325 <string name="anti_aliasing_fxaa">FXAA</string>
326 <string name="anti_aliasing_smaa">SMAA</string>
327
328 <!-- Screen Layouts -->
329 <string name="screen_layout_landscape">اÙقي</string>
330 <string name="screen_layout_portrait">عمودي</string>
331 <string name="screen_layout_auto">تلقائي</string>
332
333 <!-- Aspect Ratios -->
334 <string name="ratio_default">(16:9) Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
335 <string name="ratio_force_four_three">4:3 ÙØ±Ø¶</string>
336 <string name="ratio_force_twenty_one_nine">21:9 ÙØ±Ø¶</string>
337 <string name="ratio_force_sixteen_ten">16:10 ÙØ±Ø¶</string>
338 <string name="ratio_stretch">تمتد إلى Ø§Ù„Ù†Ø§ÙØ°Ø©</string>
339
340 <!-- CPU Accuracy -->
341 <string name="cpu_accuracy_accurate">دقه</string>
342 <string name="cpu_accuracy_unsafe">غير آمن</string>
343 <string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
344
345 <!-- Gamepad Buttons -->
346 <string name="gamepad_d_pad">أزرار الاتجاهات</string>
347 <string name="gamepad_left_stick">العصا اليسرى</string>
348 <string name="gamepad_right_stick">العصا اليمنى</string>
349 <string name="gamepad_home">شاشة الإستقبال</string>
350 <string name="gamepad_screenshot">لقطة شاشة</string>
351
352 <!-- Disk shader cache -->
353 <string name="preparing_shaders">تحضير التظليل</string>
354 <string name="building_shaders">بناء التظليل</string>
355
356 <!-- Theme options -->
357 <string name="change_app_theme">تغيير سمة التطبيق</string>
358 <string name="theme_default">Ø§ÙØªØ±Ø§Ø¶ÙŠ</string>
359 <string name="theme_material_you">Material You</string>
360
361 <!-- Theme Modes -->
362 <string name="change_theme_mode">تغيير وضع السمة</string>
363 <string name="theme_mode_follow_system">اتبع النظام</string>
364 <string name="theme_mode_light">ÙØ§ØªØ­</string>
365 <string name="theme_mode_dark">غامق</string>
366
367 <!-- Audio output engines -->
368 <string name="cubeb">cubeb</string>
369
370 <!-- Black backgrounds theme -->
371 <string name="use_black_backgrounds">خلÙيات سوداء</string>
372 <string name="use_black_backgrounds_description">عند استخدام المظهر الداكن، قم بتطبيق خلÙيات سوداء.</string>
373
374 <!-- Picture-In-Picture -->
375 <string name="picture_in_picture">صورة داخل صورة</string>
376 <string name="picture_in_picture_description">تصغير Ø§Ù„Ù†Ø§ÙØ°Ø© عند وضعها ÙÙŠ الخلÙية</string>
377 <string name="pause">توقÙ</string>
378 <string name="play">تشغيل</string>
379 <string name="mute">كتم</string>
380 <string name="unmute">إلغاء الكتم</string>
381
382 <!-- Licenses screen strings -->
383 <string name="licenses">التراخيص</string>
384 <string name="license_fidelityfx_fsr_description">AMD ترقية عالية الجودة من</string>
385 </resources>
diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml
new file mode 100644
index 000000000..d2e5fee19
--- /dev/null
+++ b/src/android/app/src/main/res/values-ckb/strings.xml
@@ -0,0 +1,336 @@
1<?xml version="1.0" encoding="utf-8"?>
2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3
4 <string name="app_disclaimer">ئەم نەرمەکاڵایە یارییەکانی کۆنسۆلی نینتێندۆ سویچ کارپێدەکات. هیچ ناونیشانێکی یاری Ùˆ کلیلی تێدا نییە..&lt;br /&gt;&lt;br /&gt;Ù¾ÛŽØ´ ئەوەی دەست Ù¾ÛŽ بکەیت، تکایە شوێنی ÙØ§ÛŒÙ„ÛŒ <![CDATA[<b> prod.keys </b>]]> دیاریبکە Ù„Û• Ù†ÛŽÙˆ کۆگای ئامێرەکەت.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">زیاتر Ùێربە</a>]]></string>
5 <string name="emulation_notification_channel_name">ئیمولەیشن کارایە</string>
6 <string name="emulation_notification_channel_description">ئاگادارکردنەوەیەکی بەردەوام نیشان دەدات کاتێک ئیمولەیشن کاردەکات.</string>
7 <string name="emulation_notification_running">یوزو کاردەکات</string>
8 <string name="notice_notification_channel_name">ئاگاداری و هەڵەکان</string>
9 <string name="notice_notification_channel_description">ئاگادارکردنەوەکان پیشان دەدات کاتێک شتێک بە هەڵەدا دەچێت.</string>
10 <string name="notification_permission_not_granted">مۆڵەتی ئاگادارکردنەوە نەدراوە!</string>
11
12 <!-- Setup strings -->
13 <string name="welcome">بەخێربێیت!</string>
14 <string name="welcome_description">Ùێربە Ú†Û†Ù† &lt;b>yuzu&lt;/b> ڕێکبخەیت Ùˆ بچییە ناو ئیمولەیشن.</string>
15 <string name="get_started">دەست پێبکە</string>
16 <string name="keys">کلیلەکان</string>
17 <string name="keys_description">ÙØ§ÛŒÙ„ÛŒ &lt;b>prod.keys&lt;/b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
18 <string name="select_keys">کلیلەکان هەڵبژێرە</string>
19 <string name="games">یاریەکان</string>
20 <string name="games_description">Ùۆڵدەری &lt;b>Games&lt;/b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
21 <string name="done">تەواو</string>
22 <string name="done_description">تۆ تەواو ئامادەیت.\nچێژ لە یارییەکانت وەربگرە!</string>
23 <string name="text_continue">بەردەوام بوون</string>
24 <string name="next">دواتر</string>
25 <string name="back">گەڕانەوە</string>
26 <string name="add_games">زیادکردنی یاری</string>
27 <string name="add_games_description">Ùۆڵدەری یارییەکانت هەڵبژێرە</string>
28 <!-- Home strings -->
29 <string name="home_games">یاریەکان</string>
30 <string name="home_search">گەڕان</string>
31 <string name="home_settings">ڕێکخستنەکان</string>
32 <string name="empty_gamelist">تا ئێستا هیچ ÙØ§ÛŒÙ„ÛŽÚ© نەدۆزراوەتەوە یان هیچ ناونیشانێکی یاری هەڵنەبژێردراوە.</string>
33 <string name="search_and_filter_games">گەڕان Ùˆ Ùلتەرکردنی یارییەکان</string>
34 <string name="select_games_folder">Ùۆڵدەری یارییەکان هەڵبژێرە</string>
35 <string name="select_games_folder_description">ڕێگە بە یوزو دەدات بۆ پڕکردنەوەی لیستی یارییەکان</string>
36 <string name="add_games_warning">هەڵبژاردنی Ùۆڵدەری یارییەکان تێپەڕدەکەیت؟</string>
37 <string name="add_games_warning_description">یارییەکان Ù„Û• لیستی یارییەکاندا پیشان نادرێن ئەگەر Ùۆڵدەرێک هەڵنەبژێردرێت.</string>
38 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
39 <string name="home_search_games">گەڕان بەدوای یارییەکاندا</string>
40 <string name="games_dir_selected">ناونیشانی یارییەکان هەڵبژێردرا</string>
41 <string name="install_prod_keys">دابمەزرێنە prod.keys</string>
42 <string name="install_prod_keys_description">پێویستە بۆ کۆدکردنەوەى یارییە تاکەکەسییەکان</string>
43 <string name="install_prod_keys_warning">زیادکردنی کلیلەکان تێپەڕدەکەیت؟</string>
44 <string name="install_prod_keys_warning_description">کلیلی دروست پێویستە بۆ وەرگرتنی یارییەکانی تاکەکەسی. تەنها ئەپەکانی homebrew کاردەکەن ئەگەر بەردەوام بیت.</string>
45 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
46 <string name="notifications">ئاگادارکردنەوەکان</string>
47 <string name="notifications_description">بە دوگمەی خوارەوە مۆڵەتی ئاگادارکردنەوەکە بدە.</string>
48 <string name="give_permission">مۆڵەت بدە</string>
49 <string name="notification_warning">پێدانی مۆڵەتی ئاگادارکردنەوە تێپەڕدەکەیت؟</string>
50 <string name="notification_warning_description">یوزو ناتوانێت لە زانیاری گرنگ ئاگادارت بکاتەوە.</string>
51 <string name="permission_denied">مۆڵەت پێدان ڕەتکرایەوە</string>
52 <string name="permission_denied_description">زۆر جار ئەم مۆڵەتەت ڕەتکردۆتەوە و ئێستا دەبێت بە دەستی ڕێگەپێدان بکەیت لە ڕێکخستنەکانی سیستەمدا.</string>
53 <string name="about">دەربارە</string>
54 <string name="about_description">وەشانی دروستکردن، بیتبێن و زۆر شتیتر</string>
55 <string name="warning_help">یارمەتی</string>
56 <string name="warning_skip">پەڕاندن</string>
57 <string name="warning_cancel">ڕەتکردنەوە</string>
58 <string name="install_amiibo_keys">دامەزراندنی کلیلی Amiibo</string>
59 <string name="install_amiibo_keys_description">پێویستە بۆ بەکارهێنانی Amiibo لە یاریدا</string>
60 <string name="invalid_keys_file">ÙØ§ÛŒÙ„ÛŒ کلیلێکی نادروست هەڵبژێردرا</string>
61 <string name="install_keys_success">کلیلەکان بە سەرکەوتوویی دامەزران</string>
62 <string name="reading_keys_failure">هەڵە لە خوێندنەوەی کۆدکردنی کلیل</string>
63 <string name="install_prod_keys_failure_extension_description">دڵنیابەوە Ú©Û• ÙØ§ÛŒÙ„ÛŒ کلیلەکانت درێژکراوەی .keys ÛŒ هەیە Ùˆ دووبارە هەوڵبدەرەوە.</string>
64 <string name="install_amiibo_keys_failure_extension_description">دڵنیابە Ú©Û• ÙØ§ÛŒÙ„ÛŒ کلیلەکانت درێژکراوەی .bin ÛŒ هەیە Ùˆ دووبارە هەوڵبدەرەوە.</string>
65 <string name="invalid_keys_error">کلیلی کۆدکردنی نادروستە</string>
66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
67 <string name="install_keys_failure_description">ÙØ§ÛŒÙ„Û• هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.</string>
68 <string name="install_gpu_driver">دامەزراندنی وەگەڕخەری GPU</string>
69 <string name="install_gpu_driver_description">دامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت</string>
70 <string name="advanced_settings">ڕێکخستنە پێشکەوتووەکان</string>
71 <string name="settings_description">سازدانی ڕێکخستنەکانی ئیمولەیتەر</string>
72 <string name="search_recently_played">بەم دواییە یاری کردووە</string>
73 <string name="search_recently_added">بەم دواییە زیادکرا</string>
74 <string name="search_retail">بەتاک</string>
75 <string name="search_homebrew">هۆم بریو</string>
76 <string name="open_user_folder">کردنەوەی Ùۆڵدەری یوزو</string>
77 <string name="open_user_folder_description">بەڕێوەبردنی ÙØ§ÛŒÙ„Û• ناوخۆییەکانی یوزو</string>
78 <string name="theme_and_color_description">دەستکاری کردنی شێوازی ئەپەکە</string>
79 <string name="no_file_manager">هیچ ÙØ§ÛŒÙ„ بەڕێوەبەرێک نەدۆزرایەوە</string>
80 <string name="notification_no_directory_link">نەتوانرا ناونیشانی یوزو بکرێتەوە</string>
81 <string name="notification_no_directory_link_description">تکایە شوێنی Ùۆڵدەری بەکارهێنەر Ù„Û•Ú¯Û•Úµ پانێڵی لایەنی ÙØ§ÛŒÙ„ بەڕێوەبارەکان بە دەست بدۆزەرەوە.</string>
82 <string name="manage_save_data">بەڕێوەبردنی داتای پاشەکەوتکراو</string>
83 <string name="manage_save_data_description">داتای پاشەکەوتکراو دۆزراوە. تکایە لە خوارەوە بژاردەیەک هەڵبژێرە.</string>
84 <string name="import_export_saves_description">هاوردەکردن یان هەناردەکردنی ÙØ§ÛŒÙ„ÛŒ پاشەکەوتکراو</string>
85 <string name="save_file_imported_success">بە سەرکەوتوویی هاوردە کرا</string>
86 <string name="save_file_invalid_zip_structure">پێکهاتەی شوێنی پاشەکەوتکراو نادروستە</string>
87 <string name="save_file_invalid_zip_structure_description">ناوی یەکەمی Ùۆڵدەر دەبێت ناسنامەی ناونیشانی یارییەکە بێت.</string>
88 <string name="import_saves">هاوردەکردن</string>
89 <string name="export_saves">هەناردەکردن</string>
90 <string name="install_firmware">دامەزراندنی پتەوواڵا</string>
91 <string name="install_firmware_description">پتەوواڵا دەبێت Ù„Û• ئەرشیÙÛŒ زیپدا بێت Ùˆ پێویستە بۆ بووتکردنی هەندێک یاری</string>
92 <string name="firmware_installing">دامەزرانی پتەوواڵا</string>
93 <string name="firmware_installed_success">پتەوواڵا بە سەرکەوتوویی دامەزرا</string>
94 <string name="firmware_installed_failure">دامەزراندنی پتەوواڵا شکستی هێنا</string>
95 <string name="share_log">هاوبەشی پێکردنی لۆگەکانی چاککردنەوە</string>
96 <string name="share_log_description">ÙØ§ÛŒÙ„Û• Ù„Û†Ú¯Û•Ú©Û•ÛŒ یوزو هاوبەش بکە بۆ چاککردنی کێشەکان</string>
97 <string name="share_log_missing">هیچ ÙØ§ÛŒÙ„ÛŽÚ©ÛŒ Ù„Û†Ú¯ نەدۆزراوە</string>
98 <string name="install_game_content">دامەزراندنی ناوەڕۆکی یاری</string>
99 <string name="install_game_content_description">دامەزراندنی نوێکاری یارییەکان یان DLC</string>
100 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
101 <!-- About screen strings -->
102 <string name="gaia_is_not_real">گایا ڕاستەقینە نییە</string>
103 <string name="copied_to_clipboard">کۆپی کرا بۆ تەختەی نووسین</string>
104 <string name="about_app_description">ئیمۆلیتەرێکی سەرچاوە-کراوەی سویچ</string>
105 <string name="contributors">بەشداربووان</string>
106 <string name="contributors_description">دروستکراوە لەگەڵ \u2764 لەلایەن تیمەکەی یوزو</string>
107 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
108 <string name="licenses_description">ئەو پڕۆژانەی کە یوزوی بۆ ئەندرۆید ڕەخساند</string>
109 <string name="build">بونیات</string>
110 <string name="support_link">https://discord.gg/u77vRWY</string>
111 <string name="website_link">https://yuzu-emu.org/</string>
112 <string name="github_link">https://github.com/yuzu-emu</string>
113
114 <!-- Early access upgrade strings -->
115 <string name="early_access">بەزوویی دەسپێگەشتن</string>
116 <string name="get_early_access">بەدەستهێنانی بەزوویی دەسپێگەشتن</string>
117 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
118 <string name="get_early_access_description">تایبەتمەندییە پێشکەوتووەکان، بەزوویی دەستگەیشتن بە نوێکارییەکان و زۆر شتی تر</string>
119 <string name="early_access_benefits">سوودەکانی بەزوویی دەسپێگەشتن</string>
120 <string name="cutting_edge_features">تایبەتمەندییە پێشکەوتووەکان</string>
121 <string name="early_access_updates">زوو دەستگەیشتن بە نوێکارییەکان</string>
122 <string name="no_manual_installation">چیتر دامەزراندنی دەستی نییە</string>
123 <string name="prioritized_support">پشتگیری لە پێشینە</string>
124 <string name="helping_game_preservation">یارمەتیدانی پاراستنی یارییەکان</string>
125 <string name="our_eternal_gratitude">سوپاس و پێزانینی هەمیشەییمان</string>
126 <string name="are_you_interested">ئایا تۆ خوازیاریت؟</string>
127
128 <!-- General settings strings -->
129 <string name="frame_limit_enable">سنووردارکردنی خێرایی</string>
130 <string name="frame_limit_enable_description">خێرایی ئیمولەیشن سنووردار دەکات بۆ ڕێژەیەکی دیاریکراو لە خێرایی ئاسایی.</string>
131 <string name="frame_limit_slider">سنووردارکردنی لەسەدای خێرایی</string>
132 <string name="frame_limit_slider_description">ڕێژەی سەدی دیاری دەکات بۆ سنووردارکردنی خێرایی ئیمولەیشن. 100% خێرایی ئاساییە. بەهایی بەرزتر یان نزمتر دەبێتە هۆی زیاد یان کەمکردنەوەی سنووری خێرایی.</string>
133 <string name="cpu_accuracy">وردی CPU</string>
134 <!-- System settings strings -->
135 <string name="use_docked_mode">دۆخی دۆککراو</string>
136 <string name="use_docked_mode_description">ڕوونی زیاد دەکات، کارایی کەم دەکاتەوە. دۆخی دەستی بەکاردێت کاتێک لەکاردەخرێت، ئەمەش ڕوونی دادەبەزێنێت و کارایی زیاد دەکات.</string>
137 <string name="emulated_region">ناوچەی ئیمولەیشن</string>
138 <string name="emulated_language">زمانی ئیمولەیتەر</string>
139 <string name="select_rtc_date">هەڵبژاردنی بەرواری RTC</string>
140 <string name="select_rtc_time">هەڵبژاردنی کاتی RTC</string>
141 <string name="use_custom_rtc">RTCی تایبەتمەند</string>
142 <string name="use_custom_rtc_description">ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت.</string>
143 <string name="set_custom_rtc">دانانی RTCی تایبەتمەند</string>
144
145 <!-- Graphics settings strings -->
146 <string name="renderer_accuracy">ئاستی وردبینی</string>
147 <string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
148 <string name="renderer_vsync">دۆخی VSync</string>
149 <string name="renderer_aspect_ratio">ڕێژەی ڕووبەری شاشە</string>
150 <string name="renderer_scaling_filter">Ùلتەری گونجاندنی پەنجەرە</string>
151 <string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
152 <string name="renderer_force_max_clock">ناچاریکردن بۆ زۆرترین کاتژمێر (تەنها ئەدرینۆ)</string>
153 <string name="renderer_force_max_clock_description">GPU ناچار دەکات بە زۆرترین کاتژمێر کاربکات (هێشتا سنووردارکردنی گەرمی جێبەجێ دەکرێت).</string>
154 <string name="renderer_asynchronous_shaders">بەکارهێنانی سێبەری ناهاوسەنگ</string>
155 <string name="renderer_asynchronous_shaders_description">سێبەرەکان بە شێوەیەکی ناهاوسەنگ کۆدەکاتەوە، پچڕپچڕی کەمدەکاتەوە بەڵام لەوانەیە گلێچ دروستکا.</string>
156 <string name="renderer_reactive_flushing">بەکارهێنانی بەرپێچدەرەوە</string>
157 <string name="renderer_reactive_flushing_description">وردی ڕێندەرکردن لە هەندێک یاریدا باشتر دەکات لەسەر تێچووی کارایی.</string>
158 <string name="use_disk_shader_cache">بیرگەخێرای سێبەری دیسک</string>
159 <string name="use_disk_shader_cache_description">پچڕپچڕی کەمدەکاتەوە بە هەڵگرتن و بارکردنی سێبەری دروستکراو لە ناوخۆدا.</string>
160
161 <!-- Debug settings strings -->
162 <string name="cpu">CPU</string>
163 <string name="renderer_api">API گراÙیک</string>
164 <string name="renderer_debug">چاککردنەوەی گراÙیک</string>
165 <string name="renderer_debug_description">API ÛŒ گراÙیکەکان ڕێکدەخات بۆ دۆخی چاککردنی خاو.</string>
166 <string name="audio_volume">قەبارەی دەنگی</string>
167 <string name="audio_volume_description">دیاریکردنی قەبارەی دەنگی دەرچووی بیستۆک و بزوێنەری دەنگی دەرەکی.</string>
168
169 <!-- Miscellaneous -->
170 <string name="slider_default">بنەڕەت</string>
171 <string name="ini_saved">ڕێکخستنە پاشەکەوتکراوەکان</string>
172 <string name="gameid_saved">ڕێکخستنە پاشەکەوتکراوەکان بۆ %1$s</string>
173 <string name="error_saving">هەڵە لە پاشەکەوتکردن %1$s.ini: %2$s</string>
174 <string name="loading">بارکردن...</string>
175 <string name="reset_setting_confirmation">ئایا دەتەوێت ئەم ڕێکخستنە بگەڕێنیتەوە بۆ بەهای بنەڕەتی خۆی؟</string>
176 <string name="reset_to_default">دوبارە ڕێکخستنەوەی بۆ بنەڕەت</string>
177 <string name="reset_all_settings">هەموو ڕێکخستنەکان دوبارە ڕێک دەخاتەوە؟</string>
178 <string name="reset_all_settings_description">هەموو ڕێکخستنە پێشکەوتووەکان دەگەڕێنەوە بۆ ڕێکخستنی بنەڕەتی خۆیان. پاشگەز بوونەوەی نییه.</string>
179 <string name="settings_reset">دوبارە ڕێککردنەوەی ڕێکخستنەکان</string>
180 <string name="close">داخستن</string>
181 <string name="learn_more">زیاتر Ùێربە</string>
182 <string name="auto">خودکار</string>
183 <string name="submit">پێشکەشکردن</string>
184 <string name="string_import">هاوردەکردن</string>
185 <string name="export">هەناردەکردن</string>
186 <!-- GPU driver installation -->
187 <string name="select_gpu_driver">هەڵبژاردنی وەگەڕخەری GPU</string>
188 <string name="select_gpu_driver_title">حەز دەکەیت وەگەڕخەری GPU ی ئێستات بگۆڕیت؟</string>
189 <string name="select_gpu_driver_install">دامەزراندن</string>
190 <string name="select_gpu_driver_default">بنەڕەت</string>
191 <string name="select_gpu_driver_use_default">بەکارهێنانی وەگەڕخەری GPU ی بنەڕەت</string>
192 <string name="select_gpu_driver_error">وەگەڕخەری نادروست هەڵبژێردرا، بە بەکارهێنانی بنەڕەتی سیستەم!</string>
193 <string name="system_gpu_driver">وەگەڕخەری GPU ی سیستەم</string>
194 <string name="installing_driver">دامەزراندنی وەگەڕخەر...</string>
195
196 <!-- Preferences Screen -->
197 <string name="preferences_settings">ڕێکخستنەکان</string>
198 <string name="preferences_general">گشتی</string>
199 <string name="preferences_system">سیستەم</string>
200 <string name="preferences_graphics">گراÙیک</string>
201 <string name="preferences_audio">دەنگ</string>
202 <string name="preferences_theme">ڕەنگ و ڕووکار</string>
203 <string name="preferences_debug">چاککردنەوە</string>
204
205 <!-- ROM loading errors -->
206 <string name="loader_error_encrypted">ڕۆمەکەت کۆدکراوە</string>
207 <string name="loader_error_encrypted_keys_description"><![CDATA[تکایە دڵنیابەوە لەدامەزراوی <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> ÙØ§ÛŒÙ„ەکەت بۆ ئەوەی بتوانرێت یارییەکان کۆد بکرێنەوە.]]></string>
208 <string name="loader_error_video_core">هەڵەیەک لە دەستپێکردنی ناوەکی ڤیدیۆکەدا ڕوویدا</string>
209 <string name="loader_error_video_core_description">ئەمەش بەزۆری بەهۆی وەگەڕخەرێکی ناتەبای GPU ەوەیە. دامەزراندنی وەگەڕخەری GPU ی تایبەتمەندکراو لەوانەیە ئەم کێشەیە چارەسەر بکات.</string>
210 <string name="loader_error_invalid_format">ناتوانرێت ڕۆم باربکرێت</string>
211 <string name="loader_error_file_not_found">ÙØ§ÛŒÙ„ÛŒ Ú•Û†Ù… بوونی نییە</string>
212
213 <!-- Emulation Menu -->
214 <string name="emulation_exit">دەرچوون لە ئیمولەیشن</string>
215 <string name="emulation_done">تەواو</string>
216 <string name="emulation_fps_counter">FPS ژمێر</string>
217 <string name="emulation_toggle_controls">گۆڕینی کۆنتڕۆڵ</string>
218 <string name="emulation_rel_stick_center">ناوەندی گێڕ بەنزیکەیی</string>
219 <string name="emulation_dpad_slide">خلیسکانی 4 دوگمەکە</string>
220 <string name="emulation_haptics">لەرینەوەی پەنجەلێدان</string>
221 <string name="emulation_show_overlay">نیشاندانی داپۆشەر</string>
222 <string name="emulation_toggle_all">گۆڕینی سەرجەم</string>
223 <string name="emulation_control_adjust">ڕێکخستنی داپۆشەر</string>
224 <string name="emulation_control_scale">پێوەر</string>
225 <string name="emulation_control_opacity">ڕوونی</string>
226 <string name="emulation_touch_overlay_reset">دووبارە ڕێکخستنەوەی داپۆشەر</string>
227 <string name="emulation_touch_overlay_edit">دەستکاریکردنی داپۆشەر</string>
228 <string name="emulation_pause">وەستاندنی ئیمولەیشن</string>
229 <string name="emulation_unpause">لادانی وەستاندنی ئیمولەیشن</string>
230 <string name="emulation_input_overlay">هەڵبژاردەکانی داپۆشەر</string>
231
232 <string name="load_settings">بارکردنی ڕێکخستنەکان...</string>
233
234 <!-- Software keyboard -->
235 <string name="software_keyboard">کیبۆردی نەرمەکاڵا</string>
236
237 <!-- Errors and warnings -->
238 <string name="abort_button">دەربارە</string>
239 <string name="continue_button">بەردەوام بوون</string>
240 <string name="system_archive_not_found">ئەرشیÙÛŒ سیستەم نەدۆزراوە</string>
241 <string name="system_archive_not_found_message">%s دیار نییە. تکایە ئەرشیÙÛŒ سیستەمەکەت ÙÚ•ÛŽ بدە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە Ù‡Û†ÛŒ تێکچوون Ùˆ Ùڕێدانەدەرەوە.</string>
242 <string name="system_archive_general">ئەرشیÙÛŽÚ©ÛŒ سیستەم</string>
243 <string name="save_load_error">هەڵەی پاشەکەوتکردن/بارکردن</string>
244 <string name="fatal_error">هەڵەی کوشندە</string>
245 <string name="fatal_error_message">هەڵەیەکی کوشندە ڕوویدا. بۆ وردەکارییەکان Ù„Û†Ú¯Û•Ú©Û• بپشکنە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە Ù‡Û†ÛŒ تێکچوون Ùˆ Ùڕێدانەدەرەوە.</string>
246 <string name="performance_warning">کوژاندنەوەی ئەم ڕێکخستنە دەبێتە هۆی کەمکردنەوەی کارایی ئیمولەیشن! بۆ باشترین ئەزموون، باشترە ئەم ڕێکخستنە چالاک بهێڵیتەوە.</string>
247 <!-- Region Names -->
248 <string name="region_japan">ژاپۆن</string>
249 <string name="region_usa">ئەمریکا</string>
250 <string name="region_europe">ئەورووپا</string>
251 <string name="region_australia">ئوسترالیا</string>
252 <string name="region_china">چین</string>
253 <string name="region_korea">کۆریا</string>
254 <string name="region_taiwan">تایوان</string>
255
256 <string name="memory_gigabyte">GB</string>
257 <!-- Renderer APIs -->
258 <string name="renderer_vulkan">ڤوڵکان</string>
259 <string name="renderer_none">هیچ</string>
260
261 <!-- Renderer Accuracy -->
262 <string name="renderer_accuracy_normal">ئاسایی</string>
263 <string name="renderer_accuracy_high">بەرز</string>
264 <string name="renderer_accuracy_extreme">ئەوپەڕ (خاو)</string>
265
266 <!-- Resolutions -->
267 <string name="resolution_half">0.5X (360p/540p)</string>
268 <string name="resolution_three_quarter">0.75X (540p/810p)</string>
269 <string name="resolution_one">1X (720p/1080p)</string>
270 <string name="resolution_two">2X (1440p/2160p) (خاو)</string>
271 <string name="resolution_three">3X (2160p/3240p) (خاو)</string>
272 <string name="resolution_four">4X (2880p/4320p) (خاو)</string>
273
274 <!-- Renderer VSync -->
275 <string name="renderer_vsync_immediate">دەستبەجێ (کوژاوە)</string>
276 <string name="renderer_vsync_mailbox">سندوقی پۆستە</string>
277 <string name="renderer_vsync_fifo">FIFO (پێکراو)</string>
278 <string name="renderer_vsync_fifo_relaxed">FIFO ئارام</string>
279
280 <!-- Scaling Filters -->
281 <string name="scaling_filter_nearest_neighbor">نزیکترین دراوسێ</string>
282 <string name="scaling_filter_bilinear">دوو هێڵی</string>
283 <string name="scaling_filter_bicubic">دووخشتەکی</string>
284 <string name="scaling_filter_gaussian">گاوسی</string>
285 <string name="scaling_filter_scale_force">پێوەرهێز</string>
286 <string name="scaling_filter_fsr">AMD FidelityFX™ سوپەر ووردبینی</string>
287
288 <!-- Anti-Aliasing -->
289 <string name="anti_aliasing_none">هیچ</string>
290 <string name="anti_aliasing_fxaa">FXAA</string>
291 <string name="anti_aliasing_smaa">SMAA</string>
292
293 <string name="screen_layout_auto">خودکار</string>
294
295 <!-- Aspect Ratios -->
296 <string name="ratio_default">بنەڕەت (16:9)</string>
297 <string name="ratio_force_four_three">ڕووبەری 4:3</string>
298 <string name="ratio_force_twenty_one_nine">ڕووبەری 21:9</string>
299 <string name="ratio_force_sixteen_ten">ڕووبەری 16:10</string>
300 <string name="ratio_stretch">کشانی پڕ بەشاشە</string>
301
302 <!-- CPU Accuracy -->
303 <string name="cpu_accuracy_accurate">وورد</string>
304 <string name="cpu_accuracy_unsafe">ناسەقامگیر</string>
305 <string name="cpu_accuracy_paranoid">بەگومان (خاو)</string>
306
307 <!-- Gamepad Buttons -->
308 <string name="gamepad_d_pad">4 دوگمەکە</string>
309 <string name="gamepad_left_stick">گێڕی چەپ</string>
310 <string name="gamepad_right_stick">گێڕی ڕاست</string>
311 <string name="gamepad_home">ماڵەوە</string>
312 <string name="gamepad_screenshot">وێنەگرتنی شاشە</string>
313
314 <!-- Disk shader cache -->
315 <string name="preparing_shaders">ئامادەکردنی سێبەرەکان</string>
316 <string name="building_shaders">دروستکردنی سێبەرەکان</string>
317
318 <!-- Theme options -->
319 <string name="change_app_theme">گۆڕینی ڕووکاری ئەپەکە</string>
320 <string name="theme_default">بنەڕەت</string>
321 <string name="theme_material_you">کەرەستەی تۆ</string>
322
323 <!-- Theme Modes -->
324 <string name="change_theme_mode">گۆڕینی دۆخی ڕووکار</string>
325 <string name="theme_mode_follow_system">پەیڕەوی کردنی سیستەم</string>
326 <string name="theme_mode_light">ڕوناکی</string>
327 <string name="theme_mode_dark">تاریک</string>
328
329 <!-- Black backgrounds theme -->
330 <string name="use_black_backgrounds">پاشبنەمای ڕەش</string>
331 <string name="use_black_backgrounds_description">لە کاتی بەکارهێنانی ڕووکاری تاریکدا، پاشبنەمای ڕەش دادەنێ.</string>
332
333 <!-- Licenses screen strings -->
334 <string name="licenses">مۆڵەتەکان</string>
335 <string name="license_fidelityfx_fsr_description">بەرزکردنەوەی کوالێتی بەرز لە کۆمپانیای AMD</string>
336 </resources>
diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml
index 72a47fbdb..9c6590b5e 100644
--- a/src/android/app/src/main/res/values-de/strings.xml
+++ b/src/android/app/src/main/res/values-de/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.&lt;br /&gt;&lt;br /&gt;Bevor du beginnst, bitte halte deine <![CDATA[<b> prod.keys </b>]]> auf deinem Gerät bereit. .&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Mehr Infos</a>]]></string> 4 <string name="app_disclaimer">Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.&lt;br /&gt;&lt;br /&gt;Bevor du beginnst, bitte halte deine <![CDATA[<b> prod.keys </b>]]> auf deinem Gerät bereit. .&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Mehr Infos</a>]]></string>
5 <string name="emulation_notification_channel_name">Emulation ist aktiv</string> 5 <string name="emulation_notification_channel_name">Emulation ist aktiv</string>
@@ -25,6 +25,7 @@
25 <string name="back">Zurück</string> 25 <string name="back">Zurück</string>
26 <string name="add_games">Spiele hinzufügen</string> 26 <string name="add_games">Spiele hinzufügen</string>
27 <string name="add_games_description">Spieleverzeichnis auswählen</string> 27 <string name="add_games_description">Spieleverzeichnis auswählen</string>
28 <string name="step_complete">Fertig!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Spiele</string> 31 <string name="home_games">Spiele</string>
@@ -38,6 +39,7 @@
38 <string name="add_games_warning_description">Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.</string> 39 <string name="add_games_warning_description">Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Spiele suchen</string> 41 <string name="home_search_games">Spiele suchen</string>
42 <string name="search_settings">Einstellungen suchen</string>
41 <string name="games_dir_selected">Spieleverzeichnis ausgewählt</string> 43 <string name="games_dir_selected">Spieleverzeichnis ausgewählt</string>
42 <string name="install_prod_keys">prod.keys installieren</string> 44 <string name="install_prod_keys">prod.keys installieren</string>
43 <string name="install_prod_keys_description">Zum Entschlüsseln von Spielen benötigt</string> 45 <string name="install_prod_keys_description">Zum Entschlüsseln von Spielen benötigt</string>
@@ -60,8 +62,11 @@
60 <string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string> 62 <string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
61 <string name="install_keys_success">Schlüssel erfolgreich installiert</string> 63 <string name="install_keys_success">Schlüssel erfolgreich installiert</string>
62 <string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string> 64 <string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
65 <string name="install_prod_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.</string>
66 <string name="install_amiibo_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.</string>
63 <string name="invalid_keys_error">Ungültige Schlüssel</string> 67 <string name="invalid_keys_error">Ungültige Schlüssel</string>
64 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 68 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
69 <string name="install_keys_failure_description">Die ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.</string>
65 <string name="install_gpu_driver">GPU-Treiber installieren</string> 70 <string name="install_gpu_driver">GPU-Treiber installieren</string>
66 <string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string> 71 <string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
67 <string name="advanced_settings">Erweiterte Einstellungen</string> 72 <string name="advanced_settings">Erweiterte Einstellungen</string>
@@ -84,7 +89,17 @@
84 <string name="save_file_invalid_zip_structure_description">Der erste Unterordnername muss die Titel-ID des Spiels sein.</string> 89 <string name="save_file_invalid_zip_structure_description">Der erste Unterordnername muss die Titel-ID des Spiels sein.</string>
85 <string name="import_saves">Importieren</string> 90 <string name="import_saves">Importieren</string>
86 <string name="export_saves">Exportieren</string> 91 <string name="export_saves">Exportieren</string>
87 92 <string name="install_firmware">Firmware installieren</string>
93 <string name="install_firmware_description">Die Firmware muss in einem ZIP-Archiv vorliegen und wird zum Booten einiger Spiele benötigt</string>
94 <string name="firmware_installing">Firmware wird installiert</string>
95 <string name="firmware_installed_success">Die Firmware wurde erfolgreich installiert!</string>
96 <string name="firmware_installed_failure">Bei der Firmware installation ist etwas fehlgeschlagen.</string>
97 <string name="share_log">Debug-Logs teilen</string>
98 <string name="share_log_description">Debug-Logs an yuzu zur Untersuchung absenden</string>
99 <string name="share_log_missing">Keine Log-Datei gefunden</string>
100 <string name="install_game_content">Spiel installieren</string>
101 <string name="install_game_content_description">Spiel Update oder DLC installieren</string>
102 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
88 <!-- About screen strings --> 103 <!-- About screen strings -->
89 <string name="gaia_is_not_real">Gaia ist nicht real</string> 104 <string name="gaia_is_not_real">Gaia ist nicht real</string>
90 <string name="copied_to_clipboard">In die Zwischenablage kopiert</string> 105 <string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
@@ -92,7 +107,10 @@
92 <string name="contributors">Beitragende</string> 107 <string name="contributors">Beitragende</string>
93 <string name="contributors_description">Gemacht mit \u2764 vom yuzu Team</string> 108 <string name="contributors_description">Gemacht mit \u2764 vom yuzu Team</string>
94 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 109 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
110 <string name="licenses_description">Projekte, die yuzu für Android möglich machen </string>
95 <string name="build">Build</string> 111 <string name="build">Build</string>
112 <string name="user_data">Nutzerdaten</string>
113 <string name="user_data_export_cancelled">Export abgebrochen</string>
96 <string name="support_link">https://discord.gg/u77vRWY</string> 114 <string name="support_link">https://discord.gg/u77vRWY</string>
97 <string name="website_link">https://yuzu-emu.org/</string> 115 <string name="website_link">https://yuzu-emu.org/</string>
98 <string name="github_link">https://github.com/yuzu-emu</string> 116 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -107,45 +125,39 @@
107 <string name="early_access_updates">Früherer Zugriff auf Updates</string> 125 <string name="early_access_updates">Früherer Zugriff auf Updates</string>
108 <string name="no_manual_installation">Keine manuelle Installation</string> 126 <string name="no_manual_installation">Keine manuelle Installation</string>
109 <string name="prioritized_support">Priorisierte Unterstützung</string> 127 <string name="prioritized_support">Priorisierte Unterstützung</string>
128 <string name="helping_game_preservation">Beitrag zur Erhaltung der Spiele</string>
110 <string name="our_eternal_gratitude">Unsere ewige Dankbarkeit</string> 129 <string name="our_eternal_gratitude">Unsere ewige Dankbarkeit</string>
111 <string name="are_you_interested">Bist du interessiert?</string> 130 <string name="are_you_interested">Bist du interessiert?</string>
112 131
113 <!-- General settings strings --> 132 <!-- General settings strings -->
114 <string name="frame_limit_enable">Geschwindigkeitsbegrenzung aktivieren</string> 133 <string name="frame_limit_enable">Limitierte Geschwindigkeit</string>
115 <string name="frame_limit_enable_description">Wenn aktiviert, wird die Emulationsgeschwindigkeit auf einen Prozentsatz der normalen Geschwindigkeit begrenzt.</string> 134 <string name="frame_limit_enable_description">Limitiert die Geschwindigkeit auf einen von dir festgelegten Prozentsatz.</string>
116 <string name="frame_limit_slider">Geschwindkeitsbegrenzung in Prozent</string> 135 <string name="frame_limit_slider">Geschwindkeitsbegrenzung in Prozent</string>
117 <string name="frame_limit_slider_description">Legt den Prozentsatz der Bergrenzung der Emulationsgeschwindigkeit fest. Mit dem Standardwert von 100% wird die Emulation auf die normale Geschwindigkeit begrenzt. Höhere oder niedrigere Werte erhöhen oder verringern die Geschwindigkeitsbegrenzung.</string> 136 <string name="frame_limit_slider_description">Gibt die prozentuale Geschwindigkeit der Emulation an. 100% sind normal. Werte darüber oder drunter werden die Geschwindigkeit entsprechend verändern.</string>
118 <string name="cpu_accuracy">CPU-Genauigkeit</string> 137 <string name="cpu_accuracy">CPU-Genauigkeit</string>
119
120 <!-- System settings strings --> 138 <!-- System settings strings -->
121 <string name="use_docked_mode">Dock-Modus</string> 139 <string name="use_docked_mode">Gedockter Modus</string>
122 <string name="use_docked_mode_description">Emuliert im Dock-Modus, was die Auflösung verbessert, aber die Leistung senkt.</string> 140 <string name="use_docked_mode_description">Der Docked Modus erhöht die Auflösung, verringert die aber die Leistung. Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die Leistung.</string>
123 <string name="emulated_region">Emulierte Region</string> 141 <string name="emulated_region">Emulierte Region</string>
124 <string name="emulated_language">Emulierte Sprache</string> 142 <string name="emulated_language">Emulierte Sprache</string>
125 <string name="select_rtc_date">RTC-Datum auswählen</string> 143 <string name="select_rtc_date">RTC-Datum auswählen</string>
126 <string name="select_rtc_time">RTC-Zeit auswählen</string> 144 <string name="select_rtc_time">RTC-Zeit auswählen</string>
127 <string name="use_custom_rtc">Benutzerdefinierte RTC aktivieren</string> 145 <string name="use_custom_rtc">Benutzerdefinierte Echtzeituhr</string>
128 <string name="use_custom_rtc_description">Mit dieser Einstellung kann eine benutzerdefinierte Echtzeituhr unabhängig von der aktuellen Systemzeit verwendet werden.</string>
129 <string name="set_custom_rtc">Benutzerdefinierte RTC einstellen</string>
130
131 <!-- Graphics settings strings --> 146 <!-- Graphics settings strings -->
132 <string name="renderer_api">API</string>
133 <string name="renderer_accuracy">Genauigkeitsstufe</string> 147 <string name="renderer_accuracy">Genauigkeitsstufe</string>
134 <string name="renderer_resolution">Auflösung</string>
135 <string name="renderer_vsync">VSync-Modus</string> 148 <string name="renderer_vsync">VSync-Modus</string>
149 <string name="renderer_screen_layout">Orientierung</string>
136 <string name="renderer_aspect_ratio">Seitenverhältnis</string> 150 <string name="renderer_aspect_ratio">Seitenverhältnis</string>
137 <string name="renderer_scaling_filter">Fensteranpassungsfilter</string> 151 <string name="renderer_scaling_filter">Fensteranpassungsfilter</string>
138 <string name="renderer_anti_aliasing">Kantenglättungs-Methode</string>
139 <string name="renderer_force_max_clock">Maximale Taktfrequenz erzwingen (nur Adreno)</string> 152 <string name="renderer_force_max_clock">Maximale Taktfrequenz erzwingen (nur Adreno)</string>
140 <string name="renderer_force_max_clock_description">Erzwingt den Betrieb der GPU mit der maximal möglichen Taktfrequenz (Temperaturbeschränkungen werden weiterhin angewendet).</string> 153 <string name="renderer_force_max_clock_description">Erzwingt den Betrieb der GPU mit der maximal möglichen Taktfrequenz (Temperaturbeschränkungen werden weiterhin angewendet).</string>
141 <string name="renderer_asynchronous_shaders">Asynchrone Shader nutzen</string> 154 <string name="renderer_asynchronous_shaders">Asynchrone Shader nutzen</string>
142 <string name="renderer_asynchronous_shaders_description">Kompiliert Shader asynchron, was Ruckler reduziert, aber zu Glitches führen kann.</string> 155 <!-- Debug settings strings -->
143 <string name="renderer_debug">Grafik-Debugging aktivieren</string> 156 <string name="cpu">CPU</string>
144 <string name="renderer_debug_description">Wenn aktiviert, schaltet die Grafik-API in einen langsameren Debugging-Modus.</string> 157 <string name="cpu_debug_mode">CPU Debugging</string>
145 <string name="use_disk_shader_cache">Nutze Festplatten-Shader-Cache</string> 158 <string name="gpu">GPU</string>
146 <string name="use_disk_shader_cache_description">Ruckeln wird durch das Speichern und Laden von generierten Shadern auf der Festplatte reduziert.</string> 159 <string name="renderer_api">API</string>
147 160 <string name="renderer_debug">Graphik-Debugging</string>
148 <!-- Audio settings strings -->
149 <string name="audio_volume">Lautstärke</string> 161 <string name="audio_volume">Lautstärke</string>
150 <string name="audio_volume_description">Legt die Lautstärke der Audioausgabe fest.</string> 162 <string name="audio_volume_description">Legt die Lautstärke der Audioausgabe fest.</string>
151 163
@@ -154,14 +166,22 @@
154 <string name="ini_saved">Einstellungen gespeichert</string> 166 <string name="ini_saved">Einstellungen gespeichert</string>
155 <string name="gameid_saved">Einstellungen für %1$s gespeichert</string> 167 <string name="gameid_saved">Einstellungen für %1$s gespeichert</string>
156 <string name="error_saving">Fehler beim Speichern von %1$s.ini: %2$s</string> 168 <string name="error_saving">Fehler beim Speichern von %1$s.ini: %2$s</string>
169 <string name="unimplemented_menu">Unimplementiertes Menü</string>
157 <string name="loading">Lädt...</string> 170 <string name="loading">Lädt...</string>
158 <string name="reset_setting_confirmation">Möchtest du diese Einstellung auf den Standardwert zurücksetzen?</string> 171 <string name="reset_setting_confirmation">Möchtest du diese Einstellung auf den Standardwert zurücksetzen?</string>
159 <string name="reset_to_default">Auf Standard zurücksetzen</string> 172 <string name="reset_to_default">Auf Standard zurücksetzen</string>
160 <string name="reset_all_settings">Alle Einstellungen zurücksetzen?</string> 173 <string name="reset_all_settings">Alle Einstellungen zurücksetzen?</string>
161 <string name="reset_all_settings_description">Alle erweiterten Einstellungen werden auf ihren Standardwert zurückgesetzt. Dies kann nicht rückgängig gemacht werden.</string>
162 <string name="settings_reset">Einstellungen zurückgesetzt</string> 174 <string name="settings_reset">Einstellungen zurückgesetzt</string>
163 <string name="close">Schließen</string> 175 <string name="close">Schließen</string>
164 <string name="learn_more">Mehr erfahren</string> 176 <string name="learn_more">Mehr erfahren</string>
177 <string name="auto">Auto</string>
178 <string name="submit">Absenden</string>
179 <string name="string_null">Null</string>
180 <string name="string_import">Importieren</string>
181 <string name="export">Exportieren</string>
182 <string name="export_failed">Export fehlgeschlagen</string>
183 <string name="import_failed">Import fehlgeschlagen</string>
184 <string name="cancelling">Abbrechen</string>
165 185
166 <!-- GPU driver installation --> 186 <!-- GPU driver installation -->
167 <string name="select_gpu_driver">GPU-Treiber auswählen</string> 187 <string name="select_gpu_driver">GPU-Treiber auswählen</string>
@@ -169,6 +189,7 @@
169 <string name="select_gpu_driver_install">Installieren</string> 189 <string name="select_gpu_driver_install">Installieren</string>
170 <string name="select_gpu_driver_default">Standard</string> 190 <string name="select_gpu_driver_default">Standard</string>
171 <string name="select_gpu_driver_use_default">Standard GPU-Treiber wird verwendet</string> 191 <string name="select_gpu_driver_use_default">Standard GPU-Treiber wird verwendet</string>
192 <string name="select_gpu_driver_error">Ungültiger Treiber ausgewählt, Standard-Treiber wird verwendet!</string>
172 <string name="system_gpu_driver">System GPU-Treiber</string> 193 <string name="system_gpu_driver">System GPU-Treiber</string>
173 <string name="installing_driver">Treiber wird installiert...</string> 194 <string name="installing_driver">Treiber wird installiert...</string>
174 195
@@ -179,6 +200,7 @@
179 <string name="preferences_graphics">Grafik</string> 200 <string name="preferences_graphics">Grafik</string>
180 <string name="preferences_audio">Audio</string> 201 <string name="preferences_audio">Audio</string>
181 <string name="preferences_theme">Theme und Farbe</string> 202 <string name="preferences_theme">Theme und Farbe</string>
203 <string name="preferences_debug">Debug</string>
182 204
183 <!-- ROM loading errors --> 205 <!-- ROM loading errors -->
184 <string name="loader_error_encrypted">Das ROM ist verschlüsselt</string> 206 <string name="loader_error_encrypted">Das ROM ist verschlüsselt</string>
@@ -192,22 +214,15 @@
192 <string name="emulation_exit">Emulation beenden</string> 214 <string name="emulation_exit">Emulation beenden</string>
193 <string name="emulation_done">Fertig</string> 215 <string name="emulation_done">Fertig</string>
194 <string name="emulation_fps_counter">FPS Zähler</string> 216 <string name="emulation_fps_counter">FPS Zähler</string>
195 <string name="emulation_toggle_controls">Steuerung umschalten</string>
196 <string name="emulation_rel_stick_center">Relative Stick-Mitte</string>
197 <string name="emulation_dpad_slide">DPad Slide</string>
198 <string name="emulation_haptics">Haptik</string>
199 <string name="emulation_show_overlay">Overlay anzeigen</string>
200 <string name="emulation_toggle_all">Alle umschalten</string> 217 <string name="emulation_toggle_all">Alle umschalten</string>
201 <string name="emulation_control_adjust">Overlay anpassen</string> 218 <string name="emulation_control_adjust">Overlay anpassen</string>
202 <string name="emulation_control_scale">Größe</string> 219 <string name="emulation_control_scale">Größe</string>
203 <string name="emulation_control_opacity">Transparenz</string> 220 <string name="emulation_control_opacity">Transparenz</string>
204 <string name="emulation_touch_overlay_reset">Overlay zurücksetzen</string> 221 <string name="emulation_touch_overlay_reset">Overlay zurücksetzen</string>
205 <string name="emulation_touch_overlay_edit">Overlay bearbeiten</string> 222 <string name="emulation_touch_overlay_edit">Overlay bearbeiten</string>
206 <string name="emulation_pause">Emulation pausieren</string>
207 <string name="emulation_unpause">Emulation fortsetzen</string>
208 <string name="emulation_input_overlay">Overlay-Optionen</string> 223 <string name="emulation_input_overlay">Overlay-Optionen</string>
209 224
210 <string name="load_settings">Lädt Einstellungen...</string> 225 <string name="load_settings">Lade Einstellungen...</string>
211 226
212 <!-- Software keyboard --> 227 <!-- Software keyboard -->
213 <string name="software_keyboard">Software-Tastatur</string> 228 <string name="software_keyboard">Software-Tastatur</string>
@@ -221,7 +236,7 @@
221 <string name="fatal_error">Schwerwiegender Fehler</string> 236 <string name="fatal_error">Schwerwiegender Fehler</string>
222 <string name="fatal_error_message">Ein schwerwiegender Fehler ist aufgetreten. Einzelheiten wurden im Log protokolliert.\nDas Fortsetzen der Emulation kann zu Abstürzen und Bugs führen.</string> 237 <string name="fatal_error_message">Ein schwerwiegender Fehler ist aufgetreten. Einzelheiten wurden im Log protokolliert.\nDas Fortsetzen der Emulation kann zu Abstürzen und Bugs führen.</string>
223 <string name="performance_warning">Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen.</string> 238 <string name="performance_warning">Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen.</string>
224 239 <string name="memory_formatted">%1$s %2$s</string>
225 <!-- Region Names --> 240 <!-- Region Names -->
226 <string name="region_japan">Japan</string> 241 <string name="region_japan">Japan</string>
227 <string name="region_usa">USA</string> 242 <string name="region_usa">USA</string>
@@ -231,6 +246,15 @@
231 <string name="region_korea">Korea</string> 246 <string name="region_korea">Korea</string>
232 <string name="region_taiwan">Taiwan</string> 247 <string name="region_taiwan">Taiwan</string>
233 248
249 <!-- Memory Sizes -->
250 <string name="memory_byte">Byte</string>
251 <string name="memory_kilobyte">KB</string>
252 <string name="memory_megabyte">MB</string>
253 <string name="memory_gigabyte">GB</string>
254 <string name="memory_terabyte">TB</string>
255 <string name="memory_petabyte">PB</string>
256 <string name="memory_exabyte">EB</string>
257
234 <!-- Renderer APIs --> 258 <!-- Renderer APIs -->
235 <string name="renderer_vulkan">Vulkan</string> 259 <string name="renderer_vulkan">Vulkan</string>
236 <string name="renderer_none">Keiner</string> 260 <string name="renderer_none">Keiner</string>
@@ -267,12 +291,15 @@
267 <string name="anti_aliasing_fxaa">FXAA</string> 291 <string name="anti_aliasing_fxaa">FXAA</string>
268 <string name="anti_aliasing_smaa">SMAA</string> 292 <string name="anti_aliasing_smaa">SMAA</string>
269 293
294 <string name="screen_layout_portrait">Portrait</string>
295 <string name="screen_layout_auto">Auto</string>
296
270 <!-- Aspect Ratios --> 297 <!-- Aspect Ratios -->
271 <string name="ratio_default">Standard (16:9)</string> 298 <string name="ratio_default">Standard (16:9)</string>
272 <string name="ratio_force_four_three">4:3 erzwingen</string> 299 <string name="ratio_force_four_three">4:3 erzwingen</string>
273 <string name="ratio_force_twenty_one_nine">21:9 erzwingen</string> 300 <string name="ratio_force_twenty_one_nine">21:9 erzwingen</string>
274 <string name="ratio_force_sixteen_ten">Erzwinge 16:10</string> 301 <string name="ratio_force_sixteen_ten">Erzwinge 16:10</string>
275 <string name="ratio_stretch">Auf Fenster anpassen</string> 302 <string name="ratio_stretch">Auf Bildschirmgröße anpsassen</string>
276 303
277 <!-- CPU Accuracy --> 304 <!-- CPU Accuracy -->
278 <string name="cpu_accuracy_accurate">Akkurat</string> 305 <string name="cpu_accuracy_accurate">Akkurat</string>
@@ -280,9 +307,9 @@
280 <string name="cpu_accuracy_paranoid">Paranoid (Langsam)</string> 307 <string name="cpu_accuracy_paranoid">Paranoid (Langsam)</string>
281 308
282 <!-- Gamepad Buttons --> 309 <!-- Gamepad Buttons -->
283 <string name="gamepad_d_pad">Steuerkreuz</string> 310 <string name="gamepad_d_pad">D-Pad</string>
284 <string name="gamepad_left_stick">Linker Analogstick</string> 311 <string name="gamepad_left_stick">Linker Stick</string>
285 <string name="gamepad_right_stick">Rechter Analogstick</string> 312 <string name="gamepad_right_stick">Rechter Stick</string>
286 <string name="gamepad_home">Home</string> 313 <string name="gamepad_home">Home</string>
287 <string name="gamepad_screenshot">Screenshot</string> 314 <string name="gamepad_screenshot">Screenshot</string>
288 315
@@ -291,18 +318,30 @@
291 <string name="building_shaders">Shader werden erstellt</string> 318 <string name="building_shaders">Shader werden erstellt</string>
292 319
293 <!-- Theme options --> 320 <!-- Theme options -->
294 <string name="change_app_theme">App-Theme ändern</string> 321 <string name="change_app_theme">App-Thema ändern</string>
295 <string name="theme_default">Standard</string> 322 <string name="theme_default">Standard</string>
296 <string name="theme_material_you">Material You</string> 323 <string name="theme_material_you">Material You</string>
297 324
298 <!-- Theme Modes --> 325 <!-- Theme Modes -->
299 <string name="change_theme_mode">Theme-Modus ändern</string> 326 <string name="change_theme_mode">Themen-Modus ändern</string>
300 <string name="theme_mode_follow_system">System folgen</string> 327 <string name="theme_mode_follow_system">System folgen</string>
301 <string name="theme_mode_light">Hell</string> 328 <string name="theme_mode_light">Hell</string>
302 <string name="theme_mode_dark">Dunkel</string> 329 <string name="theme_mode_dark">Dunkel</string>
303 330
331 <!-- Audio output engines -->
332 <string name="cubeb">cubeb</string>
333
304 <!-- Black backgrounds theme --> 334 <!-- Black backgrounds theme -->
305 <string name="use_black_backgrounds">Schwarze Hintergünde verwenden</string> 335 <string name="use_black_backgrounds">Schwarze Hintergründe</string>
306 <string name="use_black_backgrounds_description">Bei Verwendung des dunklen Themes, schwarze Hintergründe verwenden.</string> 336 <string name="use_black_backgrounds_description">Bei Verwendung des dunklen Themes, schwarze Hintergründe verwenden.</string>
307 337
308</resources> 338 <!-- Picture-In-Picture -->
339 <string name="picture_in_picture">Bild im Bild</string>
340 <string name="pause">Pause</string>
341 <string name="mute">Stummschalten</string>
342 <string name="unmute">Ton aktivieren</string>
343
344 <!-- Licenses screen strings -->
345 <string name="licenses">Lizenzen</string>
346 <string name="license_fidelityfx_fsr_description">Hochwertiges Upscaling von AMD</string>
347 </resources>
diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml
index e5bdd5889..103ac6e65 100644
--- a/src/android/app/src/main/res/values-es/strings.xml
+++ b/src/android/app/src/main/res/values-es/strings.xml
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o keys no vienen incluidos.&lt;br /&gt;&lt;br /&gt;Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string> 4 <string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o claves no vienen incluidos.&lt;br /&gt;&lt;br /&gt;Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string>
5 <string name="emulation_notification_channel_name">Emulación activa</string> 5 <string name="emulation_notification_channel_name">Emulación activa</string>
6 <string name="emulation_notification_channel_description">Muestra una notificación persistente cuando la emulación está activa.</string> 6 <string name="emulation_notification_channel_description">Muestra una notificación persistente cuando la emulación está activa.</string>
7 <string name="emulation_notification_running">yuzu esta ejecutándose</string> 7 <string name="emulation_notification_running">yuzu esta ejecutándose</string>
@@ -25,6 +25,7 @@
25 <string name="back">Atrás</string> 25 <string name="back">Atrás</string>
26 <string name="add_games">Añadir Juegos</string> 26 <string name="add_games">Añadir Juegos</string>
27 <string name="add_games_description">Selecciona la carpeta de juegos</string> 27 <string name="add_games_description">Selecciona la carpeta de juegos</string>
28 <string name="step_complete">¡Completado!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Juegos</string> 31 <string name="home_games">Juegos</string>
@@ -37,7 +38,8 @@
37 <string name="add_games_warning">¿Omitir la selección de la carpeta de juegos?</string> 38 <string name="add_games_warning">¿Omitir la selección de la carpeta de juegos?</string>
38 <string name="add_games_warning_description">No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.</string> 39 <string name="add_games_warning_description">No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Buscar Juegos</string> 41 <string name="home_search_games">Buscar juegos</string>
42 <string name="search_settings">Buscar configuración</string>
41 <string name="games_dir_selected">Directorio de juegos seleccionado</string> 43 <string name="games_dir_selected">Directorio de juegos seleccionado</string>
42 <string name="install_prod_keys">Instalar prod.keys</string> 44 <string name="install_prod_keys">Instalar prod.keys</string>
43 <string name="install_prod_keys_description">Requerido para descifrar juegos</string> 45 <string name="install_prod_keys_description">Requerido para descifrar juegos</string>
@@ -58,15 +60,18 @@
58 <string name="warning_cancel">Cancelar</string> 60 <string name="warning_cancel">Cancelar</string>
59 <string name="install_amiibo_keys">Instalar clave de Amiiboo</string> 61 <string name="install_amiibo_keys">Instalar clave de Amiiboo</string>
60 <string name="install_amiibo_keys_description">Necesario para usar Amiibo en el juego</string> 62 <string name="install_amiibo_keys_description">Necesario para usar Amiibo en el juego</string>
61 <string name="invalid_keys_file">Archivo de claves inválido seleccionado</string> 63 <string name="invalid_keys_file">Archivo de claves seleccionado inválido</string>
62 <string name="install_keys_success">Claves instaladas correctamente</string> 64 <string name="install_keys_success">Claves instaladas correctamente</string>
63 <string name="reading_keys_failure">Error al leer las claves de cifrado</string> 65 <string name="reading_keys_failure">Error al leer las claves de cifrado</string>
66 <string name="install_prod_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.</string>
64 <string name="invalid_keys_error">Claves de cifrado no válidas</string> 68 <string name="invalid_keys_error">Claves de cifrado no válidas</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string> 70 <string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
67 <string name="install_gpu_driver">Instalar driver de GPU</string> 71 <string name="install_gpu_driver">Instalar driver de GPU</string>
68 <string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string> 72 <string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
69 <string name="advanced_settings">Opciones avanzadas</string> 73 <string name="advanced_settings">Opciones avanzadas</string>
74 <string name="advanced_settings_game">Configuración avanzada: %1$s</string>
70 <string name="settings_description">Configurar las opciones del emulador</string> 75 <string name="settings_description">Configurar las opciones del emulador</string>
71 <string name="search_recently_played">Jugado recientemente</string> 76 <string name="search_recently_played">Jugado recientemente</string>
72 <string name="search_recently_added">Añadido recientemente</string> 77 <string name="search_recently_added">Añadido recientemente</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">El nombre de la primera subcarpeta debe ser el Title ID del juego.</string> 91 <string name="save_file_invalid_zip_structure_description">El nombre de la primera subcarpeta debe ser el Title ID del juego.</string>
87 <string name="import_saves">Importar</string> 92 <string name="import_saves">Importar</string>
88 <string name="export_saves">Exportar</string> 93 <string name="export_saves">Exportar</string>
94 <string name="install_firmware">Instalar firmware</string>
95 <string name="install_firmware_description">El firmware debe estar en un archivo ZIP y es necesario para ejecutar algunos juegos</string>
96 <string name="firmware_installing">Instalando firmware</string>
97 <string name="firmware_installed_success">Firmware instalado con éxito</string>
98 <string name="firmware_installed_failure">Falló la instalación de firmware</string>
99 <string name="firmware_installed_failure_description">Asegúrese de que los archivos nca del firmware estén en la raíz del zip e inténtelo de nuevo.</string>
100 <string name="share_log">Compartir registros de depuración</string>
101 <string name="share_log_description">Comparta el archivo de registro de yuzu para depurar problemas</string>
102 <string name="share_log_missing">No se encontró ningún archivo de registro</string>
103 <string name="install_game_content">Instalar contenido de juego</string>
104 <string name="install_game_content_description">Instalar actualizaciones o DLC</string>
105 <string name="installing_game_content">Instalando contenido...</string>
106 <string name="install_game_content_failure">Error instalando archivo(s) a la NAND</string>
107 <string name="install_game_content_failure_description">Asegúrese de que el/los contenido(s) son válidos y que el archivo prod.keys esté instalado.</string>
108 <string name="install_game_content_failure_base">La instalación de los juegos base no está permitida para así evitar posibles conflictos.</string>
109 <string name="install_game_content_failure_file_extension">Sólo hay soporte para el contenido en NSP y XCI. Asegúrese de que el/los contenido(s) son válidos.</string>
110 <string name="install_game_content_failed_count">%1$d error(es) de instalación</string>
111 <string name="install_game_content_success">Contenido(s) de juego instalado/s con éxito</string>
112 <string name="install_game_content_success_install">%1$d instalado con éxito</string>
113 <string name="install_game_content_success_overwrite">%1$d sobreescrito con éxito</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">Drivers personalizados no soportados</string>
116 <string name="custom_driver_not_supported_description">En estos momentos, la carga de drivers personalizados no está disponible para este dispositivo..\n¡Comprueba esta opción en el futuro para ver si ya está añadido el soporte a ese dispositivo!</string>
117 <string name="manage_yuzu_data">Administrar datos de yuzu</string>
118 <string name="manage_yuzu_data_description">Importa/exporta el firmware, las keys, los datos de usuario, ¡y más!</string>
119 <string name="share_save_file">Compartir archivo de guardado</string>
120 <string name="export_save_failed">La exportación del guardado falló</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia no es real</string> 123 <string name="gaia_is_not_real">Gaia no es real</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">Contribuidores</string> 126 <string name="contributors">Contribuidores</string>
95 <string name="contributors_description">Hecho con \u2764 del equipo yuzu</string> 127 <string name="contributors_description">Hecho con \u2764 del equipo yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Proyectos que hacen que yuzu para Android sea una realidad</string>
97 <string name="build">Versión</string> 130 <string name="build">Versión</string>
131 <string name="user_data">Datos de usuario</string>
132 <string name="user_data_description">Importa/exporta todos los datos de usuario.\n\nCuando se importen los datos de usuario, ¡los demás datos de usuario existentes serán borrados!</string>
133 <string name="exporting_user_data">Exportando datos de usuario...</string>
134 <string name="importing_user_data">Importando datos de usuario...</string>
135 <string name="import_user_data">Importar datos de usuario</string>
136 <string name="invalid_yuzu_backup">Backup de válido</string>
137 <string name="user_data_export_success">Datos de usuario exportados con éxito</string>
138 <string name="user_data_import_success">Datos de usuario importados con éxito</string>
139 <string name="user_data_export_cancelled">Exportación cancelada</string>
140 <string name="user_data_import_failed_description">Asegúrese de que las carpetas de datos de usuario estén en la raíz de la carpeta del zip y contengan un archivo config en config/config.ini e inténtelo de nuevo.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
114 <string name="are_you_interested">¿Estás interesado?</string> 157 <string name="are_you_interested">¿Estás interesado?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">Activar limite de velocidad</string> 160 <string name="frame_limit_enable">Limitar velocidad</string>
118 <string name="frame_limit_enable_description">Cuando está habilitado, la velocidad de emulación se limitará a un porcentaje específico de la velocidad normal.</string> 161 <string name="frame_limit_enable_description">Limita la velocidad de emulación a un porcentaje específico de la velocidad normal.</string>
119 <string name="frame_limit_slider">Limitar porcentaje de velocidad</string> 162 <string name="frame_limit_slider">Limitar porcentaje de velocidad</string>
120 <string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. Con el valor predeterminado del 100 %, la emulación se limitará a la velocidad normal. Valores más altos o más bajos aumentarán o disminuirán el límite de velocidad.</string> 163 <string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. 100% es la velocidad normal. Valores más altos o bajos incrementarán o disminuirán el límite de velocidad.</string>
121 <string name="cpu_accuracy">Precisión de CPU</string> 164 <string name="cpu_accuracy">Precisión de CPU</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">Modo sobremesa</string> 168 <string name="use_docked_mode">Modo Sobremesa</string>
125 <string name="use_docked_mode_description">Emula en modo sobremesa, lo que aumenta la resolución perjudicando el rendimiento.</string> 169 <string name="use_docked_mode_description">Incrementa la resolución al coste de reducir el rendimiento. El Modo Portátil es usado cuando está desactivado, reduciendo la resolución y mejorando así el rendimiento.</string>
126 <string name="emulated_region">Región emulada</string> 170 <string name="emulated_region">Región emulada</string>
127 <string name="emulated_language">Idioma emulado</string> 171 <string name="emulated_language">Idioma emulado</string>
128 <string name="select_rtc_date">Seleccionar Fecha RTC</string> 172 <string name="select_rtc_date">Seleccionar fecha RTC</string>
129 <string name="select_rtc_time">Seleccionar Tiempo RTC</string> 173 <string name="select_rtc_time">Seleccionar tiempo RTC</string>
130 <string name="use_custom_rtc">Habilitar RTC Personalizado</string> 174 <string name="use_custom_rtc">RTC personalizado</string>
131 <string name="use_custom_rtc_description">Esta configuración le permite configurar un reloj de tiempo real personalizado diferente a la hora actual de su sistema</string> 175 <string name="use_custom_rtc_description">Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema.</string>
132 <string name="set_custom_rtc">Establecer RTC Personalizado</string> 176 <string name="set_custom_rtc">Configurar RTC personalizado</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Nivel de precisión</string> 179 <string name="renderer_accuracy">Nivel de precisión</string>
137 <string name="renderer_resolution">Resolución</string> 180 <string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
138 <string name="renderer_vsync">Modo VSync</string> 181 <string name="renderer_vsync">Modo VSync</string>
182 <string name="renderer_screen_layout">Orientación</string>
139 <string name="renderer_aspect_ratio">Relación de aspecto</string> 183 <string name="renderer_aspect_ratio">Relación de aspecto</string>
140 <string name="renderer_scaling_filter">Filtro de adaptación de ventana</string> 184 <string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
141 <string name="renderer_anti_aliasing">Metodo Anti Aliasing</string> 185 <string name="renderer_anti_aliasing">Método anti-aliasing</string>
142 <string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string> 186 <string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
143 <string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string> 187 <string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
144 <string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string> 188 <string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string>
145 <string name="renderer_asynchronous_shaders_description">Compila shaders de forma asincrónica, lo que reducirá los parones pero puede introducir fallos.</string> 189 <string name="renderer_asynchronous_shaders_description">Compila shaders de manera asíncrona, reduciendo los parones, pero puede introducir fallos.</string>
146 <string name="renderer_debug">Habilitar la depuración de gráficos</string> 190 <string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
147 <string name="renderer_debug_description">Cuando esté marcado, la API de gráficos entra en un modo de depuración más lento.</string> 191 <string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
148 <string name="use_disk_shader_cache">Usar caché de shaders en disco</string> 192 <string name="use_disk_shader_cache">Caché de shaders en disco</string>
149 <string name="use_disk_shader_cache_description">Reduzca los parones almacenando y cargando shaders generados en el disco.</string> 193 <string name="use_disk_shader_cache_description">Reduce los parones almacenando y cargando shaders generados.</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">Depuración de CPU</string>
198 <string name="cpu_debug_mode_description">Pone la CPU en un modo de depuración lento.</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
201 <string name="renderer_debug">Depuración de gráficos</string>
202 <string name="renderer_debug_description">Configura la API gráfica a un modo de depuración lento.</string>
203 <string name="fastmem">Fastmem</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">Motor de salida</string>
152 <string name="audio_volume">Volumen</string> 207 <string name="audio_volume">Volumen</string>
153 <string name="audio_volume_description">Especifica el volumen de la salida de audio.</string> 208 <string name="audio_volume_description">Especifica el volumen de la salida de audio.</string>
154 209
@@ -157,14 +212,24 @@
157 <string name="ini_saved">Configuración guardada</string> 212 <string name="ini_saved">Configuración guardada</string>
158 <string name="gameid_saved">Configuración guardada para %1$s</string> 213 <string name="gameid_saved">Configuración guardada para %1$s</string>
159 <string name="error_saving">Error guardando %1$s.ini: %2$s</string> 214 <string name="error_saving">Error guardando %1$s.ini: %2$s</string>
215 <string name="unimplemented_menu">Menú sin implementar</string>
160 <string name="loading">Cargando...</string> 216 <string name="loading">Cargando...</string>
217 <string name="shutting_down">Saliendo...</string>
161 <string name="reset_setting_confirmation">¿Desea restablecer esta configuración a su valor predeterminado?</string> 218 <string name="reset_setting_confirmation">¿Desea restablecer esta configuración a su valor predeterminado?</string>
162 <string name="reset_to_default">Restablecer a predeterminado</string> 219 <string name="reset_to_default">Restablecer a predeterminado</string>
163 <string name="reset_all_settings">¿Restablecer todas las configuraciones?</string> 220 <string name="reset_all_settings">¿Restablecer todas las configuraciones?</string>
164 <string name="reset_all_settings_description">Todas las configuraciones avanzadas se restablecerán a su configuración predeterminada. Esto no se puede deshacer.</string> 221 <string name="reset_all_settings_description">Todas las opciones avanzadas se restablecerán a su configuración predeterminada. Esta acción no se puede deshacer.</string>
165 <string name="settings_reset">Reiniciar la configuracion</string> 222 <string name="settings_reset">Reiniciar la configuracion</string>
166 <string name="close">Cerrar</string> 223 <string name="close">Cerrar</string>
167 <string name="learn_more">Más información</string> 224 <string name="learn_more">Saber más</string>
225 <string name="auto">Auto</string>
226 <string name="submit">Enviar</string>
227 <string name="string_null">Null</string>
228 <string name="string_import">Importar</string>
229 <string name="export">Exportar</string>
230 <string name="export_failed">La exportación falló</string>
231 <string name="import_failed">La importación falló</string>
232 <string name="cancelling">Cancelando</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Seleccionar driver GPU</string> 235 <string name="select_gpu_driver">Seleccionar driver GPU</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">Instalar</string> 237 <string name="select_gpu_driver_install">Instalar</string>
173 <string name="select_gpu_driver_default">Predeterminado</string> 238 <string name="select_gpu_driver_default">Predeterminado</string>
174 <string name="select_gpu_driver_use_default">Usando el driver de GPU por defecto </string> 239 <string name="select_gpu_driver_use_default">Usando el driver de GPU por defecto </string>
240 <string name="select_gpu_driver_error">¡Driver no válido, utilizando el predeterminado del sistema!</string>
175 <string name="system_gpu_driver">Driver GPU del sistema</string> 241 <string name="system_gpu_driver">Driver GPU del sistema</string>
176 <string name="installing_driver">Instalando driver...</string> 242 <string name="installing_driver">Instalando driver...</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">Gráficos</string> 248 <string name="preferences_graphics">Gráficos</string>
183 <string name="preferences_audio">Audio</string> 249 <string name="preferences_audio">Audio</string>
184 <string name="preferences_theme">Tema y color</string> 250 <string name="preferences_theme">Tema y color</string>
251 <string name="preferences_debug">Depuración</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">Su ROM está encriptada</string> 254 <string name="loader_error_encrypted">Su ROM está encriptada</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titulos instalados</a>.]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor, compruebe que su archivo <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado, para que los juegos sean descifrados.]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor, compruebe que su archivo <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado, para que los juegos sean descifrados.]]></string>
190 <string name="loader_error_video_core">Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionado</string> 257 <string name="loader_error_video_core">Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionado</string>
191 <string name="loader_error_video_core_description">Esto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.</string> 258 <string name="loader_error_video_core_description">Esto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.</string>
@@ -196,25 +263,25 @@
196 <string name="emulation_exit">Salir de la emulación</string> 263 <string name="emulation_exit">Salir de la emulación</string>
197 <string name="emulation_done">Hecho</string> 264 <string name="emulation_done">Hecho</string>
198 <string name="emulation_fps_counter">Contador de FPS</string> 265 <string name="emulation_fps_counter">Contador de FPS</string>
199 <string name="emulation_toggle_controls">Alternar Controles</string> 266 <string name="emulation_toggle_controls">Alternar controles</string>
200 <string name="emulation_rel_stick_center">Centro Relativo del Stick</string> 267 <string name="emulation_rel_stick_center">Centro relativo del stick</string>
201 <string name="emulation_dpad_slide">Deslizamiento de la Cruceta</string> 268 <string name="emulation_dpad_slide">Deslizamiento de la cruceta</string>
202 <string name="emulation_haptics">Hápticos</string> 269 <string name="emulation_haptics">Toques hápticos</string>
203 <string name="emulation_show_overlay">Mostrar pantalla</string> 270 <string name="emulation_show_overlay">Mostrar overlay</string>
204 <string name="emulation_toggle_all">Alternar Todo</string> 271 <string name="emulation_toggle_all">Alternar todo</string>
205 <string name="emulation_control_adjust">Ajustar pantalla</string> 272 <string name="emulation_control_adjust">Ajustar overlay</string>
206 <string name="emulation_control_scale">Escala</string> 273 <string name="emulation_control_scale">Escala</string>
207 <string name="emulation_control_opacity">Opacidad</string> 274 <string name="emulation_control_opacity">Opacidad</string>
208 <string name="emulation_touch_overlay_reset">Reiniciar pantalla</string> 275 <string name="emulation_touch_overlay_reset">Reiniciar overlay</string>
209 <string name="emulation_touch_overlay_edit">Editar pantalla</string> 276 <string name="emulation_touch_overlay_edit">Editar overlay</string>
210 <string name="emulation_pause">Pausar Emulación</string> 277 <string name="emulation_pause">Pausar emulación</string>
211 <string name="emulation_unpause">Reanudar Emulación</string> 278 <string name="emulation_unpause">Despausar emulación</string>
212 <string name="emulation_input_overlay">Opciones de pantalla </string> 279 <string name="emulation_input_overlay">Opciones de overlay</string>
213 280
214 <string name="load_settings">Cargando configuración...</string> 281 <string name="load_settings">Cargando configuración...</string>
215 282
216 <!-- Software keyboard --> 283 <!-- Software keyboard -->
217 <string name="software_keyboard">Software del teclado</string> 284 <string name="software_keyboard">Teclado de software</string>
218 285
219 <!-- Errors and warnings --> 286 <!-- Errors and warnings -->
220 <string name="abort_button">Abortar</string> 287 <string name="abort_button">Abortar</string>
@@ -226,6 +293,9 @@
226 <string name="fatal_error">Error fatal</string> 293 <string name="fatal_error">Error fatal</string>
227 <string name="fatal_error_message">Ocurrió un error fatal. Consulte el registro para obtener más detalles.\nContinuar con la emulación puede provocar bloqueos y errores.</string> 294 <string name="fatal_error_message">Ocurrió un error fatal. Consulte el registro para obtener más detalles.\nContinuar con la emulación puede provocar bloqueos y errores.</string>
228 <string name="performance_warning">¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada.</string> 295 <string name="performance_warning">¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada.</string>
296 <string name="device_memory_inadequate">RAM de dispositivo: %1$s\nRecomendado: %2$s</string>
297 <string name="memory_formatted">%1$s %2$s</string>
298 <string name="no_game_present">¡No hay ningún juego ejecutable presente!</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">Japón</string> 301 <string name="region_japan">Japón</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">Corea</string> 306 <string name="region_korea">Corea</string>
237 <string name="region_taiwan">Taiwán</string> 307 <string name="region_taiwan">Taiwán</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">KB</string>
312 <string name="memory_megabyte">MB</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">TB</string>
315 <string name="memory_petabyte">PB</string>
316 <string name="memory_exabyte">EB</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 319 <string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">Paisaje</string>
356 <string name="screen_layout_portrait">Retrato</string>
357 <string name="screen_layout_auto">Auto</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">Predeterminado (16:9)</string> 360 <string name="ratio_default">Predeterminado (16:9)</string>
279 <string name="ratio_force_four_three">Forzar 4:3</string> 361 <string name="ratio_force_four_three">Forzar 4:3</string>
@@ -298,7 +380,7 @@
298 <string name="building_shaders">Construyendo shaders</string> 380 <string name="building_shaders">Construyendo shaders</string>
299 381
300 <!-- Theme options --> 382 <!-- Theme options -->
301 <string name="change_app_theme">Cambiar Tema</string> 383 <string name="change_app_theme">Cambiar tema</string>
302 <string name="theme_default">Predeterminado</string> 384 <string name="theme_default">Predeterminado</string>
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
@@ -308,8 +390,22 @@
308 <string name="theme_mode_light">Claro</string> 390 <string name="theme_mode_light">Claro</string>
309 <string name="theme_mode_dark">Oscuro</string> 391 <string name="theme_mode_dark">Oscuro</string>
310 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
311 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Usar Fondos Negros</string> 397 <string name="use_black_backgrounds">Fondos oscuros</string>
313 <string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string> 398 <string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
314 399
315</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">Picture in Picture</string>
402 <string name="picture_in_picture_description">Minimizar ventana cuando esté en segundo plano</string>
403 <string name="pause">Pausar</string>
404 <string name="play">Jugar</string>
405 <string name="mute">Mutear</string>
406 <string name="unmute">Desmutear</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">Licencias</string>
410 <string name="license_fidelityfx_fsr_description">Upscaling de alta calidad de AMD</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml
index 1e02828aa..5a827c50b 100644
--- a/src/android/app/src/main/res/values-fr/strings.xml
+++ b/src/android/app/src/main/res/values-fr/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Ce logiciel exécutera des jeux pour la console de jeu Nintendo Switch. Aucun jeux ou clés n\'est inclus.&lt;br /&gt;&lt;br /&gt;Avant de commencer, veuillez localiser votre fichier <![CDATA[<b> prod.keys </b>]]> sur le stockage de votre appareil.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">En savoir plus</a>]]></string> 4 <string name="app_disclaimer">Ce logiciel exécutera des jeux pour la console de jeu Nintendo Switch. Aucun jeux ou clés n\'est inclus.&lt;br /&gt;&lt;br /&gt;Avant de commencer, veuillez localiser votre fichier <![CDATA[<b> prod.keys </b>]]> sur le stockage de votre appareil.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">En savoir plus</a>]]></string>
5 <string name="emulation_notification_channel_name">L\'émulation est active</string> 5 <string name="emulation_notification_channel_name">L\'émulation est active</string>
@@ -19,12 +19,13 @@
19 <string name="games">Jeux</string> 19 <string name="games">Jeux</string>
20 <string name="games_description">Sélectionnez votre dossier &lt;b>de Jeux&lt;/b> avec le bouton ci-dessous.</string> 20 <string name="games_description">Sélectionnez votre dossier &lt;b>de Jeux&lt;/b> avec le bouton ci-dessous.</string>
21 <string name="done">Terminé</string> 21 <string name="done">Terminé</string>
22 <string name="done_description">Vous êtes prêt.\nProfitez de vos jeux !</string> 22 <string name="done_description">Vous êtes prêt.\nProfitez de vos jeux !</string>
23 <string name="text_continue">Continuer</string> 23 <string name="text_continue">Continuer</string>
24 <string name="next">Suivant</string> 24 <string name="next">Suivant</string>
25 <string name="back">Retour</string> 25 <string name="back">Retour</string>
26 <string name="add_games">Ajouter des jeux</string> 26 <string name="add_games">Ajouter des jeux</string>
27 <string name="add_games_description">Sélectionner votre dossier de jeux</string> 27 <string name="add_games_description">Sélectionner le dossier des jeux</string>
28 <string name="step_complete">Terminé !</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Jeux</string> 31 <string name="home_games">Jeux</string>
@@ -32,12 +33,13 @@
32 <string name="home_settings">Paramètres</string> 33 <string name="home_settings">Paramètres</string>
33 <string name="empty_gamelist">Aucun fichier n\'a été trouvé ou aucun répertoire de jeu n\'a encore été sélectionné.</string> 34 <string name="empty_gamelist">Aucun fichier n\'a été trouvé ou aucun répertoire de jeu n\'a encore été sélectionné.</string>
34 <string name="search_and_filter_games">Rechercher et filtrer les jeux</string> 35 <string name="search_and_filter_games">Rechercher et filtrer les jeux</string>
35 <string name="select_games_folder">Sélectionner le dossier de jeux</string> 36 <string name="select_games_folder">Sélectionner le dossier des jeux</string>
36 <string name="select_games_folder_description">Permet à yuzu de remplir la liste des jeux</string> 37 <string name="select_games_folder_description">Permet à yuzu de remplir la liste des jeux</string>
37 <string name="add_games_warning">Ne pas sélectionner le dossier des jeux ?</string> 38 <string name="add_games_warning">Ne pas sélectionner le dossier des jeux ?</string>
38 <string name="add_games_warning_description">Les jeux ne seront pas affichés dans la liste des jeux si aucun dossier n\'est sélectionné.</string> 39 <string name="add_games_warning_description">Les jeux ne seront pas affichés dans la liste des jeux si aucun dossier n\'est sélectionné.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Rechercher des jeux</string> 41 <string name="home_search_games">Rechercher des jeux</string>
42 <string name="search_settings">Rechercher un paramètre</string>
41 <string name="games_dir_selected">Répertoire de jeux sélectionné</string> 43 <string name="games_dir_selected">Répertoire de jeux sélectionné</string>
42 <string name="install_prod_keys">Installer prod.keys</string> 44 <string name="install_prod_keys">Installer prod.keys</string>
43 <string name="install_prod_keys_description">Nécessaire pour décrypter les jeux commerciaux.</string> 45 <string name="install_prod_keys_description">Nécessaire pour décrypter les jeux commerciaux.</string>
@@ -46,7 +48,7 @@
46 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> 48 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
47 <string name="notifications">Notifications</string> 49 <string name="notifications">Notifications</string>
48 <string name="notifications_description">Accordez l\'autorisation de notification avec le bouton ci-dessous.</string> 50 <string name="notifications_description">Accordez l\'autorisation de notification avec le bouton ci-dessous.</string>
49 <string name="give_permission">Donner la permission</string> 51 <string name="give_permission">Accorder la permission</string>
50 <string name="notification_warning">Ne pas accorder la permission de notification ?</string> 52 <string name="notification_warning">Ne pas accorder la permission de notification ?</string>
51 <string name="notification_warning_description">yuzu ne pourra pas vous communiquer d\'informations importantes.</string> 53 <string name="notification_warning_description">yuzu ne pourra pas vous communiquer d\'informations importantes.</string>
52 <string name="permission_denied">Permission refusée</string> 54 <string name="permission_denied">Permission refusée</string>
@@ -61,12 +63,15 @@
61 <string name="invalid_keys_file">Fichier de clés sélectionné invalide</string> 63 <string name="invalid_keys_file">Fichier de clés sélectionné invalide</string>
62 <string name="install_keys_success">Clés installées avec succès</string> 64 <string name="install_keys_success">Clés installées avec succès</string>
63 <string name="reading_keys_failure">Erreur lors de la lecture des clés de chiffrement</string> 65 <string name="reading_keys_failure">Erreur lors de la lecture des clés de chiffrement</string>
66 <string name="install_prod_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .keys et réessayez.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .bin et réessayez.</string>
64 <string name="invalid_keys_error">Clés de chiffrement invalides</string> 68 <string name="invalid_keys_error">Clés de chiffrement invalides</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.</string> 70 <string name="install_keys_failure_description">Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.</string>
67 <string name="install_gpu_driver">Installer le pilote du GPU</string> 71 <string name="install_gpu_driver">Installer le pilote du GPU</string>
68 <string name="install_gpu_driver_description">Installez des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string> 72 <string name="install_gpu_driver_description">Installer des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string>
69 <string name="advanced_settings">Paramètres avancés</string> 73 <string name="advanced_settings">Paramètres avancés</string>
74 <string name="advanced_settings_game">Paramètres avancés : %1$s</string>
70 <string name="settings_description">Configurer les paramètres de l\'émulateur</string> 75 <string name="settings_description">Configurer les paramètres de l\'émulateur</string>
71 <string name="search_recently_played">Joué récemment</string> 76 <string name="search_recently_played">Joué récemment</string>
72 <string name="search_recently_added">Ajouté récemment</string> 77 <string name="search_recently_added">Ajouté récemment</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">Le nom du premier sous-dossier doit être l\'identifiant du titre du jeu.</string> 91 <string name="save_file_invalid_zip_structure_description">Le nom du premier sous-dossier doit être l\'identifiant du titre du jeu.</string>
87 <string name="import_saves">Importer</string> 92 <string name="import_saves">Importer</string>
88 <string name="export_saves">Exporter</string> 93 <string name="export_saves">Exporter</string>
94 <string name="install_firmware">Installer le firmware</string>
95 <string name="install_firmware_description">Le firmware doit être dans une archive ZIP et est nécessaire pour démarrer certains jeux.</string>
96 <string name="firmware_installing">Installation du firmware</string>
97 <string name="firmware_installed_success">Firmware installé avec succès</string>
98 <string name="firmware_installed_failure">L\'installation du firmware a échoué</string>
99 <string name="firmware_installed_failure_description">Assurez-vous que les fichiers NCA du firmware se trouvent à la racine du fichier ZIP, puis réessayez.</string>
100 <string name="share_log">Partager les logs de débogage</string>
101 <string name="share_log_description">Partagez le fichier de log de yuzu pour déboguer les problèmes.</string>
102 <string name="share_log_missing">Aucun fichier de log trouvé</string>
103 <string name="install_game_content">Installer le contenu du jeu</string>
104 <string name="install_game_content_description">Installer une mise à jour ou un DLC</string>
105 <string name="installing_game_content">Installation du contenu en cours...</string>
106 <string name="install_game_content_failure">Erreur lors de l\'installation du fichier dans la NAND</string>
107 <string name="install_game_content_failure_description">Veuillez vous assurer que le contenu est valide et que le fichier prod.keys est installé.</string>
108 <string name="install_game_content_failure_base">L\'installation de jeux de base n\'est pas autorisée afin d\'éviter d\'éventuels conflits.</string>
109 <string name="install_game_content_failure_file_extension">Seuls les contenus NSP et XCI sont pris en charge. Veuillez vérifier que le contenu du jeu est valide.</string>
110 <string name="install_game_content_failed_count">%1$d erreur(s) d\'installation</string>
111 <string name="install_game_content_success">Contenu du jeu installé avec succès</string>
112 <string name="install_game_content_success_install">%1$d installé avec succès</string>
113 <string name="install_game_content_success_overwrite">%1$d écrasé avec succès</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">Pilotes personnalisés non supporté</string>
116 <string name="custom_driver_not_supported_description">Le chargement des pilotes personnalisés ne sont pas actuellement pris en charge pour ce périphérique. Vérifiez à nouveau cette option à l\'avenir pour voir si la prise en charge a été ajoutée !</string>
117 <string name="manage_yuzu_data">Gérer les données de yuzu</string>
118 <string name="manage_yuzu_data_description">Importer/exporter le firmware, les clés, les données utilisateur, et bien plus encore !</string>
119 <string name="share_save_file">Partager le fichier de sauvegarde</string>
120 <string name="export_save_failed">Échec de l\'exportation de la sauvegarde</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia n\'est pas réel</string> 123 <string name="gaia_is_not_real">Gaia n\'est pas réel</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">Contributeurs</string> 126 <string name="contributors">Contributeurs</string>
95 <string name="contributors_description">Fait avec \u2764 de l\'équipe yuzu</string> 127 <string name="contributors_description">Fait avec \u2764 de l\'équipe yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Des projets qui rendent possible yuzu pour Android</string>
97 <string name="build">Build</string> 130 <string name="build">Build</string>
131 <string name="user_data">Données utilisateur</string>
132 <string name="user_data_description">Importer/exporter toutes les données de l\'application.\n\nLors de l\'importation des données utilisateur, toutes les données utilisateur existantes seront supprimées !</string>
133 <string name="exporting_user_data">Exportation des données utilisateur...</string>
134 <string name="importing_user_data">Importation des données utilisateur...</string>
135 <string name="import_user_data">Importer des données utilisateur</string>
136 <string name="invalid_yuzu_backup">Backup yuzu invalide</string>
137 <string name="user_data_export_success">Les données utilisateur ont été exportés avec succès</string>
138 <string name="user_data_import_success">Les données utilisateur ont été importées avec succès</string>
139 <string name="user_data_export_cancelled">Exportation annulée</string>
140 <string name="user_data_import_failed_description">Assurez-vous que les dossiers de données utilisateur se trouvent à la racine du dossier ZIP et contiennent un fichier de configuration à config/config.ini, puis réessayez.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,64 +157,87 @@
114 <string name="are_you_interested">Es tu intéressé ?</string> 157 <string name="are_you_interested">Es tu intéressé ?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">Activer la vitesse limite</string> 160 <string name="frame_limit_enable">Limitation de vitesse</string>
118 <string name="frame_limit_enable_description">Lorsqu\'elle est activée, la vitesse d\'émulation sera limitée à un pourcentage spécifié de la vitesse normale.</string> 161 <string name="frame_limit_enable_description">Limiter la vitesse d\'émulation à un pourcentage spécifié de la vitesse normale</string>
119 <string name="frame_limit_slider">Limite en pourcentage de vitesse</string> 162 <string name="frame_limit_slider">Limite en pourcentage de vitesse</string>
120 <string name="frame_limit_slider_description">Spécifie le pourcentage pour limiter la vitesse d\'émulation. Avec la valeur par défaut de 100%, l\'émulation sera limitée à la vitesse normale. Des valeurs supérieures ou inférieures augmenteront ou diminueront la limite de vitesse.</string> 163 <string name="frame_limit_slider_description">Spécifier le pourcentage pour limiter la vitesse d\'émulation. 100% correspond à la vitesse normale. Des valeurs plus élevées ou plus basses augmenteront ou diminueront la limite de vitesse.</string>
121 <string name="cpu_accuracy">Précision du CPU</string> 164 <string name="cpu_accuracy">Précision du CPU</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">Mode TV</string> 168 <string name="use_docked_mode">Mode TV</string>
125 <string name="use_docked_mode_description">Émuler en mode TV augmente la résolution au détriment des performances.</string> 169 <string name="use_docked_mode_description">Augmenter la résolution, ce qui diminue les performances. Le mode portable est utilisé lorsque la fonction est désactivée, ce qui réduit la résolution et améliore les performances.</string>
126 <string name="emulated_region">Région émulée</string> 170 <string name="emulated_region">Région émulée</string>
127 <string name="emulated_language">Langue émulée</string> 171 <string name="emulated_language">Langue émulée</string>
128 <string name="select_rtc_date">Sélectionner la date RTC</string> 172 <string name="select_rtc_date">Sélectionner la date RTC</string>
129 <string name="select_rtc_time">Sélectionner l\'heure RTC</string> 173 <string name="select_rtc_time">Sélectionner l\'heure RTC</string>
130 <string name="use_custom_rtc">Activer l\'horloge RTC personnalisée</string> 174 <string name="use_custom_rtc">RTC personnalisé</string>
131 <string name="use_custom_rtc_description">Ce paramètre vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string> 175 <string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
132 <string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string> 176 <string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Niveau de précision</string> 179 <string name="renderer_accuracy">Niveau de précision</string>
137 <string name="renderer_resolution">Résolution</string> 180 <string name="renderer_resolution">Résolution (Mode Portable/Mode TV)</string>
138 <string name="renderer_vsync">Mode VSync</string> 181 <string name="renderer_vsync">Mode VSync</string>
182 <string name="renderer_screen_layout">Orientation</string>
139 <string name="renderer_aspect_ratio">Format</string> 183 <string name="renderer_aspect_ratio">Format</string>
140 <string name="renderer_scaling_filter">Filtre de fenêtre adaptatif</string> 184 <string name="renderer_scaling_filter">Filtre de fenêtre adaptatif</string>
141 <string name="renderer_anti_aliasing">Méthode d\'anticrénelage :</string> 185 <string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
142 <string name="renderer_force_max_clock">Forcer la fréquence d\'horloge maximale (Adreno uniquement)</string> 186 <string name="renderer_force_max_clock">Forcer les fréquences maximales (Adreno uniquement)</string>
143 <string name="renderer_force_max_clock_description">Force le GPU à fonctionner au maximum d\'horloges possibles (les contraintes thermiques seront toujours appliquées).</string> 187 <string name="renderer_force_max_clock_description">Forcer le GPU à fonctionner à ses fréquences maximales possibles (les contraintes thermiques seront toujours appliquées).</string>
144 <string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string> 188 <string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string>
145 <string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone, ce qui réduira les saccades mais peut entraîner des problèmes visuels.</string> 189 <string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone, réduisant les saccades mais pouvant entraîner des problèmes visuels.</string>
146 <string name="renderer_debug">Activer le débogage des graphismes</string> 190 <string name="renderer_reactive_flushing">Utiliser le vidage réactif</string>
147 <string name="renderer_debug_description">Lorsque cette case est cochée, l\'API graphique entre dans un mode de débogage plus lent.</string> 191 <string name="renderer_reactive_flushing_description">Améliore la précision du rendu dans certains jeux au détriment des performances.</string>
148 <string name="use_disk_shader_cache">Utiliser les shader cache de disque</string> 192 <string name="use_disk_shader_cache">Utiliser les shader cache</string>
149 <string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant les shaders générés sur le disque.</string> 193 <string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant localement les shaders générés</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">Débogage du CPU</string>
198 <string name="cpu_debug_mode_description">Place le CPU en mode lent de débogage.</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
201 <string name="renderer_debug">Débogage des graphismes</string>
202 <string name="renderer_debug_description">Définit l\'API graphique en mode de débogage lent.</string>
203 <string name="fastmem">Fastmem</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">Moteur de sortie</string>
152 <string name="audio_volume">Volume</string> 207 <string name="audio_volume">Volume</string>
153 <string name="audio_volume_description">Spécifie le volume de la sortie audio.</string> 208 <string name="audio_volume_description">Spécifier le volume de la sortie audio.</string>
154 209
155 <!-- Miscellaneous --> 210 <!-- Miscellaneous -->
156 <string name="slider_default">Défaut</string> 211 <string name="slider_default">Par défaut</string>
157 <string name="ini_saved">Paramètres enregistrés</string> 212 <string name="ini_saved">Paramètres enregistrés</string>
158 <string name="gameid_saved">Paramètres enregistrés pour %1$s</string> 213 <string name="gameid_saved">Paramètres enregistrés pour %1$s</string>
159 <string name="error_saving">Erreur lors de l\'enregistrement de %1$s.ini: %2$s</string> 214 <string name="error_saving">Erreur lors de l\'enregistrement de %1$s.ini: %2$s</string>
215 <string name="unimplemented_menu">Menu non implémenté</string>
160 <string name="loading">Chargement...</string> 216 <string name="loading">Chargement...</string>
161 <string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string> 217 <string name="shutting_down">Extinction en cours...</string>
218 <string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string>
162 <string name="reset_to_default">Réinitialiser par défaut</string> 219 <string name="reset_to_default">Réinitialiser par défaut</string>
163 <string name="reset_all_settings">Réinitialiser tous les réglages ?</string> 220 <string name="reset_all_settings">Réinitialiser tous les réglages ?</string>
164 <string name="reset_all_settings_description">Tous les paramètres avancés seront réinitialisés à leur configuration par défaut. Ça ne peut pas être annulé.</string> 221 <string name="reset_all_settings_description">Tous les paramètres avancés seront réinitialisés à leur configuration par défaut. Ça ne peut pas être annulé.</string>
165 <string name="settings_reset">Paramètres réinitialisés</string> 222 <string name="settings_reset">Paramètres réinitialisés</string>
166 <string name="close">Fermer</string> 223 <string name="close">Fermer</string>
167 <string name="learn_more">Plus d\'informations</string> 224 <string name="learn_more">En savoir plus</string>
225 <string name="auto">Auto</string>
226 <string name="submit">Soumettre</string>
227 <string name="string_null">Nul</string>
228 <string name="string_import">Importer</string>
229 <string name="export">Exporter</string>
230 <string name="export_failed">L\'exportation a échoué</string>
231 <string name="import_failed">L\'importation a échoué</string>
232 <string name="cancelling">Annulation</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Sélectionner le pilote du GPU</string> 235 <string name="select_gpu_driver">Sélectionner le pilote du GPU</string>
171 <string name="select_gpu_driver_title">Souhaitez vous remplacer votre pilote actuel ?</string> 236 <string name="select_gpu_driver_title">Souhaitez vous remplacer votre pilote actuel ?</string>
172 <string name="select_gpu_driver_install">Installer</string> 237 <string name="select_gpu_driver_install">Installer</string>
173 <string name="select_gpu_driver_default">Défaut</string> 238 <string name="select_gpu_driver_default">Par défaut</string>
174 <string name="select_gpu_driver_use_default">Utilisation du pilote de GPU par défaut</string> 239 <string name="select_gpu_driver_use_default">Utilisation du pilote du GPU par défaut</string>
240 <string name="select_gpu_driver_error">Pilote non valide sélectionné, utilisation du paramètre par défaut du système !</string>
175 <string name="system_gpu_driver">Pilote du GPU du système</string> 241 <string name="system_gpu_driver">Pilote du GPU du système</string>
176 <string name="installing_driver">Installation du pilote...</string> 242 <string name="installing_driver">Installation du pilote...</string>
177 243
@@ -182,13 +248,14 @@
182 <string name="preferences_graphics">Vidéo</string> 248 <string name="preferences_graphics">Vidéo</string>
183 <string name="preferences_audio">Audio</string> 249 <string name="preferences_audio">Audio</string>
184 <string name="preferences_theme">Thème et couleur</string> 250 <string name="preferences_theme">Thème et couleur</string>
251 <string name="preferences_debug">Débogage</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">Votre ROM est cryptée</string> 254 <string name="loader_error_encrypted">Votre ROM est cryptée</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Veuillez suivre les guides pour redumper vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartouches de jeu</a> ou <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titres installés</a>.]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[Veuillez suivre les guides pour refaire un dump de vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartouches de jeu</a> ou de vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">titres installés</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Veuillez vous assurer que votre fichier <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> est installé pour que les jeux puissent être déchiffrés.]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[Veuillez vous assurer que votre fichier <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> est installé pour que les jeux puissent être déchiffrés.]]></string>
190 <string name="loader_error_video_core">Une erreur s\'est produite lors de l\'initialisation du noyau vidéo</string> 257 <string name="loader_error_video_core">Une erreur s\'est produite lors de l\'initialisation du noyau vidéo</string>
191 <string name="loader_error_video_core_description">Cela est généralement dû à un pilote du GPU incompatible. L\'installation d\'un pilote du GPU personnalisé peut résoudre ce problème.</string> 258 <string name="loader_error_video_core_description">Cela est généralement dû à un pilote GPU incompatible. L\'installation d\'un pilote GPU personnalisé peut résoudre ce problème.</string>
192 <string name="loader_error_invalid_format">Impossible de charger la ROM</string> 259 <string name="loader_error_invalid_format">Impossible de charger la ROM</string>
193 <string name="loader_error_file_not_found">Le fichier ROM n\'existe pas</string> 260 <string name="loader_error_file_not_found">Le fichier ROM n\'existe pas</string>
194 261
@@ -198,8 +265,8 @@
198 <string name="emulation_fps_counter">Compteur FPS</string> 265 <string name="emulation_fps_counter">Compteur FPS</string>
199 <string name="emulation_toggle_controls">Activer/Désactiver les contrôles</string> 266 <string name="emulation_toggle_controls">Activer/Désactiver les contrôles</string>
200 <string name="emulation_rel_stick_center">Centre du stick relatif</string> 267 <string name="emulation_rel_stick_center">Centre du stick relatif</string>
201 <string name="emulation_dpad_slide">Glissement du DPad</string> 268 <string name="emulation_dpad_slide">Glissement du D-pad</string>
202 <string name="emulation_haptics">Haptique</string> 269 <string name="emulation_haptics">Toucher haptique</string>
203 <string name="emulation_show_overlay">Afficher l\'overlay</string> 270 <string name="emulation_show_overlay">Afficher l\'overlay</string>
204 <string name="emulation_toggle_all">Tout basculer</string> 271 <string name="emulation_toggle_all">Tout basculer</string>
205 <string name="emulation_control_adjust">Ajuster l\'overlay</string> 272 <string name="emulation_control_adjust">Ajuster l\'overlay</string>
@@ -225,7 +292,10 @@
225 <string name="save_load_error">Erreur de sauvegarde/chargement</string> 292 <string name="save_load_error">Erreur de sauvegarde/chargement</string>
226 <string name="fatal_error">Erreur fatale</string> 293 <string name="fatal_error">Erreur fatale</string>
227 <string name="fatal_error_message">Une erreur fatale s\'est produite. Consultez les logs pour plus de détails.\nContinuer l\'émulation peut entraîner des plantages et des bogues.</string> 294 <string name="fatal_error_message">Une erreur fatale s\'est produite. Consultez les logs pour plus de détails.\nContinuer l\'émulation peut entraîner des plantages et des bogues.</string>
228 <string name="performance_warning">La désactivation de ce paramètre réduira considérablement les performances d\'émulation ! Pour une expérience optimale, il est recommandé de laisser ce paramètre activé.</string> 295 <string name="performance_warning">La désactivation de ce paramètre réduira considérablement les performances d\'émulation ! Pour une expérience optimale, il est recommandé de laisser ce paramètre activé.</string>
296 <string name="device_memory_inadequate">Mémoire RAM de l\'appareil : %1$s\nRecommandé : %2$s</string>
297 <string name="memory_formatted">%1$s %2$s</string>
298 <string name="no_game_present">Aucun jeu démarreable présent !</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">Japon</string> 301 <string name="region_japan">Japon</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">Corée</string> 306 <string name="region_korea">Corée</string>
237 <string name="region_taiwan">Taïwan</string> 307 <string name="region_taiwan">Taïwan</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Octet</string>
311 <string name="memory_kilobyte">Ko</string>
312 <string name="memory_megabyte">Mo</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">To</string>
315 <string name="memory_petabyte">Po</string>
316 <string name="memory_exabyte">Eo</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 319 <string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">Paysage</string>
356 <string name="screen_layout_portrait">Portrait</string>
357 <string name="screen_layout_auto">Auto</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">Par défaut (16:9)</string> 360 <string name="ratio_default">Par défaut (16:9)</string>
279 <string name="ratio_force_four_three">Forcer le 4:3</string> 361 <string name="ratio_force_four_three">Forcer le 4:3</string>
@@ -288,8 +370,8 @@
288 370
289 <!-- Gamepad Buttons --> 371 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">Pavé directionnel</string> 372 <string name="gamepad_d_pad">Pavé directionnel</string>
291 <string name="gamepad_left_stick">Stick Gauche</string> 373 <string name="gamepad_left_stick">Stick gauche</string>
292 <string name="gamepad_right_stick">Stick Droit</string> 374 <string name="gamepad_right_stick">Stick droit</string>
293 <string name="gamepad_home">Home</string> 375 <string name="gamepad_home">Home</string>
294 <string name="gamepad_screenshot">Capture d\'écran</string> 376 <string name="gamepad_screenshot">Capture d\'écran</string>
295 377
@@ -299,7 +381,7 @@
299 381
300 <!-- Theme options --> 382 <!-- Theme options -->
301 <string name="change_app_theme">Changer le thème de l\'application</string> 383 <string name="change_app_theme">Changer le thème de l\'application</string>
302 <string name="theme_default">Défaut</string> 384 <string name="theme_default">Par défaut</string>
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
305 <!-- Theme Modes --> 387 <!-- Theme Modes -->
@@ -308,8 +390,22 @@
308 <string name="theme_mode_light">Lumineux</string> 390 <string name="theme_mode_light">Lumineux</string>
309 <string name="theme_mode_dark">Sombre</string> 391 <string name="theme_mode_dark">Sombre</string>
310 392
311 <!-- Black backgrounds theme --> 393 <!-- Audio output engines -->
312 <string name="use_black_backgrounds">Utiliser des arrière-plans noirs</string> 394 <string name="cubeb">cubeb</string>
313 <string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer des arrière-plans noirs.</string>
314 395
315</resources> 396 <!-- Black backgrounds theme -->
397 <string name="use_black_backgrounds">Arrière-plan noir</string>
398 <string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer un arrière-plan noir.</string>
399
400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">Lecteur réduit</string>
402 <string name="picture_in_picture_description">Réduire la fenêtre lorsqu\'elle est placée en arrière-plan</string>
403 <string name="pause">Pause</string>
404 <string name="play">Jouer</string>
405 <string name="mute">Couper le son</string>
406 <string name="unmute">Remettre le son</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">Licences</string>
410 <string name="license_fidelityfx_fsr_description">Mise à l\'échelle de haute qualité par AMD.</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml
new file mode 100644
index 000000000..0af78a57c
--- /dev/null
+++ b/src/android/app/src/main/res/values-he/strings.xml
@@ -0,0 +1,367 @@
1<?xml version="1.0" encoding="utf-8"?>
2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3
4 <string name="app_disclaimer">התוכנה תריץ ×ž×©×—×§×™× ×œ×§×•× ×¡×•×œ×ª ×” Nintendo Switch. ××£ משחק ×ו ×§×‘×¦×™× ×‘×¢×œ×™ זכויות ×™×•×¦×¨×™× × ×›×œ×œ×™×.&lt;br /&gt;&lt;br /&gt; לפני ש×ת/×” מתחיל בבקשה ×ž×¦× ×ת קובץ <![CDATA[<b>prod.keys</b>]]> על המכשיר.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">×§×¨× ×¢×•×“</a>]]></string>
5 <string name="emulation_notification_channel_name">×מולציה פעילה</string>
6 <string name="emulation_notification_channel_description">מציג התר××” מתמשכת ×›×שר ×”×מולציה פועלת.</string>
7 <string name="emulation_notification_running">yuzu רץ</string>
8 <string name="notice_notification_channel_name">התר×ות ותקלות</string>
9 <string name="notice_notification_channel_description">מציג התר×ות ×›×שר משהו הולך ×œ× ×›×©×•×¨×”.</string>
10 <string name="notification_permission_not_granted">הרש×ות התר×ות ×œ× × ×™×ª× ×”!</string>
11
12 <!-- Setup strings -->
13 <string name="welcome">×‘×¨×•×›×™× ×”×‘××™×!</string>
14 <string name="welcome_description">למד ×יך להפעיל &lt;b>yuzu&lt;/b> וקפוץ ישר ל×מולציה.</string>
15 <string name="get_started">כדי להתחיל</string>
16 <string name="keys">מפתחות</string>
17 <string name="keys_description">בחר ×ת קובץ ×” &lt;b>prod.keys&lt;/b> שלך ×¢× ×”×›×¤×ª×•×¨ למטה.</string>
18 <string name="select_keys">בחר מפתחות</string>
19 <string name="games">משחקי×</string>
20 <string name="games_description">בחר ×ת התיקיית ×” &lt;b>Games&lt;/b> שלך ×¢× ×”×›×¤×ª×•×¨ למטה.</string>
21 <string name="done">סיו×</string>
22 <string name="done_description">×ת/×” מוכן. \nתהנה/×™ ×ž×”×ž×©×—×§×™× ×©×œ×š </string>
23 <string name="text_continue">המשך</string>
24 <string name="next">הב×</string>
25 <string name="back">×חורה</string>
26 <string name="add_games">הוסף משחקי×</string>
27 <string name="add_games_description">בחר/×™ ×ת תיקיית ×”×ž×©×—×§×™× ×©×œ×š</string>
28 <string name="step_complete">הושל×!</string>
29
30 <!-- Home strings -->
31 <string name="home_games">משחקי×</string>
32 <string name="home_search">חפש</string>
33 <string name="home_settings">הגדרות</string>
34 <string name="empty_gamelist">×œ× × ×ž×¦×ו ×§×‘×¦×™× ×ו לנבחרה ספריית ×§×‘×¦×™× ×‘×™× ×ª×™×™×.</string>
35 <string name="search_and_filter_games">חפש וסנן משחקי×</string>
36 <string name="select_games_folder">בחר תיקיית משחקי×</string>
37 <string name="select_games_folder_description">×פשר ל yuzu ל×כלס ×ת רשימת המשחקי×</string>
38 <string name="add_games_warning">לדלג על בחירת תיקיית המשחקי×?</string>
39 <string name="add_games_warning_description">×ž×©×—×§×™× ×œ× ×™×•×¦×’×• ברשימת ×”×ž×©×—×§×™× ×× ×œ× ×‘×—×¨×” תיקיית משחקי×.</string>
40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
41 <string name="home_search_games">חפש משחקי×</string>
42 <string name="search_settings">חפש בהגדרות</string>
43 <string name="games_dir_selected">ספריית ×ž×©×—×§×™× × ×‘×—×¨×”</string>
44 <string name="install_prod_keys">התקן prod.keys</string>
45 <string name="install_prod_keys_description">הכרחי בכדי לפענח משחקי×</string>
46 <string name="install_prod_keys_warning">לדלג על הוספת מפתחות?</string>
47 <string name="install_prod_keys_warning_description">מפתחות ×—×•×§×™×™× ×”×›×¨×—×™×™× ×›×“×™ לשחק במשחקי×. רק ×פליקציות פירטיות יפעלו ×× ×ª×ž×©×™×š.</string>
48 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
49 <string name="notifications">התר×ות</string>
50 <string name="notifications_description">תן גישה להתר×ות ×¢× ×”×›×¤×ª×•×¨ למטה.</string>
51 <string name="give_permission">תן הרש××”</string>
52 <string name="notification_warning">דלג על מתן הרש××” להתר×ות?</string>
53 <string name="notification_warning_description">yuzu ×œ× ×™×•×›×œ להתריע לך על מידע חשוב.</string>
54 <string name="permission_denied">הרש××” נדחתה</string>
55 <string name="permission_denied_description">×ת/×” דיחת ×ת ההרש××” יותר מדי ×¤×¢×ž×™× ×•×¢×›×©×™×• ×ת/×” צריך/×” לתת גישה ב×ופן ידני בהגדרות.</string>
56 <string name="about">×ודות</string>
57 <string name="about_description">מספר גירסה, ×§×¨×“×™×˜×™× ×•×¢×•×“</string>
58 <string name="warning_help">עזרה</string>
59 <string name="warning_skip">דלג</string>
60 <string name="warning_cancel">ביטול</string>
61 <string name="install_amiibo_keys">התקן מפתחות Amiibo</string>
62 <string name="install_amiibo_keys_description">נחוץ כדי להשתמש ב Amiibo במשחק</string>
63 <string name="invalid_keys_file">קובץ מפתחות ×œ× ×—×•×§×™ נבחר</string>
64 <string name="install_keys_success">מפתחות הותקנו בהצלחה</string>
65 <string name="reading_keys_failure">שגי××” בקרי×ת מפתחות ההצפנה</string>
66 <string name="install_prod_keys_failure_extension_description">×•×“× ×©×œ×§×•×‘×¥ המפתחות שלך יש סיומת של key. ונסה/×™ שוב.</string>
67 <string name="install_amiibo_keys_failure_extension_description">וד×/×™ שלקובץ המפתחות שלך יש סיומת של bin. ונסה/×™ שוב.</string>
68 <string name="invalid_keys_error">מפתחות הצפנה ×œ× ×—×•×§×™×™×</string>
69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
70 <string name="install_keys_failure_description">קבוץ שנבחר מושחת ×ו ×œ× × ×›×•×Ÿ. בבקשה ×”×•×¦× ×ž×—×“×© ×ת המפתחות שלך.</string>
71 <string name="install_gpu_driver">התקן דרייבר למעבד הגרפי</string>
72 <string name="install_gpu_driver_description">התקן ×“×¨×™×™×‘×¨×™× ××—×¨×™× ×‘×©×‘×™×œ סיכוי ×œ×‘×™×¦×•×¢×™× ×ו דיוק ×’×‘×•×”×”×™× ×™×•×ª×¨</string>
73 <string name="advanced_settings">הגדרות מתקדמות</string>
74 <string name="advanced_settings_game">הגדרות מתקדמות: %1$s</string>
75 <string name="settings_description">הדר ×ת הגדרות ×”×מולטור</string>
76 <string name="search_recently_played">שוחק ל×חרונה</string>
77 <string name="search_recently_added">הוסף ל×חרונה</string>
78 <string name="search_retail">קמעונ××™</string>
79 <string name="search_homebrew">Homebrew</string>
80 <string name="open_user_folder">פתח ×ת תיקיית yuzu </string>
81 <string name="open_user_folder_description">× ×” ל ×ת ×”×§×‘×¦×™× ×”×¤× ×™×ž×™×™×Ÿ של yuzu</string>
82 <string name="theme_and_color_description">ערוך ×ת נר×ות ×”×פליקציה</string>
83 <string name="no_file_manager">×œ× × ×ž×¦× ×ž× ×”×œ קבצי×</string>
84 <string name="notification_no_directory_link">×œ× ×™×›×•×œ לפתוח ×ת ספריית yuzu</string>
85 <string name="notification_no_directory_link_description">בבקשה ×ž×§× ×ת תיקיית המשתמש בפנל הצידי של מנהל ×”×§×‘×¦×™× ×‘×ופן ידני.</string>
86 <string name="manage_save_data">נהל מידע שמור</string>
87 <string name="manage_save_data_description">מידע שמור ×œ× × ×ž×¦×. בבקשה בחר/×™ ×ופציה מלמטה</string>
88 <string name="import_export_saves_description">×™×‘× ×ו ×™×¦× ×§×‘×¦×™ שמירה</string>
89 <string name="save_file_imported_success">×™×•×‘× ×‘×”×¦×œ×—×”</string>
90 <string name="save_file_invalid_zip_structure">מבנה ספריית השמירות ×œ× ×—×•×§×™</string>
91 <string name="save_file_invalid_zip_structure_description">התת תיקייה הר×שונה חייב להיות ×” title ID של המשחק</string>
92 <string name="import_saves">ייבו×</string>
93 <string name="export_saves">ייצו×</string>
94 <string name="install_firmware">התקן firmware</string>
95 <string name="install_firmware_description">×” frimware חייב להיות בקובץ zip ×•×”×•× ×”×›×¨×—×™ להפעלת חלק מהמשחקי×</string>
96 <string name="firmware_installing">מתקין frimware</string>
97 <string name="firmware_installed_success">ה frimware הותקן בהצלחה</string>
98 <string name="firmware_installed_failure">התקנת ה frimware נכשלה</string>
99 <string name="firmware_installed_failure_description">×•×“× ×©×§×‘×¦×™ ×” firmware nca נמצ××™× ×‘×©×•×¨×© ×” zip ונסה שוב.</string>
100 <string name="share_log">שתף ×ת יומני ×”×¨×™×©×•× ×©×œ מיפוי הב××’×™×</string>
101 <string name="share_log_description">שתף ×ת קובץ יומני ×”×¨×™×©×•× ×©×œ yuzu בכדי לתקן בעיות</string>
102 <string name="share_log_missing">×œ× × ×ž×¦× ×§×•×‘×¥ יומן רישו×</string>
103 <string name="install_game_content">התקן תוכן משחק</string>
104 <string name="install_game_content_description">התקן עדכוני משחק ×ו DLC</string>
105 <string name="installing_game_content">מתקין תוכן...</string>
106 <string name="install_game_content_failure">תקלה בהתקנת הקובץ (×ו קבצי×) ל NAND</string>
107 <string name="install_game_content_failure_description">בבקשה ×•×“× ×©×”×ª×•×›×Ÿ (×ו תכני×) ×—×•×§×™×™× ×•×©×§×•×‘×¥ ×” prod.keys מותקן.</string>
108 <string name="install_game_content_failure_base">התקנת משחק בסיס נדחת בכדי להימנע ×ž×§×•× ×¤×œ×™×§×˜×™× ×פשריי×.</string>
109 <string name="install_game_content_failure_file_extension">רק קבצי NSP ו XCI נתמכי×. בבקשה ×•×“× ×©×ª×•×›×Ÿ (×ו תכני×) המשחק חוקי.</string>
110 <string name="install_game_content_failed_count">%1$dבעיה (בעיות) התקנה</string>
111 <string name="install_game_content_success">תוכן (×ו תכני) המשחק הותקנו בהצלחה</string>
112 <string name="install_game_content_success_install">%1$d הותקן בהצלחה</string>
113 <string name="install_game_content_success_overwrite">%1$d נדרס/נכתב מעל בהצלחה</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">×“×¨×™×™×‘×¨×™× ×ž×•×ª××ž×™× ×ישית ×œ× × ×ª×ž×›×™×</string>
116 <string name="custom_driver_not_supported_description">הטענת ×“×¨×™×™×‘×™× ×ž×•×ª××ž×™× ×ישית ×œ× × ×ª×ž×š כרגע על מכשיר ×–×”. \nבבקשה בדוק ×ופציה זו בעתיד בכדי לר×ות ×× × ×•×¡×¤×” תמיכה!</string>
117 <string name="manage_yuzu_data">נהל ×ת המידע של yuzu</string>
118 <string name="manage_yuzu_data_description">יב×/×™×¦× firmware, keys, מידע של משתמש ועוד!</string>
119 <string name="share_save_file">שתף קובץ שמירה</string>
120 <string name="export_save_failed">נכשל ×‘×™×™×¦×•× ×©×ž×™×¨×”</string>
121
122 <!-- About screen strings -->
123 <string name="gaia_is_not_real">Gaia ×œ× ×מיתית</string>
124 <string name="copied_to_clipboard">הועתק ללוח</string>
125 <string name="about_app_description">×מולטור Switch ×¢× ×§×•×“ פתוח</string>
126 <string name="contributors">תורמי×</string>
127 <string name="contributors_description">נוצר ×¢× \u2764 מקבוצת yuzu</string>
128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">×¤×¨×•×™×™×§×˜×™× ×©×”×•×¤×›×™× ×ת yuzu ל Android ×פשרי</string>
130 <string name="build">גרסה</string>
131 <string name="user_data">נתוני משתמש</string>
132 <string name="user_data_description">יב×/×™×¦× ×ת כל נתוני ×”×פליקציה.\n\n×›×שר מייב××™× ×ת נתוני המשתמש, כל נתוני המשתמש ×”×§×™×™×ž×™× ×™×ž×—×§×•!</string>
133 <string name="exporting_user_data">×ž×™×™×¦× × ×ª×•× ×™ משתמש...</string>
134 <string name="importing_user_data">×ž×™×™×‘× × ×ª×•× ×™ משתמש...</string>
135 <string name="import_user_data">×™×‘× × ×ª×•× ×™ משתמש</string>
136 <string name="invalid_yuzu_backup">גיבוי yuzu ×œ× ×—×•×§×™</string>
137 <string name="user_data_export_success">נתוני משתמש יוצ×ו בהצלחה</string>
138 <string name="user_data_import_success">נתוני משתמש יוב×ו בהצלחה</string>
139 <string name="user_data_export_cancelled">×™×™×¦×•× ×‘×•×˜×œ</string>
140 <string name="user_data_import_failed_description">×•×“× ×©× ×ª×•× ×™ המשתמש נמצ××™× ×‘×©×•×¨×© קובץ ×” zip ×•×©×”×•× ×ž×›×™×œ קובץ סידור ב config/config.ini ונסה שוב.</string>
141 <string name="support_link">https://discord.gg/u77vRWY</string>
142 <string name="website_link">https://yuzu-emu.org/</string>
143 <string name="github_link">https://github.com/yuzu-emu</string>
144
145 <!-- Early access upgrade strings -->
146 <string name="early_access">גישה מוקדמת</string>
147 <string name="get_early_access">קבל גישה מוקדמת</string>
148 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
149 <string name="get_early_access_description">תכונות חותכות קצה, גישה מוקדמת לעדכוני×, ועוד</string>
150 <string name="early_access_benefits">יתרונות של גישה מקודמת</string>
151 <string name="cutting_edge_features">תכונות חותכות קצה</string>
152 <string name="early_access_updates">גישה מוקדמת לעדכוני×</string>
153 <string name="no_manual_installation">×œ×œ× ×”×ª×§× ×” ידנית</string>
154 <string name="prioritized_support">תמיכה בעדיפות</string>
155 <string name="helping_game_preservation">עוזר בשמירת משחקי×</string>
156 <string name="our_eternal_gratitude">התודה ×”×ינסופית שלנו</string>
157 <string name="are_you_interested">×תה מעוניין?</string>
158
159 <!-- General settings strings -->
160 <string name="frame_limit_enable">הגבל מהירות</string>
161 <string name="frame_limit_enable_description">מגביל ×ת מהירות ×”×מולציה ל×חוז מהירות המבוקש מהמהירות הרגילה.</string>
162 <string name="frame_limit_slider">הגבל ×ת ×חוז המהירות</string>
163 <string name="frame_limit_slider_description">מדייק ×ת ×חוז מהירות ×”×מולציה. 100% ×–×” מהירות רגילה. ×¢×¨×›×™× ×’×“×•×œ×™× ×ו ×§×˜× ×™× ×™×יצו ×ו ×™×טו ×ת מהירות ×”×מולציה.</string>
164 <string name="cpu_accuracy">דיוק המעבד</string>
165 <string name="value_with_units">%1$s%2$s</string>
166
167 <!-- System settings strings -->
168 <string name="use_docked_mode">מצב עגינה</string>
169 <string name="use_docked_mode_description">מעלה ×ת הרזולוציה, פוגע בביצועי×. משתמש במצב נייד ×›×שר מנוטרל, מפחית ×ת הרזולוציה ומעלה ×ת הביצועי×.</string>
170 <string name="emulated_region">×זור ×מולציה</string>
171 <string name="emulated_language">שפת ×מולציה</string>
172 <string name="select_rtc_date">בחר ת×ריך RTC</string>
173 <string name="select_rtc_time">בחר זמן RTC</string>
174 <string name="use_custom_rtc">RTC מות×× ×ישית</string>
175 <string name="use_custom_rtc_description">מ×פשר לך לקבוע שעון זמן ×מת נפרד משעון המערכת שלך.</string>
176 <string name="set_custom_rtc">קבע RTC מות×× ×ישית</string>
177
178 <!-- Graphics settings strings -->
179 <string name="renderer_accuracy">רמת דיוק</string>
180 <string name="renderer_resolution">רזולוציה (מעוגן/נייד)</string>
181 <string name="renderer_vsync">מצב VSync</string>
182 <string name="renderer_screen_layout">כיוון</string>
183 <string name="renderer_aspect_ratio">יחס רוחב גובה</string>
184 <string name="renderer_scaling_filter">פילטר מת×× ×—×œ×•×Ÿ</string>
185 <string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
186 <string name="renderer_force_max_clock">החזק מהירות שעון מקסימלית (רק ל Adreno)</string>
187 <string name="renderer_force_max_clock_description">מכריח לדחוף ×ת מהירויות המעבד הגרפי ×œ×ž×§×¡×™×ž×•× (הגבלות ×—×•× ×™×ž×©×™×›×• לתפקד).</string>
188 <string name="renderer_reactive_flushing_description">משפר ×ת הדיוק של ×”×מולציה ×‘×ž×©×—×§×™× ×ž×¡×•×™×™×ž×™× ×‘×ž×—×™×¨ של ביצועי×.</string>
189 <!-- Debug settings strings -->
190 <string name="cpu">מעבד</string>
191 <string name="cpu_debug_mode_description">מכניס ×ת המעבד למצב דיב××’ ×יטי</string>
192 <string name="gpu">מעבד גרפי</string>
193 <!-- Audio settings strings -->
194 <string name="audio_output_engine">מנוע פלט</string>
195 <string name="audio_volume">עוצמת שמע</string>
196 <!-- Miscellaneous -->
197 <string name="slider_default">ברירת מחדל</string>
198 <string name="ini_saved">הגדרות שמורות</string>
199 <string name="gameid_saved">הגדרות שמורות עבור %1$s</string>
200 <string name="error_saving">תקלה בשמירת %1$s.ini: %2$s</string>
201 <string name="loading">טוען...</string>
202 <string name="shutting_down">כיבוי...</string>
203 <string name="reset_setting_confirmation">×תה מעוניין ל×פס ×ת ההגדרה הזו חזרה לברירת המחדל?</string>
204 <string name="reset_to_default">×פס לברירת המחדל</string>
205 <string name="reset_all_settings">ל×פס ×ת כל ההגדרות?</string>
206 <string name="reset_all_settings_description">כל ההגדרות המתקדמות ×™×ופסו לברירת המחדל. ×œ× × ×™×ª×Ÿ לבטל פעולה זו.</string>
207 <string name="settings_reset">×פס הגדרות</string>
208 <string name="close">סגור</string>
209 <string name="learn_more">למד עוד</string>
210 <string name="auto">×וטומטי</string>
211 <string name="submit">שלח</string>
212 <string name="string_import">ייבו×</string>
213 <string name="export">ייצו×</string>
214 <string name="export_failed">×™×™×¦×•× × ×›×©×œ</string>
215 <string name="import_failed">×™×™×‘×•× × ×›×©×œ</string>
216 <string name="cancelling">מבטל</string>
217
218 <!-- GPU driver installation -->
219 <string name="select_gpu_driver">בחר דרייבר למעבד הגרפי</string>
220 <string name="select_gpu_driver_title">×תה מעוניין להחליף ×ת הדרייבר של המעבד הגרפי שלך?</string>
221 <string name="select_gpu_driver_install">התקן</string>
222 <string name="select_gpu_driver_default">ברירת מחדל</string>
223 <string name="select_gpu_driver_use_default">משתמש בדרייבר ברירת המחדל של המעבד הגרפי</string>
224 <string name="select_gpu_driver_error">דרייבר ×œ× ×—×•×§×™ נבחר, משתמש בברירת המחדל של המערכת!</string>
225 <string name="system_gpu_driver">דרייבר של המעבד הגרפי של המערכת</string>
226 <string name="installing_driver">מתקין דרייבר...</string>
227
228 <!-- Preferences Screen -->
229 <string name="preferences_settings">הגדרות</string>
230 <string name="preferences_general">כללי</string>
231 <string name="preferences_system">מערכת</string>
232 <string name="preferences_graphics">גרפיקה</string>
233 <string name="preferences_audio">שמע</string>
234 <string name="preferences_theme">צבע ונוש×</string>
235 <!-- ROM loading errors -->
236 <string name="loader_error_encrypted">המשחק שלך מוצפן</string>
237 <string name="loader_error_invalid_format">×ין ×פשרות לטעון ×ת המשחק</string>
238 <string name="loader_error_file_not_found">קובץ המשחק ×œ× ×§×™×™×</string>
239
240 <!-- Emulation Menu -->
241 <string name="emulation_exit">×¦× ×ž×”×מולציה</string>
242 <string name="emulation_done">סיו×</string>
243 <string name="emulation_fps_counter">סופר FPS</string>
244 <string name="emulation_control_scale">קנה מידה</string>
245 <string name="emulation_control_opacity">שקיפות</string>
246 <string name="emulation_pause">עצור ×מולציה</string>
247 <string name="emulation_unpause">המשך ×מולציה</string>
248 <string name="load_settings">טוען הגדרות...</string>
249
250 <!-- Software keyboard -->
251 <string name="software_keyboard">מקלדת תוכנה</string>
252
253 <!-- Errors and warnings -->
254 <string name="abort_button">×ודות</string>
255 <string name="continue_button">המשך</string>
256 <string name="system_archive_not_found">×רכיון מערכת ×œ× × ×ž×¦×</string>
257 <string name="system_archive_not_found_message">%s חסר. בבקשה ×”×•×¦× ×ª× ×רכיוני המערכת שלך./nהמשכת ×”×מולציה עלולה ×œ×’×¨×•× ×œ×§×¨×™×¡×•×ª וב××’×™×.</string>
258 <string name="system_archive_general">×רכיון מערכת</string>
259 <string name="save_load_error">בעיית שמירה/טעינה</string>
260 <string name="fatal_error">שגי××” חמורה</string>
261 <string name="device_memory_inadequate">RAM המכשיר: %1$s/nמומלץ: %2$s</string>
262 <string name="memory_formatted">%1$s%2$s</string>
263 <string name="no_game_present">×ין משחק שניתן להריץ!</string>
264
265 <!-- Region Names -->
266 <string name="region_japan">יפן</string>
267 <string name="region_usa">×רה״ב</string>
268 <string name="region_europe">×ירופה</string>
269 <string name="region_australia">×וסטרליה</string>
270 <string name="region_china">סין</string>
271 <string name="region_korea">קורי××”</string>
272 <string name="region_taiwan">טייוו×ן</string>
273
274 <!-- Memory Sizes -->
275 <string name="memory_byte">בייט</string>
276 <string name="memory_kilobyte">KB</string>
277 <string name="memory_megabyte">MB</string>
278 <string name="memory_gigabyte">GB</string>
279 <string name="memory_terabyte">TB</string>
280 <string name="memory_petabyte">PB</string>
281 <string name="memory_exabyte">EB</string>
282
283 <!-- Renderer APIs -->
284 <string name="renderer_vulkan">Vulkan</string>
285 <string name="renderer_none">×ין ×©×•× ×“×‘×¨</string>
286
287 <!-- Renderer Accuracy -->
288 <string name="renderer_accuracy_normal">רגיל</string>
289 <string name="renderer_accuracy_high">גבוה</string>
290 <string name="renderer_accuracy_extreme">××§×¡×˜×¨×™× (×יטי)</string>
291
292 <!-- Resolutions -->
293 <string name="resolution_half">0.5X (360p/540p)</string>
294 <string name="resolution_three_quarter">0.75X (540p/810p)</string>
295 <string name="resolution_one">1X (720p/1080p)</string>
296 <string name="resolution_two">2X (1440p/2160p) (×יטי)</string>
297 <string name="resolution_three">3X (2160p/3240p) (×יטי)</string>
298 <string name="resolution_four">4X (2880p/4320p) (×יטי)</string>
299
300 <string name="renderer_vsync_mailbox">תיבת דו×ר</string>
301 <string name="renderer_vsync_fifo">FIFO (On)</string>
302 <string name="renderer_vsync_fifo_relaxed">FIFO נינוח</string>
303
304 <!-- Scaling Filters -->
305 <string name="scaling_filter_nearest_neighbor">השכן הקרוב ביותר</string>
306 <string name="scaling_filter_scale_force">ScaleForce</string>
307 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ Super Resolution</string>
308
309 <!-- Anti-Aliasing -->
310 <string name="anti_aliasing_none">×ין ×©×•× ×“×‘×¨</string>
311 <string name="anti_aliasing_fxaa">FXAA</string>
312 <string name="anti_aliasing_smaa">SMAA</string>
313
314 <!-- Screen Layouts -->
315 <string name="screen_layout_landscape">לרוחב</string>
316 <string name="screen_layout_portrait">ל×ורך</string>
317 <string name="screen_layout_auto">×וטומטי</string>
318
319 <!-- Aspect Ratios -->
320 <string name="ratio_default">ברירת מחדל (16:9)</string>
321 <string name="ratio_force_four_three">הכרח 4:3</string>
322 <string name="ratio_force_twenty_one_nine">הכרח 21:9</string>
323 <string name="ratio_force_sixteen_ten">הכרח 16:10</string>
324 <string name="ratio_stretch">הרחב לגודל המסך</string>
325
326 <!-- CPU Accuracy -->
327 <string name="cpu_accuracy_accurate">מדויק</string>
328 <string name="cpu_accuracy_unsafe">×œ× ×‘×˜×•×—</string>
329 <string name="cpu_accuracy_paranoid">פר×נו×ידי (×יטי)</string>
330
331 <!-- Gamepad Buttons -->
332 <string name="gamepad_d_pad">D-pad</string>
333 <string name="gamepad_left_stick">ג׳ויסטיק שמ×לי</string>
334 <string name="gamepad_right_stick">ג׳ויסטיק ימני</string>
335 <string name="gamepad_home">בית</string>
336 <string name="gamepad_screenshot">×¦×™×œ×•× ×ž×¡×š</string>
337
338 <!-- Theme options -->
339 <string name="change_app_theme">שנה ×ת × ×•×©× ×”×פליקצייה</string>
340 <string name="theme_default">ברירת מחדל</string>
341 <string name="theme_material_you">חומר ×תה/מ×טירי×ל יו</string>
342
343 <!-- Theme Modes -->
344 <string name="change_theme_mode">שנה ×ת מצב הנוש×</string>
345 <string name="theme_mode_follow_system">עקוב ×חרי המערכת</string>
346 <string name="theme_mode_light">בהיר</string>
347 <string name="theme_mode_dark">×›×”×”</string>
348
349 <!-- Audio output engines -->
350 <string name="cubeb">cubeb</string>
351
352 <!-- Black backgrounds theme -->
353 <string name="use_black_backgrounds">×¨×§×¢×™× ×©×—×•×¨×™×</string>
354 <string name="use_black_backgrounds_description">×›×©×ž×ª×©×ž×©×™× ×‘×ž×¦×‘ ×›×”×”, ×©× ×¨×§×¢×™× ×©×—×•×¨×™×.</string>
355
356 <!-- Picture-In-Picture -->
357 <string name="picture_in_picture">תמונה בתוך תמונה</string>
358 <string name="picture_in_picture_description">הקטן ×ת החלון ×›×שר × ×ž×¦× ×‘×¨×§×¢</string>
359 <string name="pause">עצור</string>
360 <string name="play">שחק</string>
361 <string name="mute">השתק</string>
362 <string name="unmute">בטל השתקה</string>
363
364 <!-- Licenses screen strings -->
365 <string name="licenses">רישיונות</string>
366 <string name="license_fidelityfx_fsr_description">×פסקיילינג ב×יכות גבוהה מ AMD</string>
367 </resources>
diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml
new file mode 100644
index 000000000..6563ba288
--- /dev/null
+++ b/src/android/app/src/main/res/values-hu/strings.xml
@@ -0,0 +1,402 @@
1<?xml version="1.0" encoding="utf-8"?>
2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3
4 <string name="app_disclaimer">Ez a szoftver Nintendo Switch játékkonzolhoz készült játékokat futtat. Nem tartalmaz játékokat vagy kulcsokat. .&lt;br /&gt;&lt;br /&gt;Mielőtt hozzákezdenél, kérjük, válaszd ki a <![CDATA[<b>prod.keys</b>]]> fájl helyét a készülék tárhelyén&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Tudj meg többet</a>]]></string>
5 <string name="emulation_notification_channel_name">Emuláció aktív</string>
6 <string name="emulation_notification_channel_description">Ãllandó értesítést jelenít meg, amíg az emuláció fut.</string>
7 <string name="emulation_notification_running">A yuzu fut</string>
8 <string name="notice_notification_channel_name">Megjegyzések és hibák</string>
9 <string name="notice_notification_channel_description">Értesítések megjelenítése, ha valami rosszul sül el.</string>
10 <string name="notification_permission_not_granted">Nincs engedély az értesítés megjelenítéséhez!</string>
11
12 <!-- Setup strings -->
13 <string name="welcome">Üdvözöljük!</string>
14 <string name="welcome_description">Ismerkedj meg a &lt;b>yuzu&lt;/b> beállításával és ugorj bele az emulációba.</string>
15 <string name="get_started">Vágjunk bele</string>
16 <string name="keys">Kulcsok</string>
17 <string name="keys_description">Válaszd ki a(z) &lt;b>prod.keys&lt;/b> fájlodat az alábbi gombbal.</string>
18 <string name="select_keys">Kulcsok kiválasztása</string>
19 <string name="games">Játékok</string>
20 <string name="games_description">
21Válaszd ki a(z) &lt;b>Games&lt;/b> mappát az alábbi gombbal.</string>
22 <string name="done">Kész</string>
23 <string name="done_description">Minden kész.\nJó szórakozást!</string>
24 <string name="text_continue">Folytatás</string>
25 <string name="next">Következő</string>
26 <string name="back">Vissza</string>
27 <string name="add_games">Játékok hozzáadása</string>
28 <string name="add_games_description">Játékaid mappa kiválasztása</string>
29 <string name="step_complete">Kész!</string>
30
31 <!-- Home strings -->
32 <string name="home_games">Játékok</string>
33 <string name="home_search">Keresés</string>
34 <string name="home_settings">Beállítások</string>
35 <string name="empty_gamelist">Nem található fájl, vagy még nincs kiválasztva könyvtár.</string>
36 <string name="search_and_filter_games">Játékok keresése és szűrése</string>
37 <string name="select_games_folder">Játékmappa kiválasztása</string>
38 <string name="add_games_warning">Kihagyod a játékok mappa kiválasztását?</string>
39 <string name="add_games_warning_description">A játékok nem jelennek meg a Játékok listában, ha egy mappa nincs kijelölve.</string>
40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
41 <string name="home_search_games">Játékok keresése</string>
42 <string name="search_settings">Beállítások keresése</string>
43 <string name="games_dir_selected">Játékok könyvtár kiválasztva</string>
44 <string name="install_prod_keys">prod.keys telepítése</string>
45 <string name="install_prod_keys_description">Kiskereskedelmi játékok dekódolásához szükséges</string>
46 <string name="install_prod_keys_warning">Kihagyod a kulcsok hozzáadását?</string>
47 <string name="install_prod_keys_warning_description">A kiskereskedelmi játékok emulálásához érvényes kulcsokra van szükség. Csak a homebrew alkalmazások fognak működni, ha folytatod.</string>
48 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
49 <string name="notifications">Értesítések</string>
50 <string name="notifications_description">Értesítési engedélyek megadása az alábbi gombbal.</string>
51 <string name="give_permission">Engedély megadása</string>
52 <string name="notification_warning">Kihagyod az értesítési engedély megadását?</string>
53 <string name="notification_warning_description">yuzu nem fog tudni értesíteni a fontos imformációkról</string>
54 <string name="permission_denied">Engedély megtagadva</string>
55 <string name="permission_denied_description">Túl gyakran utasítottad el a hozzáférést, így manuálisan kell jóváhagynod a rendszer beállításokban.</string>
56 <string name="about">A programról</string>
57 <string name="about_description">Build verzió, készítők, és még több</string>
58 <string name="warning_help">Segítség</string>
59 <string name="warning_skip">Kihagyás</string>
60 <string name="warning_cancel">Mégse</string>
61 <string name="install_amiibo_keys">Amiibo kulcsok telepítése</string>
62 <string name="install_amiibo_keys_description">Amiibo használata szükséges a játékhoz</string>
63 <string name="invalid_keys_file">Érvénytelen titkosítófájlok kiválasztva</string>
64 <string name="install_keys_success">Kulcsok sikeresen telepítve</string>
65 <string name="reading_keys_failure">Hiba történt a titkosítókulcsok olvasása során</string>
66 <string name="install_prod_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .keys kiterjesztéssel rendelkezik, majd próbáld újra.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .bin kiterjesztéssel rendelkezik, majd próbáld újra.</string>
68 <string name="invalid_keys_error">Érvénytelen titkosítókulcsok</string>
69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
70 <string name="install_keys_failure_description">A kiválasztott fájl helytelen, vagy sérült. Ãllíts össze egy új kulcsot.</string>
71 <string name="install_gpu_driver">GPU illesztőprogram telepítése</string>
72 <string name="install_gpu_driver_description">Alternatív illesztőprogramok telepítése az esetlegesen elérhető teljesítmény és pontosság érdekében</string>
73 <string name="advanced_settings">Haladó beállítások</string>
74 <string name="advanced_settings_game">Haladó beállítások: %1$s</string>
75 <string name="settings_description">Emulátorbeállítások konfigurálása</string>
76 <string name="search_recently_played">Nemrég játszva</string>
77 <string name="search_recently_added">Nemrég hozzáadva</string>
78 <string name="search_retail">Kiskereskedelmi</string>
79 <string name="open_user_folder">yuzu mappa megnyitása</string>
80 <string name="open_user_folder_description">yuzu belső fájljainak kezelése</string>
81 <string name="theme_and_color_description">Az alkalmazás megjelenésének módosítása</string>
82 <string name="no_file_manager">Nem található fájlkezelő</string>
83 <string name="notification_no_directory_link">Nem sikerült megnyitni a yuzu könyvtárat</string>
84 <string name="notification_no_directory_link_description">Kérjük, manuálisan keresd meg a felhasználói mappát a fájlkezelő oldalsó paneljével.</string>
85 <string name="manage_save_data">Mentésadatok kezelése</string>
86 <string name="manage_save_data_description">Mentés található. Kérjük, válassz egyet az alábbi opciók közül.</string>
87 <string name="import_export_saves_description">Mentési fájlok importálás vagy exportálása</string>
88 <string name="save_file_imported_success">Sikeresen importálva</string>
89 <string name="save_file_invalid_zip_structure">Érvénytelen mentési könyvtárstruktúra</string>
90 <string name="save_file_invalid_zip_structure_description">Az első almappa neve a játék azonosítója kell, hogy legyen.</string>
91 <string name="import_saves">Importálás</string>
92 <string name="export_saves">Exportálás</string>
93 <string name="install_firmware">Firmware telepítés</string>
94 <string name="install_firmware_description">A firmwarenek ZIP archívumban kell lennie, és szükséges a játékok indításához</string>
95 <string name="firmware_installing">Firmware telepítése</string>
96 <string name="firmware_installed_success">Firmware sikeresen telepítve</string>
97 <string name="firmware_installed_failure">Firmware telepítése sikertelen</string>
98 <string name="firmware_installed_failure_description">Győződj meg róla, hogy a firmware nca fájlok a zip gyökerénél vannak, és próbáld meg újra.</string>
99 <string name="share_log">Hibakereső logok megosztása</string>
100 <string name="share_log_description">A yuzu naplófájl megosztása a problémák elhárításához</string>
101 <string name="share_log_missing">Nem található log fájl</string>
102 <string name="install_game_content">Játéktartalom telepítése</string>
103 <string name="install_game_content_description">Játékfrissítések vagy DLC telepítése</string>
104 <string name="installing_game_content">Tartalom telepítése...</string>
105 <string name="install_game_content_failure">Hiba történt a fájl(ok) NAND-ra telepítése közben</string>
106 <string name="install_game_content_failure_description">Győződj meg róla, hogy a tartalom valós, és a prod.keys fájl telepítve van.</string>
107 <string name="install_game_content_failure_base">Az alapjátékok telepítése nem engedélyezett az esetleges konfliktusok elkerülése érdekében.</string>
108 <string name="install_game_content_failure_file_extension">Csak NSP és XCI tartalom támogatott. Győződj meg róla, hogy a játéktartalom érvényes.</string>
109 <string name="install_game_content_failed_count">%1$d telepítési hiba</string>
110 <string name="install_game_content_success">Játéktartalom sikeresen telepítve</string>
111 <string name="install_game_content_success_install">%1$d sikeresen telepítve</string>
112 <string name="install_game_content_success_overwrite">%1$d sikeresen felülírva</string>
113 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
114 <string name="custom_driver_not_supported">Egyéni illesztőprogramok nem támogatottak</string>
115 <string name="custom_driver_not_supported_description">Egyéni illesztőprogram telepítése jelenleg nem támogatott ezen az eszközön.\nNézz vissza később, hátha hozzáadtuk a támogatását!</string>
116 <string name="manage_yuzu_data">yuzu adatok kezelése</string>
117 <string name="manage_yuzu_data_description">Firmware, kulcsok, felhasználói adatok és egyebek importálása/exportálása</string>
118 <string name="share_save_file">Mentési fájl megosztása</string>
119 <string name="export_save_failed">A mentés exportálása sikertelen</string>
120
121 <!-- About screen strings -->
122 <string name="gaia_is_not_real">Gaia nem valódi</string>
123 <string name="copied_to_clipboard">Másolva a vágólapra</string>
124 <string name="about_app_description">Egy nyílt forráskódú Switch emulátor</string>
125 <string name="contributors">Hozzájárulók</string>
126 <string name="contributors_description">\u2764 által készítve a yuzu csapattól</string>
127 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
128 <string name="licenses_description">Projektek, amik nélkül a yuzu nem jöhetett volna létre Androidra</string>
129 <string name="user_data">Felhasználói adatok</string>
130 <string name="user_data_description">Az összes alkalmazásadat importálása/exportálása.\n\nA felhasználói adatok importálásakor az összes meglévő felhasználói adat törlődik!</string>
131 <string name="exporting_user_data">Felhasználói adatok exportálása...</string>
132 <string name="importing_user_data">Felhasználói adatok importálása...</string>
133 <string name="import_user_data">Felhasználói adatok importálása</string>
134 <string name="invalid_yuzu_backup">Érvénytelen yuzu biztonsági másolat</string>
135 <string name="user_data_export_success">Felhasználói adatok sikeresen exportálva</string>
136 <string name="user_data_import_success">Felhasználói adatok sikeresen importálva</string>
137 <string name="user_data_export_cancelled">Exportálás megszakítva</string>
138 <string name="user_data_import_failed_description">Ellenőrizd, hogy a felhasználói adatok mappái a zip mappa gyökerében vannak, és tartalmaznak egy konfig fájlt a config/config.ini címen, majd próbáld meg újra.</string>
139 <string name="support_link">https://discord.gg/u77vRWY</string>
140 <string name="website_link">https://yuzu-emu.org/</string>
141 <string name="github_link">https://github.com/yuzu-emu</string>
142
143 <!-- Early access upgrade strings -->
144 <string name="early_access">Korai hozzáférés</string>
145 <string name="get_early_access">Szerezz korai hozzáférést</string>
146 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
147 <string name="get_early_access_description">Legújabb funkciók, korai hozzáférés a frissítésekhez, és sok más</string>
148 <string name="early_access_benefits">Korai hozzáférés előnyei</string>
149 <string name="cutting_edge_features">Legújabb funkciók</string>
150 <string name="early_access_updates">Korai hozzáférés a frissítésekhez</string>
151 <string name="no_manual_installation">Automatikus telepítések</string>
152 <string name="prioritized_support">Priorizált támogatás</string>
153 <string name="our_eternal_gratitude">Valamint az örök hálánk</string>
154 <string name="are_you_interested">Érdekel a dolog?</string>
155
156 <!-- General settings strings -->
157 <string name="frame_limit_enable">Sebességkorlát</string>
158 <string name="frame_limit_enable_description">Korlátozza az emuláció sebességét a normál sebesség adott százalékára.</string>
159 <string name="frame_limit_slider">Sebességkorlát százaléka</string>
160 <string name="frame_limit_slider_description">Az emuláció sebességét határozza meg. 100% a normál sebesség. A magasabb értékek növelik, az alacsonyabbak csökkentik a sebességkorlátot.</string>
161 <string name="cpu_accuracy">CPU pontosság</string>
162 <string name="value_with_units">%1$s%2$s</string>
163
164 <!-- System settings strings -->
165 <string name="use_docked_mode">Dokkolt mód</string>
166 <string name="use_docked_mode_description">Növeli a felbontást, de csökkenti a teljesítményt. Kikapcsolás esetén a Kézi mód van használatban, ami kisebb felbontást, de nagyobb teljesítményt eredményez.</string>
167 <string name="emulated_region">Emulált régió</string>
168 <string name="emulated_language">Emulált nyelv</string>
169 <string name="select_rtc_date">Válassz RTC dátumot</string>
170 <string name="select_rtc_time">Válassz RTC időt</string>
171 <string name="use_custom_rtc">Egyéni RTC</string>
172 <string name="use_custom_rtc_description">Megadhatsz egy valós idejű órát, amely eltér a rendszer által használt órától.</string>
173 <string name="set_custom_rtc">Egyéni RTC beállítása</string>
174
175 <!-- Graphics settings strings -->
176 <string name="renderer_accuracy">Pontosság szintje</string>
177 <string name="renderer_resolution">Felbontás (Kézi/Dockolt)</string>
178 <string name="renderer_vsync">VSync mód</string>
179 <string name="renderer_screen_layout">Orientáció</string>
180 <string name="renderer_aspect_ratio">Képarány</string>
181 <string name="renderer_scaling_filter">Ablakhoz alkalmazkodó szűrő</string>
182 <string name="renderer_anti_aliasing">Élsimítási módszer</string>
183 <string name="renderer_force_max_clock">Maximum órajel kényszerítése (csak Adreno)</string>
184 <string name="renderer_force_max_clock_description">Kényszeríti a GPU-t a lehető legnagyobb órajelen működésre (a hőmérséklet korlátozások továbbra is érvényben maradnak).</string>
185 <string name="renderer_asynchronous_shaders">Aszinkron árnyékolók használata</string>
186 <string name="renderer_asynchronous_shaders_description">Aszinkron módon fordítja az árnyékolókat, ami csökkenti az akadozást, de hibákat okozhat.</string>
187 <string name="renderer_reactive_flushing">Reaktív ürítés használata</string>
188 <string name="renderer_reactive_flushing_description">Javítja a renderelési pontosságot néhány játékban a teljesítmény rovására.</string>
189 <string name="use_disk_shader_cache">Lemez árnyékoló gyorsítótár</string>
190 <string name="use_disk_shader_cache_description">Csökkenti az akadásokat azáltal, hogy helyileg tárolja és tölti be a generált árnyékolókat.</string>
191
192 <!-- Debug settings strings -->
193 <string name="cpu">CPU</string>
194 <string name="cpu_debug_mode">CPU hibakeresés</string>
195 <string name="cpu_debug_mode_description">Lassú hibakereső módba állítja a CPU-t.</string>
196 <string name="gpu">GPU</string>
197 <string name="renderer_api">API</string>
198 <string name="renderer_debug">Grafikai hibakeresés</string>
199 <string name="renderer_debug_description">Lassú hibakeresési módba állítja a grafikus API-t .</string>
200 <!-- Audio settings strings -->
201 <string name="audio_output_engine">Kimeneti rendszer</string>
202 <string name="audio_volume">Hangerő</string>
203 <string name="audio_volume_description">Hangkimenet hangerejének megadása</string>
204
205 <!-- Miscellaneous -->
206 <string name="slider_default">Alapértelmezett</string>
207 <string name="ini_saved">Beállítások elmentve</string>
208 <string name="gameid_saved">Beállítások elmentve a következőhöz: %1$s</string>
209 <string name="error_saving">Mentési hiba%1$s .ini: %2$s</string>
210 <string name="unimplemented_menu">Nem implementált menü</string>
211 <string name="loading">Betöltés...</string>
212 <string name="shutting_down">Leállítás...</string>
213 <string name="reset_setting_confirmation">Szeretnéd visszaállítani a beállítások az alapértelmezett értékekre?</string>
214 <string name="reset_to_default">Alaphelyzetbe állítás</string>
215 <string name="reset_all_settings">Alaphelyzetbe állítod a beállításokat?</string>
216 <string name="reset_all_settings_description">Minden haladó beállítás vissza lesz állítva az alapértelmezett konfigurációra. Ez a művelet nem vonható vissza.</string>
217 <string name="settings_reset">Beállítások alaphelyzetbe állítva</string>
218 <string name="close">Bezárás</string>
219 <string name="learn_more">Tudj meg többet</string>
220 <string name="auto">Automatikus</string>
221 <string name="submit">Küldés</string>
222 <string name="string_null">Nulla</string>
223 <string name="string_import">Importálás</string>
224 <string name="export">Exportálás</string>
225 <string name="export_failed">Exportálás sikertelen</string>
226 <string name="import_failed">Importálás sikertelen</string>
227 <string name="cancelling">Megszakítás</string>
228
229 <!-- GPU driver installation -->
230 <string name="select_gpu_driver">Válassz GPU illesztőprogramot</string>
231 <string name="select_gpu_driver_title">Szeretnéd lecserélni a jelenlegi GPU illesztőprogramot?</string>
232 <string name="select_gpu_driver_install">Telepítés</string>
233 <string name="select_gpu_driver_default">Alapértelmezett</string>
234 <string name="select_gpu_driver_use_default">Alapértelmezett GPU illesztőprogram használata</string>
235 <string name="select_gpu_driver_error">Érvénytelen driver kiválasztva, a rendszer alapértelmezett lesz használva!</string>
236 <string name="system_gpu_driver">Rendszer GPU illesztőprogram</string>
237 <string name="installing_driver">Illesztőprogram telepítése...</string>
238
239 <!-- Preferences Screen -->
240 <string name="preferences_settings">Beállítások</string>
241 <string name="preferences_general">Ãltalános</string>
242 <string name="preferences_system">Rendszer</string>
243 <string name="preferences_graphics">Grafika</string>
244 <string name="preferences_audio">Hang</string>
245 <string name="preferences_theme">Téma és színek</string>
246 <string name="preferences_debug">Hibakeresés</string>
247
248 <!-- ROM loading errors -->
249 <string name="loader_error_encrypted">ROM titkosítva</string>
250 <string name="loader_error_encrypted_keys_description"><![CDATA[Győződj meg róla, hogy a <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> fájl telepítve van, hogy a játékok visszafejthetők legyenek.]]></string>
251 <string name="loader_error_video_core">Hiba lépett fel a videómag inicializása során</string>
252 <string name="loader_error_video_core_description">Ezt általában egy nem kompatibilis GPU illesztő okozza. Egyéni GPU illesztőprogram telepítése megoldhatja a problémát.</string>
253 <string name="loader_error_invalid_format">Nem sikerült betölteni a ROM-ot</string>
254 <string name="loader_error_file_not_found">ROM fájl nem létezik</string>
255
256 <!-- Emulation Menu -->
257 <string name="emulation_exit">Emuláció bezárása</string>
258 <string name="emulation_done">Kész</string>
259 <string name="emulation_fps_counter">FPS számláló</string>
260 <string name="emulation_toggle_controls">Irányítás átkapcsolása</string>
261 <string name="emulation_dpad_slide">D-pad csúsztatása</string>
262 <string name="emulation_haptics">Érintés haptikája</string>
263 <string name="emulation_show_overlay">Ãtfedés mutatása</string>
264 <string name="emulation_toggle_all">Össze átkapcsolása</string>
265 <string name="emulation_control_adjust">Ãtfedés testreszabása</string>
266 <string name="emulation_control_scale">Skálázás</string>
267 <string name="emulation_control_opacity">Ãtlátszóság</string>
268 <string name="emulation_touch_overlay_reset">Ãtfedés visszaállítása</string>
269 <string name="emulation_touch_overlay_edit">Ãtfedés módosítása</string>
270 <string name="emulation_pause">Emuláció szünetelése</string>
271 <string name="emulation_unpause">Emuláció folytatása</string>
272 <string name="emulation_input_overlay">Ãtfedés beállításai</string>
273
274 <string name="load_settings">Beállítások betöltése...</string>
275
276 <!-- Software keyboard -->
277 <string name="software_keyboard">Szoftver billenytűzet</string>
278
279 <!-- Errors and warnings -->
280 <string name="abort_button">Megszakítás</string>
281 <string name="continue_button">Folytatás</string>
282 <string name="system_archive_not_found">Nem található rendszerarchívum</string>
283 <string name="system_archive_not_found_message">%s hiányzik. Kérjük, mentsd ki a rendszerarchívumaidat.\nAz emuláció folytatása összeomlásokhoz és hibákhoz vezethet.</string>
284 <string name="system_archive_general">Egy rendszerarchívum</string>
285 <string name="save_load_error">Mentési/betöltési hiba</string>
286 <string name="fatal_error">Végzetes hiba</string>
287 <string name="fatal_error_message">Végzetes hiba történt. Ellenőrizd a logot a részletekért.\nAz emuláció folytatása összeomlást és hibákat eredményzhet.</string>
288 <string name="performance_warning">Ennek a beállításnak a kikapcsolása jelentős mértékben csökkenti a teljesítményt! A legjobb élmény érdekében javasolt a beállítás bekapcsolva tartása.</string>
289 <string name="device_memory_inadequate">Eszköz RAM: %1$s\nAjánlott: %2$s</string>
290 <string name="memory_formatted">%1$s %2$s</string>
291 <string name="no_game_present">Nincs indítható játék!</string>
292
293 <!-- Region Names -->
294 <string name="region_japan">Japán</string>
295 <string name="region_usa">USA</string>
296 <string name="region_europe">Európa</string>
297 <string name="region_australia">Ausztrália</string>
298 <string name="region_china">Kína</string>
299 <string name="region_korea">Korea</string>
300 <string name="region_taiwan">Tajvan</string>
301
302 <!-- Memory Sizes -->
303 <string name="memory_byte">Bájt</string>
304 <string name="memory_kilobyte">KB</string>
305 <string name="memory_megabyte">MB</string>
306 <string name="memory_gigabyte">GB</string>
307 <string name="memory_terabyte">TB</string>
308 <string name="memory_petabyte">PB</string>
309 <string name="memory_exabyte">EB</string>
310
311 <!-- Renderer APIs -->
312 <string name="renderer_vulkan">Vulkan</string>
313 <string name="renderer_none">Nincs</string>
314
315 <!-- Renderer Accuracy -->
316 <string name="renderer_accuracy_normal">Normál</string>
317 <string name="renderer_accuracy_high">Magas</string>
318 <string name="renderer_accuracy_extreme">Extrém (Lassú)</string>
319
320 <!-- Resolutions -->
321 <string name="resolution_half">0.5X (360p/540p)</string>
322 <string name="resolution_three_quarter">0.75X (540p/810p)</string>
323 <string name="resolution_one">1X (720p/1080p)</string>
324 <string name="resolution_two">2X (1440p/2160p) (Lassú)</string>
325 <string name="resolution_three">3X (2160p/3240p) (Lassú)</string>
326 <string name="resolution_four">4X (2880p/4320p) (Lassú)</string>
327
328 <!-- Renderer VSync -->
329 <string name="renderer_vsync_immediate">Azonnali (Ki)</string>
330 <string name="renderer_vsync_mailbox">Postaláda</string>
331 <string name="renderer_vsync_fifo">FIFO (Be)</string>
332 <string name="renderer_vsync_fifo_relaxed">FIFO Relaxált</string>
333
334 <!-- Scaling Filters -->
335 <string name="scaling_filter_nearest_neighbor">Legközelebbi szomszéd</string>
336 <string name="scaling_filter_bilinear">Bilineáris</string>
337 <string name="scaling_filter_bicubic">Bikubikus</string>
338 <string name="scaling_filter_gaussian">Gauss-féle</string>
339 <string name="scaling_filter_scale_force">ScaleForce</string>
340 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ Super Resolution</string>
341
342 <!-- Anti-Aliasing -->
343 <string name="anti_aliasing_none">Nincs</string>
344 <string name="anti_aliasing_fxaa">FXAA</string>
345 <string name="anti_aliasing_smaa">SMAA</string>
346
347 <!-- Screen Layouts -->
348 <string name="screen_layout_landscape">Fekvő</string>
349 <string name="screen_layout_portrait">Ãlló</string>
350 <string name="screen_layout_auto">Automatikus</string>
351
352 <!-- Aspect Ratios -->
353 <string name="ratio_default">Alapértelmezett (16:9)</string>
354 <string name="ratio_force_four_three">4:3 kényszerítése</string>
355 <string name="ratio_force_twenty_one_nine">21:9 kényszerítése</string>
356 <string name="ratio_force_sixteen_ten">16:10 kényszerítése</string>
357 <string name="ratio_stretch">Ablakhoz nyújtás</string>
358
359 <!-- CPU Accuracy -->
360 <string name="cpu_accuracy_accurate">Pontos</string>
361 <string name="cpu_accuracy_unsafe">Nem biztonságos</string>
362 <string name="cpu_accuracy_paranoid">Paranoid (Lassú)</string>
363
364 <!-- Gamepad Buttons -->
365 <string name="gamepad_d_pad">D-pad</string>
366 <string name="gamepad_left_stick">Bal kar</string>
367 <string name="gamepad_right_stick">Jobb kar</string>
368 <string name="gamepad_home">Home</string>
369 <string name="gamepad_screenshot">Képernyőmentés</string>
370
371 <!-- Disk shader cache -->
372 <string name="preparing_shaders">Ãrnyékolók elÅ‘készítése</string>
373 <string name="building_shaders">Ãrnyékolók létrehozása</string>
374
375 <!-- Theme options -->
376 <string name="change_app_theme">Alkalmazás témájának módosítása</string>
377 <string name="theme_default">Alapértelmezett</string>
378 <!-- Theme Modes -->
379 <string name="change_theme_mode">Téma váltása</string>
380 <string name="theme_mode_follow_system">Rendszerbeállítások használata</string>
381 <string name="theme_mode_light">Világos</string>
382 <string name="theme_mode_dark">Sötét</string>
383
384 <!-- Audio output engines -->
385 <string name="cubeb">cubeb</string>
386
387 <!-- Black backgrounds theme -->
388 <string name="use_black_backgrounds">Fekete háttér</string>
389 <string name="use_black_backgrounds_description">Sötét téma használatakor fekete háttér használata.</string>
390
391 <!-- Picture-In-Picture -->
392 <string name="picture_in_picture">Kép a képben</string>
393 <string name="picture_in_picture_description">Ablak minimalizálása, amikor háttérbe kerül</string>
394 <string name="pause">Szünet</string>
395 <string name="play">Lejátszás</string>
396 <string name="mute">Némítás</string>
397 <string name="unmute">Némítás feloldása</string>
398
399 <!-- Licenses screen strings -->
400 <string name="licenses">Licenszek</string>
401 <string name="license_fidelityfx_fsr_description">Magas minőségű felskálázás az AMD-től</string>
402 </resources>
diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml
index 09c9345b0..5afebb4c4 100644
--- a/src/android/app/src/main/res/values-it/strings.xml
+++ b/src/android/app/src/main/res/values-it/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Questo software permette di giocare ai giochi della console Nintendo Switch. Nessun gioco o chiave è inclusa.&lt;br /&gt;&lt;br /&gt;Prima di iniziare, perfavore individua il file <![CDATA[<b>prod.keys </b>]]> nella memoria del tuo dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Scopri di più</a>]]></string> 4 <string name="app_disclaimer">Questo software permette di giocare ai giochi della console Nintendo Switch. Nessun gioco o chiave è inclusa.&lt;br /&gt;&lt;br /&gt;Prima di iniziare, perfavore individua il file <![CDATA[<b>prod.keys </b>]]> nella memoria del tuo dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Scopri di più</a>]]></string>
5 <string name="emulation_notification_channel_name">L\'emulatore è attivo</string> 5 <string name="emulation_notification_channel_name">L\'emulatore è attivo</string>
@@ -13,9 +13,9 @@
13 <string name="welcome">Benvenuto!</string> 13 <string name="welcome">Benvenuto!</string>
14 <string name="welcome_description">Scopri come configurare &lt;b>yuzu&lt;/b> e passare all\'emulazione.</string> 14 <string name="welcome_description">Scopri come configurare &lt;b>yuzu&lt;/b> e passare all\'emulazione.</string>
15 <string name="get_started">Iniziare</string> 15 <string name="get_started">Iniziare</string>
16 <string name="keys">Pulsanti</string> 16 <string name="keys">Chiavi</string>
17 <string name="keys_description">Seleziona il tuo file &lt;b>prod.keys&lt;/b> con il pulsante in basso.</string> 17 <string name="keys_description">Seleziona il tuo file &lt;b>prod.keys&lt;/b> con il pulsante in basso.</string>
18 <string name="select_keys">Selezione Pulsanti</string> 18 <string name="select_keys">Seleziona le chiavi</string>
19 <string name="games">Giochi</string> 19 <string name="games">Giochi</string>
20 <string name="games_description">Seleziona la cartella &lt;b>Games&lt;/b> con il pulsante in basso.</string> 20 <string name="games_description">Seleziona la cartella &lt;b>Games&lt;/b> con il pulsante in basso.</string>
21 <string name="done">Fatto</string> 21 <string name="done">Fatto</string>
@@ -25,6 +25,7 @@
25 <string name="back">Indietro</string> 25 <string name="back">Indietro</string>
26 <string name="add_games">Aggiungi giochi</string> 26 <string name="add_games">Aggiungi giochi</string>
27 <string name="add_games_description">Seleziona la cartella dei giochi</string> 27 <string name="add_games_description">Seleziona la cartella dei giochi</string>
28 <string name="step_complete">Completato!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Giochi</string> 31 <string name="home_games">Giochi</string>
@@ -38,6 +39,7 @@
38 <string name="add_games_warning_description">I giochi non saranno mostrati nella lista dei giochi se una cartella non è selezionata.</string> 39 <string name="add_games_warning_description">I giochi non saranno mostrati nella lista dei giochi se una cartella non è selezionata.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Cerca giochi</string> 41 <string name="home_search_games">Cerca giochi</string>
42 <string name="search_settings">Cerca impostazione</string>
41 <string name="games_dir_selected">Cartella dei giochi selezionata</string> 43 <string name="games_dir_selected">Cartella dei giochi selezionata</string>
42 <string name="install_prod_keys">Installa prod.keys</string> 44 <string name="install_prod_keys">Installa prod.keys</string>
43 <string name="install_prod_keys_description">Necessario per decrittografare i giochi</string> 45 <string name="install_prod_keys_description">Necessario per decrittografare i giochi</string>
@@ -61,15 +63,18 @@
61 <string name="invalid_keys_file">Selezionate chiavi non valide</string> 63 <string name="invalid_keys_file">Selezionate chiavi non valide</string>
62 <string name="install_keys_success">Chiavi installate correttamente</string> 64 <string name="install_keys_success">Chiavi installate correttamente</string>
63 <string name="reading_keys_failure">Errore durante la lettura delle chiavi di crittografia</string> 65 <string name="reading_keys_failure">Errore durante la lettura delle chiavi di crittografia</string>
66 <string name="install_prod_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .keys e prova di nuovo.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .bin e prova di nuovo</string>
64 <string name="invalid_keys_error">Chiavi di crittografia non valide</string> 68 <string name="invalid_keys_error">Chiavi di crittografia non valide</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.</string> 70 <string name="install_keys_failure_description">Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.</string>
67 <string name="install_gpu_driver">Installa i driver GPU</string> 71 <string name="install_gpu_driver">Installa i driver GPU</string>
68 <string name="install_gpu_driver_description">Installa driver alternativi per potenziali prestazioni migliori o accuratezza.</string> 72 <string name="install_gpu_driver_description">Installa driver alternativi per potenziali prestazioni migliori o accuratezza.</string>
69 <string name="advanced_settings">Impostazioni avanzate</string> 73 <string name="advanced_settings">Impostazioni avanzate</string>
74 <string name="advanced_settings_game">Impostazioni Avanzate: %1$s</string>
70 <string name="settings_description">Configura le impostazioni dell\'emulatore</string> 75 <string name="settings_description">Configura le impostazioni dell\'emulatore</string>
71 <string name="search_recently_played">Giocato recentemente</string> 76 <string name="search_recently_played">Giocati recentemente</string>
72 <string name="search_recently_added">Aggiunto recentemente</string> 77 <string name="search_recently_added">Aggiunti recentemente</string>
73 <string name="search_retail">Rivenditore</string> 78 <string name="search_retail">Rivenditore</string>
74 <string name="search_homebrew">Homebrew</string> 79 <string name="search_homebrew">Homebrew</string>
75 <string name="open_user_folder">Apri la cartella di yuzu</string> 80 <string name="open_user_folder">Apri la cartella di yuzu</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">La prima sotto cartella <b>deve</b> chiamarsi come l\'ID del titolo del gioco.</string> 91 <string name="save_file_invalid_zip_structure_description">La prima sotto cartella <b>deve</b> chiamarsi come l\'ID del titolo del gioco.</string>
87 <string name="import_saves">Importa</string> 92 <string name="import_saves">Importa</string>
88 <string name="export_saves">Esporta</string> 93 <string name="export_saves">Esporta</string>
94 <string name="install_firmware">Installa firmware</string>
95 <string name="install_firmware_description">Il firmware deve essere in un archivio ZIP ed è necessario per avviare alcuni giochi</string>
96 <string name="firmware_installing">Installando il firmware</string>
97 <string name="firmware_installed_success">Firmware installato con successo</string>
98 <string name="firmware_installed_failure">L\'installazione del firmware è fallita</string>
99 <string name="firmware_installed_failure_description">Accertati che i file .nca del firmware siano contenuti direttamente nella radice dello .zip e riprova.</string>
100 <string name="share_log">Condividi log di debug</string>
101 <string name="share_log_description">Condividi i log di yuzu per ricevere supporto</string>
102 <string name="share_log_missing">Nessun file di log trovato</string>
103 <string name="install_game_content">Installa contenuti di gioco</string>
104 <string name="install_game_content_description">Installa aggiornamenti o DLC</string>
105 <string name="installing_game_content">Installazione dei contenuti...</string>
106 <string name="install_game_content_failure">Errore durante l\'installazione del contenuto in NAND.</string>
107 <string name="install_game_content_failure_description">Accertati che i contenuti da installare siano validi e che le prod.keys siano presenti.</string>
108 <string name="install_game_content_failure_base">Installare i giochi base in NAND non è permesso, perché potrebbe causare dei conflitti con altri tipi di contenuti(Aggiornamenti e DLC)</string>
109 <string name="install_game_content_failure_file_extension">Solo i tipi NSP e XCI sono supportati. Verifica che i contenuti di gioco siano validi.</string>
110 <string name="install_game_content_failed_count">Errori di installazione: %1$d</string>
111 <string name="install_game_content_success">Contenuto/i di gioco installato/i con successo.</string>
112 <string name="install_game_content_success_install">%1$dinstallato con successo.</string>
113 <string name="install_game_content_success_overwrite">%1$dsovrascritto con successo</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">I driver personalizzati non sono supportati.</string>
116 <string name="custom_driver_not_supported_description">I driver personalizzati non sono attualmente supportati su questo dispositivo.\n Ricontrolla in futuro.</string>
117 <string name="manage_yuzu_data">Gestisci i dati di Yuzu</string>
118 <string name="manage_yuzu_data_description">Importa/Esporta il firmware, le keys, i dati utente, e altro!</string>
119 <string name="share_save_file">Condividi i tuoi dati di salvataggio</string>
120 <string name="export_save_failed">Errore durante l\'esportazione del salvataggio</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia non è reale</string> 123 <string name="gaia_is_not_real">Gaia non è reale</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">Collaboratori</string> 126 <string name="contributors">Collaboratori</string>
95 <string name="contributors_description">Realizzato con \u2764 dal team yuzu</string> 127 <string name="contributors_description">Realizzato con \u2764 dal team yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Progetti che rendono yuzu per Android possibile</string>
97 <string name="build">Compilazione</string> 130 <string name="build">Compilazione</string>
131 <string name="user_data">Dati Utente</string>
132 <string name="user_data_description">Importa/Esporta tutti i dati dell\'applicazione.\n\nDurante l\'importazione dei Dati Utente, quelli già esistenti verranno ELIMINATI.</string>
133 <string name="exporting_user_data">Esportazione dei Dati Utente...</string>
134 <string name="importing_user_data">Importazione dei Dati Utente...</string>
135 <string name="import_user_data">Importa i Dati Utente</string>
136 <string name="invalid_yuzu_backup">Backup di Yuzu Invalido</string>
137 <string name="user_data_export_success">Dati Utente esportati con successo</string>
138 <string name="user_data_import_success">Dati Utente importati con successo.</string>
139 <string name="user_data_export_cancelled">Esportazione annullata</string>
140 <string name="user_data_import_failed_description">Assicurati che la cartella dei Dati dell\'utente stiano nella radice del file.zip e che sia presente una cartella config in config/config.ini, poi, riprova.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
114 <string name="are_you_interested">Sei interessato?</string> 157 <string name="are_you_interested">Sei interessato?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">Abilita il limite di velocità</string> 160 <string name="frame_limit_enable">Limita velocità</string>
118 <string name="frame_limit_enable_description">Quando abilitato, la velocità di emulazione verrà limitata a una specifica percentuale della velocità normale.</string> 161 <string name="frame_limit_enable_description">Limita la velocità dell\'emulazione a una specifica percentuale della velocità normale.</string>
119 <string name="frame_limit_slider">Limite velocità percentuale</string> 162 <string name="frame_limit_slider">Limite velocità percentuale</string>
120 <string name="frame_limit_slider_description">Specifica la percentuale del limite della velocità di emulazione. Con quella preimpostata al 100% l\'emulazione verrà limitata alla velocità normale. Valori più alti o bassi aumenteranno o diminuiranno il limite di velocità.</string> 163 <string name="frame_limit_slider_description">Specifica la percentuale per limitare la velocità di emulazione. 100% è la velocità normale. Valori maggiori o minori aumenteranno o diminuiranno il limite di velocità</string>
121 <string name="cpu_accuracy">Accuratezza della CPU</string> 164 <string name="cpu_accuracy">Accuratezza della CPU</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">Modalità docked</string> 168 <string name="use_docked_mode">Modalità Docked</string>
125 <string name="use_docked_mode_description">Emula in modalità docked, questo aumenta la risoluzione a spese delle performance.</string> 169 <string name="use_docked_mode_description">Aumenta la risoluzione, diminuendo le performance. La modalità portatile è usata quando disabilitato, diminuendo la risoluzione e aumentando le performance.</string>
126 <string name="emulated_region">Regione emulata</string> 170 <string name="emulated_region">Regione emulata</string>
127 <string name="emulated_language">Lingua emulata</string> 171 <string name="emulated_language">Lingua emulata</string>
128 <string name="select_rtc_date">Seleziona la data dall\'orologio in tempo reale</string> 172 <string name="select_rtc_date">Imposta la data </string>
129 <string name="select_rtc_time">Seleziona il tempo dall\'orologio in tempo reale</string> 173 <string name="select_rtc_time">Imposta l\'ora, i minuti e i secondi.</string>
130 <string name="use_custom_rtc">Abilità l\'orologio in tempo reale personalizzato</string> 174 <string name="use_custom_rtc">RTC Personalizzato</string>
131 <string name="use_custom_rtc_description">Questa impostazione ti permette di impostare un orologio in tempo reale personalizzato separato da quello del tuo sistema corrente.</string> 175 <string name="use_custom_rtc_description">Ti permette di impostare un orologio in tempo reale personalizzato, completamente separato da quello di sistema.</string>
132 <string name="set_custom_rtc">Imposta l\'orologio in tempo reale personalizzato</string> 176 <string name="set_custom_rtc">Imposta un orologio in tempo reale personalizzato</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Livello di accuratezza</string> 179 <string name="renderer_accuracy">Livello di accuratezza</string>
137 <string name="renderer_resolution">Risoluzione</string> 180 <string name="renderer_resolution">Risoluzione (Portatile/Docked)</string>
138 <string name="renderer_vsync">Modalità VSync</string> 181 <string name="renderer_vsync">Modalità VSync</string>
139 <string name="renderer_aspect_ratio">Rapporto d\'aspetto</string> 182 <string name="renderer_screen_layout">Orientamento</string>
140 <string name="renderer_scaling_filter">Filtro di adattamento alla finestra</string> 183 <string name="renderer_aspect_ratio">Rapporto d\'aspetto: </string>
184 <string name="renderer_scaling_filter">Filtro adattivo della finestra </string>
141 <string name="renderer_anti_aliasing">Metodo di anti-aliasing</string> 185 <string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
142 <string name="renderer_force_max_clock">Forza clock massimi (solo Adreno)</string> 186 <string name="renderer_force_max_clock">Forza clock massimi (solo Adreno)</string>
143 <string name="renderer_force_max_clock_description">Forza la GPU a girare col massimo clock possibile (i vincoli alla temperatura saranno comunque applicati)</string> 187 <string name="renderer_force_max_clock_description">Forza la GPU a girare col massimo clock possibile (i vincoli alla temperatura saranno comunque applicati)</string>
144 <string name="renderer_asynchronous_shaders">Usa shaders asincrone</string> 188 <string name="renderer_asynchronous_shaders">Usa shaders asincrone</string>
145 <string name="renderer_asynchronous_shaders_description">Compila le shaders asincronamente, questo riduce lo shutter ma potrebbe introdurre dei glitch. </string> 189 <string name="renderer_asynchronous_shaders_description">Compila le shader in modo asincrone, riducendo lo stutter. Può causare glitch grafici.</string>
146 <string name="renderer_debug">Abilità il debug grafico</string> 190 <string name="renderer_reactive_flushing">Abilita il Reactive Flushing</string>
147 <string name="renderer_debug_description">Quando l\'opzione è selezionata, l\'API grafica entra in una modalità di debug più lenta</string> 191 <string name="renderer_reactive_flushing_description">Migliora l\'accuratezza della grafica in alcuni giochi, al costo delle performance.</string>
148 <string name="use_disk_shader_cache">Usa cache shader su disco</string> 192 <string name="use_disk_shader_cache">Usa la cache delle shader</string>
149 <string name="use_disk_shader_cache_description">Riduce lo stuttering salvando e caricando le shader generate sul disco.</string> 193 <string name="use_disk_shader_cache_description">Riduce lo stuttering caricando le shader già compilate all\'avvio.</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">Debug della CPU</string>
198 <string name="cpu_debug_mode_description">Imposta la CPU in modalità Debug (Più lento)</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
201 <string name="renderer_debug">Debug GPU</string>
202 <string name="renderer_debug_description">Imposta l\'API grafica in uno stato dedicato al Debugging. Impatta di molto sulle performance.</string>
203 <string name="fastmem">Fastmem</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">Motore di Output</string>
152 <string name="audio_volume">Volume</string> 207 <string name="audio_volume">Volume</string>
153 <string name="audio_volume_description">Specifica il volume dell\'audio in uscita.</string> 208 <string name="audio_volume_description">Specifica il volume dell\'audio in uscita.</string>
154 209
@@ -157,14 +212,24 @@
157 <string name="ini_saved">Impostazioni salvate</string> 212 <string name="ini_saved">Impostazioni salvate</string>
158 <string name="gameid_saved">Impostazioni salvate per %1$s</string> 213 <string name="gameid_saved">Impostazioni salvate per %1$s</string>
159 <string name="error_saving">Errore nel salvare %1$s.ini %2$s</string> 214 <string name="error_saving">Errore nel salvare %1$s.ini %2$s</string>
215 <string name="unimplemented_menu">Menu non implementato</string>
160 <string name="loading">Caricamento…</string> 216 <string name="loading">Caricamento…</string>
217 <string name="shutting_down">Spegnimento...</string>
161 <string name="reset_setting_confirmation">Vuoi ripristinare queste impostazioni al loro valore originale?</string> 218 <string name="reset_setting_confirmation">Vuoi ripristinare queste impostazioni al loro valore originale?</string>
162 <string name="reset_to_default">Riportare alle impostazioni originali</string> 219 <string name="reset_to_default">Riportare alle impostazioni originali</string>
163 <string name="reset_all_settings">Resettare tutte le impostazioni?</string> 220 <string name="reset_all_settings">Resettare tutte le impostazioni?</string>
164 <string name="reset_all_settings_description">Tutte le Impostazioni Avanzate saranno ripristinate a quelle originali. Questa operazione non è reversibile</string> 221 <string name="reset_all_settings_description">Le impostazione avanzate verranno completamente reimpostate. Questa operazione è IRREVERSIBILE.</string>
165 <string name="settings_reset">Reimposta le impostazioni</string> 222 <string name="settings_reset">Reimposta le impostazioni</string>
166 <string name="close">Chiudi</string> 223 <string name="close">Chiudi</string>
167 <string name="learn_more">Per saperne di più</string> 224 <string name="learn_more">Per saperne di più</string>
225 <string name="auto">Automatico</string>
226 <string name="submit">Invia</string>
227 <string name="string_null">Nullo</string>
228 <string name="string_import">Importa</string>
229 <string name="export">Esporta</string>
230 <string name="export_failed">Esportazione Fallita</string>
231 <string name="import_failed">Importazione Fallita</string>
232 <string name="cancelling">Cancellazione</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Seleziona il driver della GPU</string> 235 <string name="select_gpu_driver">Seleziona il driver della GPU</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">Installa</string> 237 <string name="select_gpu_driver_install">Installa</string>
173 <string name="select_gpu_driver_default">Predefinito</string> 238 <string name="select_gpu_driver_default">Predefinito</string>
174 <string name="select_gpu_driver_use_default">Utilizza il driver predefinito della GPU.</string> 239 <string name="select_gpu_driver_use_default">Utilizza il driver predefinito della GPU.</string>
240 <string name="select_gpu_driver_error">Il driver selezionato è invalido, è in utilizzo quello predefinito di sistema!</string>
175 <string name="system_gpu_driver">Driver GPU del sistema</string> 241 <string name="system_gpu_driver">Driver GPU del sistema</string>
176 <string name="installing_driver">Installando i driver...</string> 242 <string name="installing_driver">Installando i driver...</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">Grafica</string> 248 <string name="preferences_graphics">Grafica</string>
183 <string name="preferences_audio">Audio</string> 249 <string name="preferences_audio">Audio</string>
184 <string name="preferences_theme">Tema e colori</string> 250 <string name="preferences_theme">Tema e colori</string>
251 <string name="preferences_debug">Debug</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">La tua ROM è criptata</string> 254 <string name="loader_error_encrypted">La tua ROM è criptata</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Per favore segui la guida per eseguire il dump della <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartuccia di gioco</a> o i <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titoli installati</a>.]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[Segui la nostra guida per fare il <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">dump delle tue cartucce di gioco</a>oppure <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">dei titoli già installati</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Per favore assicurati che il file <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> sia installato in modo che i giochi possano essere decrittati.]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[Per favore assicurati che il file <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> sia installato in modo che i giochi possano essere decrittati.]]></string>
190 <string name="loader_error_video_core">È stato riscontrato un errore nell\'inizializzazione del core video</string> 257 <string name="loader_error_video_core">È stato riscontrato un errore nell\'inizializzazione del core video</string>
191 <string name="loader_error_video_core_description">Questo è causato solitamente dal driver incompatibile di una GPU. L\'installazione di driver GPU personalizzati potrebbe risolvere questo problema.</string> 258 <string name="loader_error_video_core_description">Questo è causato solitamente dal driver incompatibile di una GPU. L\'installazione di driver GPU personalizzati potrebbe risolvere questo problema.</string>
@@ -193,28 +260,28 @@
193 <string name="loader_error_file_not_found">Il file della ROM non esiste</string> 260 <string name="loader_error_file_not_found">Il file della ROM non esiste</string>
194 261
195 <!-- Emulation Menu --> 262 <!-- Emulation Menu -->
196 <string name="emulation_exit">Uscire dall\'emulazione</string> 263 <string name="emulation_exit">Arresta emulazione</string>
197 <string name="emulation_done">Fatto</string> 264 <string name="emulation_done">Fatto</string>
198 <string name="emulation_fps_counter">Contatore degli FPS</string> 265 <string name="emulation_fps_counter">Contatore FPS</string>
199 <string name="emulation_toggle_controls">Controlli a interruttore</string> 266 <string name="emulation_toggle_controls">Controlli a interruttore</string>
200 <string name="emulation_rel_stick_center">Centro relativo degli Stick</string> 267 <string name="emulation_rel_stick_center">Centro relativo degli Stick</string>
201 <string name="emulation_dpad_slide">Slittamento del Pad Direzionale</string> 268 <string name="emulation_dpad_slide">DPad A Scorrimento</string>
202 <string name="emulation_haptics">Aptico</string> 269 <string name="emulation_haptics">Feedback Aptico</string>
203 <string name="emulation_show_overlay">Mostra Overlay</string> 270 <string name="emulation_show_overlay">Mostra l\'Overlay</string>
204 <string name="emulation_toggle_all">Attiva/disattiva tutto</string> 271 <string name="emulation_toggle_all">Attiva/Disattiva tutto</string>
205 <string name="emulation_control_adjust">Aggiusta Overlay</string> 272 <string name="emulation_control_adjust">Modifica l\'Overlay</string>
206 <string name="emulation_control_scale">Scala</string> 273 <string name="emulation_control_scale">Scala</string>
207 <string name="emulation_control_opacity">Opacità</string> 274 <string name="emulation_control_opacity">Opacità</string>
208 <string name="emulation_touch_overlay_reset">Reimposta Overlay</string> 275 <string name="emulation_touch_overlay_reset">Reimposta l\'Overlay</string>
209 <string name="emulation_touch_overlay_edit">Modifica Overlay</string> 276 <string name="emulation_touch_overlay_edit">Modifica l\'Overlay</string>
210 <string name="emulation_pause">Metti in pausa l\'emulazione</string> 277 <string name="emulation_pause">Sospendi l\'emulazione</string>
211 <string name="emulation_unpause">Riprendi Emulazione</string> 278 <string name="emulation_unpause">Riprendi l\'emulazione</string>
212 <string name="emulation_input_overlay">Impostazioni Overlay</string> 279 <string name="emulation_input_overlay">Opzioni overlay</string>
213 280
214 <string name="load_settings">Caricamento delle impostazioni...</string> 281 <string name="load_settings">Carico le impostazioni...</string>
215 282
216 <!-- Software keyboard --> 283 <!-- Software keyboard -->
217 <string name="software_keyboard">Tastiera software</string> 284 <string name="software_keyboard">Tastiera Software</string>
218 285
219 <!-- Errors and warnings --> 286 <!-- Errors and warnings -->
220 <string name="abort_button">Interrompi</string> 287 <string name="abort_button">Interrompi</string>
@@ -226,6 +293,9 @@
226 <string name="fatal_error">Errore Fatale</string> 293 <string name="fatal_error">Errore Fatale</string>
227 <string name="fatal_error_message">Un errore fatale è accaduto. Controlla i log per i dettagli.\nContinuare ad emulare potrebbe portare bug o causare crash.</string> 294 <string name="fatal_error_message">Un errore fatale è accaduto. Controlla i log per i dettagli.\nContinuare ad emulare potrebbe portare bug o causare crash.</string>
228 <string name="performance_warning">Disattivare questa impostazione può ridurre significativamente le performance di emulazione! Per una migliore esperienza, è consigliato lasciare questa impostazione attivata.</string> 295 <string name="performance_warning">Disattivare questa impostazione può ridurre significativamente le performance di emulazione! Per una migliore esperienza, è consigliato lasciare questa impostazione attivata.</string>
296 <string name="device_memory_inadequate">RAM Totale:%1$s\nRaccomandati: %2$s</string>
297 <string name="memory_formatted">%1$s%2$s</string>
298 <string name="no_game_present">Non è presente alcun gioco avviabile.</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">Giappone</string> 301 <string name="region_japan">Giappone</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">Corea</string> 306 <string name="region_korea">Corea</string>
237 <string name="region_taiwan">Taiwan</string> 307 <string name="region_taiwan">Taiwan</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">Kb</string>
312 <string name="memory_megabyte">Mb</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">Tb</string>
315 <string name="memory_petabyte">Pb</string>
316 <string name="memory_exabyte">Eb</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 319 <string name="renderer_vulkan">Vulkan</string>
@@ -274,12 +351,17 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">Layout Orizzontale</string>
356 <string name="screen_layout_portrait">Layout Verticale</string>
357 <string name="screen_layout_auto">Automatico</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">Predefinito (16:9)</string> 360 <string name="ratio_default">Predefinito (16:9)</string>
279 <string name="ratio_force_four_three">Forza 4:3</string> 361 <string name="ratio_force_four_three">Forza 4:3</string>
280 <string name="ratio_force_twenty_one_nine">Forza 21:9</string> 362 <string name="ratio_force_twenty_one_nine">Forza 21:9</string>
281 <string name="ratio_force_sixteen_ten">Forza 16:10</string> 363 <string name="ratio_force_sixteen_ten">Forza 16:10</string>
282 <string name="ratio_stretch">Allunga a finestra</string> 364 <string name="ratio_stretch">Adatta alla finestra</string>
283 365
284 <!-- CPU Accuracy --> 366 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Accurata</string> 367 <string name="cpu_accuracy_accurate">Accurata</string>
@@ -287,9 +369,9 @@
287 <string name="cpu_accuracy_paranoid">Paranoico (Lento)</string> 369 <string name="cpu_accuracy_paranoid">Paranoico (Lento)</string>
288 370
289 <!-- Gamepad Buttons --> 371 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">D-Pad</string> 372 <string name="gamepad_d_pad">D-pad</string>
291 <string name="gamepad_left_stick">Levetta sinistra</string> 373 <string name="gamepad_left_stick">Analogico sinistro</string>
292 <string name="gamepad_right_stick">Levetta destra</string> 374 <string name="gamepad_right_stick">Analogico destro</string>
293 <string name="gamepad_home">Home</string> 375 <string name="gamepad_home">Home</string>
294 <string name="gamepad_screenshot">Screenshot</string> 376 <string name="gamepad_screenshot">Screenshot</string>
295 377
@@ -298,7 +380,7 @@
298 <string name="building_shaders">Costruendo gli shaders</string> 380 <string name="building_shaders">Costruendo gli shaders</string>
299 381
300 <!-- Theme options --> 382 <!-- Theme options -->
301 <string name="change_app_theme">Cambia il tema dell\'app</string> 383 <string name="change_app_theme">Cambia tema dell\'app</string>
302 <string name="theme_default">Predefinito</string> 384 <string name="theme_default">Predefinito</string>
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
@@ -308,8 +390,22 @@
308 <string name="theme_mode_light">Chiaro</string> 390 <string name="theme_mode_light">Chiaro</string>
309 <string name="theme_mode_dark">Scuro</string> 391 <string name="theme_mode_dark">Scuro</string>
310 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
311 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Usa sfondi neri</string> 397 <string name="use_black_backgrounds">Sfondi neri</string>
313 <string name="use_black_backgrounds_description">Quando utilizzi il tema scuro, applica sfondi neri.</string> 398 <string name="use_black_backgrounds_description">Quando utilizzi il tema scuro, applica sfondi neri.</string>
314 399
315</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">Picture in Picture</string>
402 <string name="picture_in_picture_description">Minimizza la finestra quando viene impostata in background</string>
403 <string name="pause">Pausa</string>
404 <string name="play">Gioca</string>
405 <string name="mute">Silenzia</string>
406 <string name="unmute">Riattiva</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">Licenze</string>
410 <string name="license_fidelityfx_fsr_description">Upscaling di alta qualità da parte di AMD</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml
index a0ea78bef..3be4e7d26 100644
--- a/src/android/app/src/main/res/values-ja/strings.xml
+++ b/src/android/app/src/main/res/values-ja/strings.xml
@@ -1,11 +1,12 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">ã“ã®ã‚½ãƒ•トウェアã¯ã€Nintendo Switch用ã®ã‚²ãƒ¼ãƒ ã‚’実行ã—ã¾ã™ã€‚ ゲームソフトやキーã¯å«ã¾ã‚Œã¾ã›ã‚“。&lt;br /&gt;&lt;br /&gt;事å‰ã«ã€ <![CDATA[<b> prod.keys </b>]]> ファイルをデãƒã‚¤ã‚¹ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã«é…ç½®ã—ã¦ãŠã„ã¦ãã ã•ã„。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">詳細</a>]]></string> 4 <string name="app_disclaimer">ã“ã®ã‚½ãƒ•トウェアã§ã¯ã€Nintendo Switchã®ã‚²ãƒ¼ãƒ ã‚’実行ã§ãã¾ã™ã€‚ ゲームソフトやキーã¯å«ã¾ã‚Œã¾ã›ã‚“。&lt;br /&gt;&lt;br /&gt;事å‰ã«ã€ <![CDATA[<b> prod.keys </b>]]> ファイルをストレージã«é…ç½®ã—ã¦ãŠã„ã¦ãã ã•ã„。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">詳細</a>]]></string>
5 <string name="emulation_notification_channel_name">ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åйã§ã™</string> 5 <string name="emulation_notification_channel_name">ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæœ‰åйã§ã™</string>
6 <string name="emulation_notification_channel_description">エミュレーションã®å®Ÿè¡Œä¸­ã«å¸¸è¨­é€šçŸ¥ã‚’表示ã—ã¾ã™ã€‚</string> 6 <string name="emulation_notification_channel_description">エミュレーションã®å®Ÿè¡Œä¸­ã«å¸¸è¨­é€šçŸ¥ã‚’表示ã—ã¾ã™ã€‚</string>
7 <string name="emulation_notification_running">yuzu ã¯å®Ÿè¡Œä¸­ã§ã™</string> 7 <string name="emulation_notification_running">yuzu ã¯å®Ÿè¡Œä¸­ã§ã™</string>
8 <string name="notice_notification_channel_description">å•題ãŒç™ºç”Ÿã—ãŸã¨ãã«é€šçŸ¥ã‚’表示ã—ã¾ã™ã€‚</string> 8 <string name="notice_notification_channel_name">通知ã¨ã‚¨ãƒ©ãƒ¼</string>
9 <string name="notice_notification_channel_description">å•題ã®ç™ºç”Ÿæ™‚ã«é€šçŸ¥ã‚’表示ã—ã¾ã™ã€‚</string>
9 <string name="notification_permission_not_granted">通知ãŒè¨±å¯ã•れã¦ã„ã¾ã›ã‚“!</string> 10 <string name="notification_permission_not_granted">通知ãŒè¨±å¯ã•れã¦ã„ã¾ã›ã‚“!</string>
10 11
11 <!-- Setup strings --> 12 <!-- Setup strings -->
@@ -16,7 +17,7 @@
16 <string name="keys_description">下ã®ãƒœã‚¿ãƒ³ã‹ã‚‰ &lt;b>prod.keys&lt;/b> ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„。</string> 17 <string name="keys_description">下ã®ãƒœã‚¿ãƒ³ã‹ã‚‰ &lt;b>prod.keys&lt;/b> ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„。</string>
17 <string name="select_keys">ã‚­ãƒ¼ã‚’é¸æŠž</string> 18 <string name="select_keys">ã‚­ãƒ¼ã‚’é¸æŠž</string>
18 <string name="games">ゲーム</string> 19 <string name="games">ゲーム</string>
19 <string name="games_description">下ã®ãƒœã‚¿ãƒ³ã‹ã‚‰&lt;b>ゲーム&lt;/b>ãŒã‚ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¦ãã ã•ã„。</string> 20 <string name="games_description">下ã®ãƒœã‚¿ãƒ³ã‹ã‚‰&lt;b>ゲーム&lt;/b>ã®ã‚ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¦ãã ã•ã„。</string>
20 <string name="done">完了</string> 21 <string name="done">完了</string>
21 <string name="done_description">準備ãŒå®Œäº†ã—ã¾ã—ãŸã€‚\nã‚²ãƒ¼ãƒ ã‚’ãŠæ¥½ã—ã¿ãã ã•ã„!</string> 22 <string name="done_description">準備ãŒå®Œäº†ã—ã¾ã—ãŸã€‚\nã‚²ãƒ¼ãƒ ã‚’ãŠæ¥½ã—ã¿ãã ã•ã„!</string>
22 <string name="text_continue">続行</string> 23 <string name="text_continue">続行</string>
@@ -24,48 +25,53 @@
24 <string name="back">戻る</string> 25 <string name="back">戻る</string>
25 <string name="add_games">ゲームを追加</string> 26 <string name="add_games">ゲームを追加</string>
26 <string name="add_games_description">ã‚²ãƒ¼ãƒ ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž</string> 27 <string name="add_games_description">ã‚²ãƒ¼ãƒ ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž</string>
28 <string name="step_complete">完了!</string>
27 29
28 <!-- Home strings --> 30 <!-- Home strings -->
29 <string name="home_games">ゲーム</string> 31 <string name="home_games">ゲーム</string>
30 <string name="home_search">検索</string> 32 <string name="home_search">検索</string>
31 <string name="home_settings">設定</string> 33 <string name="home_settings">設定</string>
32 <string name="empty_gamelist">ファイルãŒè¦‹ã¤ã‹ã‚‰ãªã„ã‹ã€ã‚²ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒã¾ã é¸æŠžã•れã¦ã„ã¾ã›ã‚“。</string> 34 <string name="empty_gamelist">ファイルãŒå­˜åœ¨ã—ãªã„ã‹ã‚²ãƒ¼ãƒ ãƒ•ォルダãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“。</string>
33 <string name="search_and_filter_games">ã‚²ãƒ¼ãƒ ã®æ¤œç´¢ã¨çµžã‚Šè¾¼ã¿</string> 35 <string name="search_and_filter_games">ã‚²ãƒ¼ãƒ ã®æ¤œç´¢ã¨çµžã‚Šè¾¼ã¿</string>
34 <string name="select_games_folder">ã‚²ãƒ¼ãƒ ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž</string> 36 <string name="select_games_folder">ゲームフォルダ</string>
35 <string name="select_games_folder_description">yuzu ãŒã‚²ãƒ¼ãƒ ãƒªã‚¹ãƒˆã«è¿½åŠ ã§ãるよã†ã«ã—ã¾ã™</string> 37 <string name="select_games_folder_description">ゲームをyuzuã®ã‚²ãƒ¼ãƒ ãƒªã‚¹ãƒˆã«è¿½åŠ ã—ã¾ã™</string>
36 <string name="add_games_warning">ゲームフォルダã®é¸æŠžã‚’スキップã—ã¾ã™ã‹?</string> 38 <string name="add_games_warning">ゲームフォルダã®é¸æŠžã‚’スキップã—ã¾ã™ã‹?</string>
37 <string name="add_games_warning_description">ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ãªã„å ´åˆã€ã‚²ãƒ¼ãƒ ã¯ã‚²ãƒ¼ãƒ ãƒªã‚¹ãƒˆã«è¡¨ç¤ºã•れã¾ã›ã‚“。</string> 39 <string name="add_games_warning_description">ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ãªã„ã¨ã€ã‚²ãƒ¼ãƒ ãŒãƒªã‚¹ãƒˆã«è¡¨ç¤ºã•れã¾ã›ã‚“。</string>
38 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
39 <string name="home_search_games">ゲームを検索</string> 41 <string name="home_search_games">ゲームを検索</string>
40 <string name="games_dir_selected">ゲームディレクトリãŒé¸æŠžã•れã¾ã—ãŸ</string> 42 <string name="search_settings">検索設定</string>
41 <string name="install_prod_keys">prod.keys をインストール</string> 43 <string name="games_dir_selected">ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¾ã—ãŸ</string>
42 <string name="install_prod_keys_description">ゲームã®å¾©å·åŒ–ã«å¿…è¦</string> 44 <string name="install_prod_keys">prod.keys</string>
45 <string name="install_prod_keys_description">製å“版ゲームã®å¾©å·åŒ–ã«å¿…è¦ã§ã™</string>
43 <string name="install_prod_keys_warning">キーã®è¿½åŠ ã‚’ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™ã‹ï¼Ÿ</string> 46 <string name="install_prod_keys_warning">キーã®è¿½åŠ ã‚’ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™ã‹ï¼Ÿ</string>
44 <string name="install_prod_keys_warning_description">製å“版ゲームã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«ã¯ã€æœ‰åйãªã‚­ãƒ¼ãŒå¿…è¦ã§ã™ã€‚続行ã™ã‚‹ã¨è‡ªä½œã‚¢ãƒ—リã—ã‹æ©Ÿèƒ½ã—ã¾ã›ã‚“。</string> 47 <string name="install_prod_keys_warning_description">製å“版ゲームã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«ã¯ã€æœ‰åйãªã‚­ãƒ¼ãŒå¿…è¦ã§ã™ã€‚続行ã™ã‚‹ã¨è‡ªä½œã‚¢ãƒ—リã—ã‹æ©Ÿèƒ½ã—ã¾ã›ã‚“。</string>
45 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> 48 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
46 <string name="notifications">通知</string> 49 <string name="notifications">通知</string>
47 <string name="notifications_description">下ã®ãƒœã‚¿ãƒ³ã§é€šçŸ¥ã®æ¨©é™ã‚’許å¯ã—ã¦ãã ã•ã„。</string> 50 <string name="notifications_description">下ã®ãƒœã‚¿ãƒ³ã§é€šçŸ¥ã‚’許å¯ã—ã¦ãã ã•ã„。</string>
48 <string name="give_permission">許å¯</string> 51 <string name="give_permission">許å¯</string>
49 <string name="notification_warning">通知ã®è¨±å¯ã‚’スキップã—ã¾ã™ã‹ï¼Ÿ</string> 52 <string name="notification_warning">通知ã®è¨±å¯ã‚’スキップã—ã¾ã™ã‹ï¼Ÿ</string>
50 <string name="notification_warning_description">yuzuã¯é‡è¦ãªãŠçŸ¥ã‚‰ã›ã‚’通知ã§ãã¾ã›ã‚“。</string> 53 <string name="notification_warning_description">yuzuã¯é‡è¦ãªãŠçŸ¥ã‚‰ã›ã‚’通知ã§ãã¾ã›ã‚“。</string>
51 <string name="permission_denied">権é™ãŒæ‹’å¦ã•れã¾ã—ãŸ</string> 54 <string name="permission_denied">権é™ãŒæ‹’å¦ã•れã¾ã—ãŸ</string>
52 <string name="permission_denied_description">ã“ã®æ¨©é™ã‚’複数回拒å¦ã—ãŸãŸã‚ã€ã‚·ã‚¹ãƒ†ãƒ è¨­å®šã§æ‰‹å‹•ã§è¨±å¯ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚</string> 55 <string name="permission_denied_description">ã“ã®æ¨©é™ã‚’複数回拒å¦ã—ãŸãŸã‚ã€è¨­å®šã‹ã‚‰æ‰‹å‹•ã§è¨±å¯ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚</string>
53 <string name="about">情報</string> 56 <string name="about">情報</string>
54 <string name="about_description">ビルドãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆãªã©</string> 57 <string name="about_description">ビルドãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆãªã©</string>
55 <string name="warning_help">ヘルプ</string> 58 <string name="warning_help">ヘルプ</string>
56 <string name="warning_skip">スキップ</string> 59 <string name="warning_skip">スキップ</string>
57 <string name="warning_cancel">キャンセル</string> 60 <string name="warning_cancel">キャンセル</string>
58 <string name="install_amiibo_keys">Amiibo キーをインストール</string> 61 <string name="install_amiibo_keys">Amiibo</string>
59 <string name="install_amiibo_keys_description">ゲーム内ã§ã® Amiibo ã®ä½¿ç”¨ã«å¿…è¦</string> 62 <string name="install_amiibo_keys_description">ゲーム内ã§ã® Amiibo ã®ä½¿ç”¨ã«å¿…è¦ã§ã™</string>
60 <string name="invalid_keys_file">無効ãªã‚­ãƒ¼ãƒ•ァイルãŒé¸æŠžã•れã¾ã—ãŸ</string> 63 <string name="invalid_keys_file">無効ãªã‚­ãƒ¼ãƒ•ァイルã§ã</string>
61 <string name="install_keys_success">正常ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¾ã—ãŸ</string> 64 <string name="install_keys_success">正常ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¾ã—ãŸ</string>
62 <string name="reading_keys_failure">æš—å·åŒ–キーã®èª­ã¿å–りエラー</string> 65 <string name="reading_keys_failure">æš—å·åŒ–キーã®èª­ã¿è¾¼ã¿å¤±æ•—</string>
63 <string name="invalid_keys_error">æš—å·åŒ–キーãŒç„¡åйã§ã™</string> 66 <string name="install_prod_keys_failure_extension_description">ã‚­ãƒ¼ã®æ‹¡å¼µå­ãŒ.keysã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã€å†åº¦ãŠè©¦ã—ãã ã•ã„。</string>
67 <string name="install_amiibo_keys_failure_extension_description">ã‚­ãƒ¼ã®æ‹¡å¼µå­ãŒ.binã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã€å†åº¦ãŠè©¦ã—ãã ã•ã„。</string>
68 <string name="invalid_keys_error">æš—å·åŒ–キーãŒç„¡åй</string>
64 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
65 <string name="install_keys_failure_description">é¸æŠžã•れãŸãƒ•ァイルãŒä¸æ­£ã¾ãŸã¯ç ´æã—ã¦ã„ã¾ã™ã€‚キーをå†ãƒ€ãƒ³ãƒ—ã—ã¦ãã ã•ã„。</string> 70 <string name="install_keys_failure_description">ファイルãŒé–“é•ã£ã¦ã„ã‚‹ã‹ç ´æã—ã¦ã„ã¾ã™ã€‚キーをå†ãƒ€ãƒ³ãƒ—ã—ã¦ãã ã•ã„。</string>
66 <string name="install_gpu_driver">GPUドライãƒãƒ¼ã‚’インストール</string> 71 <string name="install_gpu_driver">GPUドライãƒãƒ¼</string>
67 <string name="install_gpu_driver_description">代替ドライãƒãƒ¼ã‚’インストールã—ã¦ãƒ‘フォーマンスや精度をå‘上ã•ã›ã¾ã™</string> 72 <string name="install_gpu_driver_description">代替ドライãƒãƒ¼ã‚’インストールã—ã¦ãƒ‘フォーマンスや精度をå‘上ã•ã›ã¾ã™</string>
68 <string name="advanced_settings">高度ãªè¨­å®š</string> 73 <string name="advanced_settings">高度ãªè¨­å®š</string>
74 <string name="advanced_settings_game">高度ãªè¨­å®š: %1$s</string>
69 <string name="settings_description">エミュレーターã®è¨­å®šã‚’æ§‹æˆã—ã¾ã™</string> 75 <string name="settings_description">エミュレーターã®è¨­å®šã‚’æ§‹æˆã—ã¾ã™</string>
70 <string name="search_recently_played">最近プレイã—ãŸ</string> 76 <string name="search_recently_played">最近プレイã—ãŸ</string>
71 <string name="search_recently_added">最近追加ã•れãŸ</string> 77 <string name="search_recently_added">最近追加ã•れãŸ</string>
@@ -77,15 +83,34 @@
77 <string name="no_file_manager">ファイルマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ</string> 83 <string name="no_file_manager">ファイルマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ</string>
78 <string name="notification_no_directory_link">yuzuã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é–‹ã‘ã¾ã›ã‚“</string> 84 <string name="notification_no_directory_link">yuzuã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é–‹ã‘ã¾ã›ã‚“</string>
79 <string name="notification_no_directory_link_description">ファイルマãƒãƒ¼ã‚¸ãƒ£ã®ã‚µã‚¤ãƒ‰ãƒ‘ãƒãƒ«ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ•ã‚©ãƒ«ãƒ€ã‚’æ‰‹å‹•ã§æŽ¢ã—ã¦ãã ã•ã„。</string> 85 <string name="notification_no_directory_link_description">ファイルマãƒãƒ¼ã‚¸ãƒ£ã®ã‚µã‚¤ãƒ‰ãƒ‘ãƒãƒ«ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ•ã‚©ãƒ«ãƒ€ã‚’æ‰‹å‹•ã§æŽ¢ã—ã¦ãã ã•ã„。</string>
80 <string name="manage_save_data">セーブデータを管ç†</string> 86 <string name="manage_save_data">セーブデータ</string>
81 <string name="manage_save_data_description">セーブデータãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚以下ã®ã‚ªãƒ—ションã‹ã‚‰é¸æŠžã—ã¦ãã ã•ã„。</string> 87 <string name="manage_save_data_description">セーブデータãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚æ“ä½œã‚’é¸æŠžã—ã¦ãã ã•ã„。</string>
82 <string name="import_export_saves_description">セーブファイルをインãƒãƒ¼ãƒˆ/エクスãƒãƒ¼ãƒˆ</string> 88 <string name="import_export_saves_description">セーブファイルをインãƒãƒ¼ãƒˆ/エクスãƒãƒ¼ãƒˆ</string>
83 <string name="save_file_imported_success">インãƒãƒ¼ãƒˆãŒå®Œäº†ã—ã¾ã—ãŸ</string> 89 <string name="save_file_imported_success">インãƒãƒ¼ãƒˆãŒå®Œäº†ã—ã¾ã—ãŸ</string>
84 <string name="save_file_invalid_zip_structure">セーブデータã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªæ§‹é€ ãŒç„¡åйã§ã™</string> 90 <string name="save_file_invalid_zip_structure">セーブデータã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªæ§‹é€ ãŒç„¡åй</string>
85 <string name="save_file_invalid_zip_structure_description">最åˆã®ã‚µãƒ–フォルダåã¯ã€ã‚²ãƒ¼ãƒ ã®ã‚¿ã‚¤ãƒˆãƒ«IDã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚</string> 91 <string name="save_file_invalid_zip_structure_description">最åˆã®ã‚µãƒ–フォルダåã¯ã€ã‚²ãƒ¼ãƒ ã®ã‚¿ã‚¤ãƒˆãƒ«IDã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚</string>
86 <string name="import_saves">インãƒãƒ¼ãƒˆ</string> 92 <string name="import_saves">インãƒãƒ¼ãƒˆ</string>
87 <string name="export_saves">エクスãƒãƒ¼ãƒˆ</string> 93 <string name="export_saves">エクスãƒãƒ¼ãƒˆ</string>
88 94 <string name="install_firmware">ファームウェア</string>
95 <string name="install_firmware_description">ファームウェアã¯ZIPアーカイブã§ã‚ã‚‹å¿…è¦ãŒã‚りã€ä¸€éƒ¨ã®ã‚²ãƒ¼ãƒ ã‚’èµ·å‹•ã™ã‚‹ã®ã«å¿…è¦ã§ã™</string>
96 <string name="firmware_installing">ファームウェアをインストール中</string>
97 <string name="firmware_installed_success">インストールãŒå®Œäº†ã—ã¾ã—ãŸ</string>
98 <string name="firmware_installed_failure">インストール失敗</string>
99 <string name="share_log">デãƒãƒƒã‚°ãƒ­ã‚°</string>
100 <string name="share_log_description">yuzuã®ãƒ­ã‚°ãƒ•ァイルを共有ã—ã¦å•題をデãƒãƒƒã‚°ã—ã¾ã™</string>
101 <string name="share_log_missing">ログãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</string>
102 <string name="install_game_content">追加コンテンツ</string>
103 <string name="install_game_content_description">更新データやDLCをインストールã—ã¾ã™</string>
104 <string name="installing_game_content">コンテンツをインストール中...</string>
105 <string name="install_game_content_failure_file_extension">NSPã¨XCIå½¢å¼ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚ã‚²ãƒ¼ãƒ ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒæœ‰åйãªã‚‚ã®ã§ã‚ã‚‹ã‹ã”確èªãã ã•ã„。</string>
106 <string name="install_game_content_failed_count">%1$d ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚¨ãƒ©ãƒ¼</string>
107 <string name="install_game_content_success">ゲームコンテンツã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«æˆåŠŸã—ã¾ã—ãŸ</string>
108 <string name="install_game_content_success_install">%1$d ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«æˆåŠŸã—ã¾ã—ãŸ</string>
109 <string name="install_game_content_success_overwrite">%1$d ã®ä¸Šæ›¸ãã«æˆåŠŸã—ã¾ã—ãŸ</string>
110 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
111 <string name="custom_driver_not_supported">カスタムドライãƒã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“</string>
112 <string name="manage_yuzu_data">yuzu データを管ç†</string>
113 <string name="share_save_file">セーブファイルを共有</string>
89 <!-- About screen strings --> 114 <!-- About screen strings -->
90 <string name="gaia_is_not_real">ガイアã¯å®Ÿåœ¨ã—ãªã„</string> 115 <string name="gaia_is_not_real">ガイアã¯å®Ÿåœ¨ã—ãªã„</string>
91 <string name="copied_to_clipboard">クリップボードã«ã‚³ãƒ”ーã—ã¾ã—ãŸ</string> 116 <string name="copied_to_clipboard">クリップボードã«ã‚³ãƒ”ーã—ã¾ã—ãŸ</string>
@@ -93,7 +118,15 @@
93 <string name="contributors">貢献者</string> 118 <string name="contributors">貢献者</string>
94 <string name="contributors_description">yuzuãƒãƒ¼ãƒ ã®\u2764ã§ä½œã‚‰ã‚ŒãŸ</string> 119 <string name="contributors_description">yuzuãƒãƒ¼ãƒ ã®\u2764ã§ä½œã‚‰ã‚ŒãŸ</string>
95 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 120 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
121 <string name="licenses_description">yuzu for Androidã®ä½œæˆã‚’å¯èƒ½ã«ã—ãŸãƒ—ロジェクト</string>
96 <string name="build">ビルド</string> 122 <string name="build">ビルド</string>
123 <string name="user_data">ユーザデータ</string>
124 <string name="exporting_user_data">ユーザデータをエクスãƒãƒ¼ãƒˆä¸­...</string>
125 <string name="importing_user_data">ユーザデータをインãƒãƒ¼ãƒˆä¸­...</string>
126 <string name="import_user_data">ユーザデータをインãƒãƒ¼ãƒˆ</string>
127 <string name="user_data_export_success">ユーザデータã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã«æˆåŠŸã—ã¾ã—ãŸ</string>
128 <string name="user_data_import_success">ユーザデータã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«æˆåŠŸã—ã¾ã—ãŸ</string>
129 <string name="user_data_export_cancelled">エクスãƒãƒ¼ãƒˆã‚’キャンセルã—ã¾ã—ãŸ</string>
97 <string name="support_link">https://discord.gg/u77vRWY</string> 130 <string name="support_link">https://discord.gg/u77vRWY</string>
98 <string name="website_link">https://yuzu-emu.org/</string> 131 <string name="website_link">https://yuzu-emu.org/</string>
99 <string name="github_link">https://github.com/yuzu-emu</string> 132 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -105,72 +138,91 @@
105 <string name="get_early_access_description">æœ€å…ˆç«¯ã®æ©Ÿèƒ½ã€ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã®æ—©æœŸã‚¢ã‚¯ã‚»ã‚¹ãªã©</string> 138 <string name="get_early_access_description">æœ€å…ˆç«¯ã®æ©Ÿèƒ½ã€ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã®æ—©æœŸã‚¢ã‚¯ã‚»ã‚¹ãªã©</string>
106 <string name="early_access_benefits">早期アクセスã®ãƒ¡ãƒªãƒƒãƒˆ</string> 139 <string name="early_access_benefits">早期アクセスã®ãƒ¡ãƒªãƒƒãƒˆ</string>
107 <string name="cutting_edge_features">æœ€å…ˆç«¯ã®æ©Ÿèƒ½</string> 140 <string name="cutting_edge_features">æœ€å…ˆç«¯ã®æ©Ÿèƒ½</string>
108 <string name="early_access_updates">ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆã®æ—©æœŸã‚¢ã‚¯ã‚»ã‚¹</string> 141 <string name="early_access_updates">アップデートã¸ã®æ—©æœŸã‚¢ã‚¯ã‚»ã‚¹</string>
109 <string name="no_manual_installation">手動インストールãŒä¸è¦</string> 142 <string name="no_manual_installation">手動インストールãŒä¸è¦</string>
110 <string name="prioritized_support">優先的ãªã‚µãƒãƒ¼ãƒˆ</string> 143 <string name="prioritized_support">優先サãƒãƒ¼ãƒˆ</string>
111 <string name="helping_game_preservation">ゲームã®ä¿å­˜ã«è²¢çŒ®</string> 144 <string name="helping_game_preservation">ゲームã®ä¿å­˜ã«è²¢çŒ®</string>
112 <string name="our_eternal_gratitude">ç§ãŸã¡ã®æ°¸é ã®æ„Ÿè¬</string> 145 <string name="our_eternal_gratitude">ç§ãŸã¡ã‹ã‚‰æ°¸é ã®æ„Ÿè¬</string>
113 <string name="are_you_interested">興味ãŒã‚りã¾ã™ã‹ï¼Ÿ</string> 146 <string name="are_you_interested">興味ãŒã‚りã¾ã™ã‹ï¼Ÿ</string>
114 147
115 <!-- General settings strings --> 148 <!-- General settings strings -->
116 <string name="frame_limit_enable">速度制é™ã‚’有効化</string> 149 <string name="frame_limit_enable">エミュレーション速度を制é™</string>
117 <string name="frame_limit_enable_description">有効ã«ã™ã‚‹ã¨ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³é€Ÿåº¦ãŒä»»æ„ã®å‰²åˆã«åˆ¶é™ã•れã¾ã™ã€‚</string> 150 <string name="frame_limit_enable_description">エミュレーション速度を指定ã—ãŸå‰²åˆã«åˆ¶é™ã—ã¾ã™ã€‚</string>
118 <string name="frame_limit_slider">エミュレーション速度ã®åˆ¶é™</string> 151 <string name="frame_limit_slider">エミュレーション速度</string>
119 <string name="frame_limit_slider_description">エミュレーション速度を制é™ã™ã‚‹å‰²åˆã‚’指定ã—ã¾ã™ã€‚デフォルトã®100%ã§ã¯ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯é€šå¸¸ã®é€Ÿåº¦ã«åˆ¶é™ã•れã¾ã™ã€‚値ãŒé«˜ã„ã¾ãŸã¯ä½Žã„ã»ã©ã€é€Ÿåº¦åˆ¶é™ãŒå¢—加ã¾ãŸã¯æ¸›å°‘ã—ã¾ã™ã€‚</string> 152 <string name="frame_limit_slider_description">エミュレーション速度を制é™ã™ã‚‹ãƒ‘ーセンテージを指定ã—ã¾ã™ã€‚100%ã¯é€šå¸¸é€Ÿåº¦ã§ã™ã€‚値ã®å¢—減ã§é€Ÿåº¦ã‚‚増減ã—ã¾ã™ã€‚</string>
120 <string name="cpu_accuracy">CPU精度</string> 153 <string name="cpu_accuracy">CPU精度</string>
121
122 <!-- System settings strings --> 154 <!-- System settings strings -->
123 <string name="use_docked_mode">TVモード</string> 155 <string name="use_docked_mode">TVモード</string>
124 <string name="use_docked_mode_description">TVモードã§ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ãƒˆã—ã¾ã™ã€‚パフォーマンスãŒçŠ ç‰²ã«ãªã‚Šã¾ã™ãŒã€è§£åƒåº¦ãŒå‘上ã—ã¾ã™ã€‚</string> 156 <string name="use_docked_mode_description">高解åƒåº¦ã€ä½Žãƒ‘フォーマンス。無効時ã«ã¯æºå¸¯ãƒ¢ãƒ¼ãƒ‰ãŒä½¿ç”¨ã•れã¾ã™ï¼ˆä½Žè§£åƒåº¦ã€é«˜ãƒ‘フォーマンス)。</string>
125 <string name="emulated_region">地域</string> 157 <string name="emulated_region">地域</string>
126 <string name="emulated_language">言語</string> 158 <string name="emulated_language">言語</string>
127 <string name="select_rtc_date">RTCã®æ—¥ä»˜ã‚’é¸æŠž</string> 159 <string name="select_rtc_date">RTCã®æ—¥ä»˜ã‚’é¸æŠž</string>
128 <string name="select_rtc_time">RTCã®æ™‚åˆ»ã‚’é¸æŠž</string> 160 <string name="select_rtc_time">RTCã®æ™‚åˆ»ã‚’é¸æŠž</string>
129 <string name="use_custom_rtc">カスタムRTC</string> 161 <string name="use_custom_rtc">カスタム RTC</string>
130 <string name="use_custom_rtc_description">ç¾åœ¨ã®ã‚·ã‚¹ãƒ†ãƒ æ™‚é–“ã¨ã¯åˆ¥ã«ã‚«ã‚¹ã‚¿ãƒ ã®ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ã‚¯ãƒ­ãƒƒã‚¯ã‚’設定ã§ãã¾ã™ã€‚</string> 162 <string name="use_custom_rtc_description">ç¾åœ¨ã®ã‚·ã‚¹ãƒ†ãƒ æ™‚é–“ã¨ã¯åˆ¥ã«ã€ä»»æ„ã®ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ã‚¯ãƒ­ãƒƒã‚¯ã‚’設定ã§ãã¾ã™ã€‚</string>
131 <string name="set_custom_rtc">カスタムRTCを設定</string> 163 <string name="set_custom_rtc">カスタムRTCを設定</string>
132 164
133 <!-- Graphics settings strings --> 165 <!-- Graphics settings strings -->
134 <string name="renderer_api">API</string>
135 <string name="renderer_accuracy">精度</string> 166 <string name="renderer_accuracy">精度</string>
136 <string name="renderer_resolution">è§£åƒåº¦</string> 167 <string name="renderer_resolution">è§£åƒåº¦ï¼ˆæºå¸¯ãƒ¢ãƒ¼ãƒ‰/TVモード)</string>
137 <string name="renderer_vsync">åž‚ç›´åŒæœŸãƒ¢ãƒ¼ãƒ‰</string> 168 <string name="renderer_vsync">åž‚ç›´åŒæœŸãƒ¢ãƒ¼ãƒ‰</string>
169 <string name="renderer_screen_layout">ç”»é¢ã®å‘ã</string>
138 <string name="renderer_aspect_ratio">アスペクト比</string> 170 <string name="renderer_aspect_ratio">アスペクト比</string>
139 <string name="renderer_scaling_filter">ウィンドウé©å¿œãƒ•ィルター</string> 171 <string name="renderer_scaling_filter">ウィンドウé©å¿œãƒ•ィルター</string>
140 <string name="renderer_anti_aliasing">アンãƒã‚¨ã‚¤ãƒªã‚¢ã‚¹æ–¹å¼</string> 172 <string name="renderer_anti_aliasing">アンãƒã‚¨ã‚¤ãƒªã‚¢ã‚¹æ–¹å¼</string>
141 <string name="renderer_force_max_clock">最大クロックを強制 (Adrenoã®ã¿)</string> 173 <string name="renderer_force_max_clock">最大クロックを強制 (Adrenoã®ã¿)</string>
142 <string name="renderer_force_max_clock_description">GPUã‚’å¯èƒ½ãªé™ã‚Šæœ€å¤§ã‚¯ãƒ­ãƒƒã‚¯ã§å‹•作ã•ã›ã¾ã™ (éŽç†±åˆ¶é™ã¯å¼•ãç¶šãé©ç”¨ã•れã¾ã™)。</string> 174 <string name="renderer_force_max_clock_description">GPUを最大é™å¯èƒ½ãªå‘¨æ³¢æ•°ã§å‹•作ã•ã›ã¾ã™ (éŽç†±åˆ¶é™ã¯å¼•ãç¶šãé©ç”¨ã•れã¾ã™)。</string>
143 <string name="renderer_asynchronous_shaders">éžåŒæœŸã‚·ã‚§ãƒ¼ãƒ€ãƒ¼</string> 175 <string name="renderer_asynchronous_shaders">éžåŒæœŸã‚·ã‚§ãƒ¼ãƒ€ãƒ¼</string>
144 <string name="renderer_asynchronous_shaders_description">シェーダーをéžåŒæœŸã§ã‚³ãƒ³ãƒ‘イルã—ã¾ã™ã€‚コマè½ã¡ãŒè»½æ¸›ã•れã¾ã™ãŒã€ä¸å…·åˆãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string> 176 <string name="renderer_asynchronous_shaders_description">シェーダーをéžåŒæœŸã§ã‚³ãƒ³ãƒ‘イルã—ã¾ã™ã€‚コマè½ã¡ãŒè»½æ¸›ã•れã¾ã™ãŒã€ä¸å…·åˆãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string>
177 <string name="renderer_reactive_flushing">峿™‚書ãè¾¼ã¿</string>
178 <string name="renderer_reactive_flushing_description">一部ã®ã‚²ãƒ¼ãƒ ã«ãŠã„ã¦ã€ãƒ‘フォーマンスを犠牲ã«ã—ãªãŒã‚‰ã‚‚ã€ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ç²¾åº¦ã‚’å‘上ã•ã›ã¾ã™ã€‚</string>
179 <string name="use_disk_shader_cache">ディスクシェーダーキャッシュ</string>
180 <string name="use_disk_shader_cache_description">生æˆã—ãŸã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã‚’端末ã«ä¿å­˜ã—ã¦èª­ã¿è¾¼ã¿ã€ã‚³ãƒžè½ã¡ã‚’軽減ã—ã¾ã™ã€‚</string>
181
182 <!-- Debug settings strings -->
183 <string name="cpu">CPU</string>
184 <string name="cpu_debug_mode">CPU デãƒãƒƒã‚®ãƒ³ã‚°</string>
185 <string name="gpu">GPU</string>
186 <string name="renderer_api">API</string>
145 <string name="renderer_debug">グラフィックデãƒãƒƒã‚°</string> 187 <string name="renderer_debug">グラフィックデãƒãƒƒã‚°</string>
146 <string name="renderer_debug_description">オンã«ã™ã‚‹ã¨ã€ã‚°ãƒ©ãƒ•ィックAPI ã¯ä½Žé€Ÿã®ãƒ‡ãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã«å…¥ã‚Šã¾ã™ã€‚</string> 188 <string name="renderer_debug_description">グラフィックAPIを低速デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã«è¨­å®šã—ã¾ã™ã€‚</string>
147 <string name="use_disk_shader_cache">シェーダーキャッシュを使用</string> 189 <string name="fastmem">Fastmem</string>
148 <string name="use_disk_shader_cache_description">生æˆã—ãŸã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã‚’ディスクã«ä¿å­˜ã—ã¦èª­ã¿è¾¼ã‚€ã“ã¨ã§ã€ã‚³ãƒžè½ã¡ã‚’軽減ã—ã¾ã™ã€‚</string>
149 190
150 <!-- Audio settings strings --> 191 <!-- Audio settings strings -->
192 <string name="audio_output_engine">出力エンジン</string>
151 <string name="audio_volume">音é‡</string> 193 <string name="audio_volume">音é‡</string>
152 <string name="audio_volume_description">オーディオ出力ã®éŸ³é‡ã‚’指定ã—ã¾ã™</string> 194 <string name="audio_volume_description">オーディオ出力ã®éŸ³é‡ã‚’指定ã—ã¾ã™</string>
153 195
154 <!-- Miscellaneous --> 196 <!-- Miscellaneous -->
155 <string name="slider_default">デフォルト</string> 197 <string name="slider_default">デフォルト</string>
156 <string name="ini_saved">設定をä¿å­˜ã—ã¾ã—ãŸ</string> 198 <string name="ini_saved">設定をä¿å­˜ã—ã¾ã—ãŸ</string>
157 <string name="gameid_saved">%1$sã®è¨­å®šã‚’ä¿å­˜ã—ã¾ã—ãŸ</string> 199 <string name="gameid_saved">%1$s ã®è¨­å®šã‚’ä¿å­˜ã—ã¾ã—ãŸ</string>
158 <string name="error_saving">%1$s.ini ã®ä¿å­˜ã‚¨ãƒ©ãƒ¼: %2$s</string> 200 <string name="error_saving">%1$s.ini ã®ä¿å­˜ã‚¨ãƒ©ãƒ¼: %2$s</string>
201 <string name="unimplemented_menu">未実装ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼</string>
159 <string name="loading">読ã¿è¾¼ã¿ä¸­â€¦</string> 202 <string name="loading">読ã¿è¾¼ã¿ä¸­â€¦</string>
203 <string name="shutting_down">終了中...</string>
160 <string name="reset_setting_confirmation">ã“ã®è¨­å®šã‚’åˆæœŸå€¤ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã‹?</string> 204 <string name="reset_setting_confirmation">ã“ã®è¨­å®šã‚’åˆæœŸå€¤ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã‹?</string>
161 <string name="reset_to_default">åˆæœŸè¨­å®šã«æˆ»ã™</string> 205 <string name="reset_to_default">åˆæœŸè¨­å®šã«æˆ»ã™</string>
162 <string name="reset_all_settings">ã™ã¹ã¦ã®è¨­å®šã‚’リセットã—ã¾ã™ã‹ï¼Ÿ</string> 206 <string name="reset_all_settings">ã™ã¹ã¦ã®è¨­å®šã‚’リセットã—ã¾ã™ã‹ï¼Ÿ</string>
163 <string name="reset_all_settings_description">ã™ã¹ã¦ã®è©³ç´°è¨­å®šãŒåˆæœŸè¨­å®šã«æˆ»ã•れã¾ã™ã€‚ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。</string> 207 <string name="reset_all_settings_description">ã™ã¹ã¦ã®è©³ç´°è¨­å®šãŒåˆæœŸå€¤ã«æˆ»ã•れã¾ã™ã€‚ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。</string>
164 <string name="settings_reset">設定をリセットã—ã¾ã—ãŸ</string> 208 <string name="settings_reset">設定をリセットã—ã¾ã—ãŸ</string>
165 <string name="close">é–‰ã˜ã‚‹</string> 209 <string name="close">é–‰ã˜ã‚‹</string>
166 <string name="learn_more">詳細情報</string> 210 <string name="learn_more">詳細情報</string>
211 <string name="auto">自動</string>
212 <string name="submit">é€ä¿¡</string>
213 <string name="string_import">インãƒãƒ¼ãƒˆ</string>
214 <string name="export">エクスãƒãƒ¼ãƒˆ</string>
215 <string name="export_failed">エクスãƒãƒ¼ãƒˆå¤±æ•—</string>
216 <string name="import_failed">インãƒãƒ¼ãƒˆå¤±æ•—</string>
217 <string name="cancelling">キャンセル中</string>
167 218
168 <!-- GPU driver installation --> 219 <!-- GPU driver installation -->
169 <string name="select_gpu_driver">GPUドライãƒã‚’é¸æŠž</string> 220 <string name="select_gpu_driver">GPUドライãƒã‚’é¸æŠž</string>
170 <string name="select_gpu_driver_title">ç¾åœ¨ã®GPUドライãƒãƒ¼ã‚’ç½®ãæ›ãˆã¾ã™ã‹ï¼Ÿ</string> 221 <string name="select_gpu_driver_title">ç¾åœ¨ã®GPUドライãƒã‚’ç½®ãæ›ãˆã¾ã™ã‹ï¼Ÿ</string>
171 <string name="select_gpu_driver_install">インストール</string> 222 <string name="select_gpu_driver_install">インストール</string>
172 <string name="select_gpu_driver_default">デフォルト</string> 223 <string name="select_gpu_driver_default">デフォルト</string>
173 <string name="select_gpu_driver_use_default">デフォルトã®GPUドライãƒãƒ¼ã‚’使用ã—ã¾ã™</string> 224 <string name="select_gpu_driver_use_default">デフォルトã®ãƒ‰ãƒ©ã‚¤ãƒã‚’使用ã—ã¾ã™</string>
225 <string name="select_gpu_driver_error">é¸æŠžã•れãŸãƒ‰ãƒ©ã‚¤ãƒãŒç„¡åйã€ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルトを使用ã—ã¾ã™!</string>
174 <string name="system_gpu_driver">システムã®GPUドライãƒ</string> 226 <string name="system_gpu_driver">システムã®GPUドライãƒ</string>
175 <string name="installing_driver">インストール中…</string> 227 <string name="installing_driver">インストール中…</string>
176 228
@@ -181,33 +233,34 @@
181 <string name="preferences_graphics">グラフィック</string> 233 <string name="preferences_graphics">グラフィック</string>
182 <string name="preferences_audio">サウンド</string> 234 <string name="preferences_audio">サウンド</string>
183 <string name="preferences_theme">テーマã¨è‰²</string> 235 <string name="preferences_theme">テーマã¨è‰²</string>
236 <string name="preferences_debug">デãƒãƒƒã‚°</string>
184 237
185 <!-- ROM loading errors --> 238 <!-- ROM loading errors -->
186 <string name="loader_error_encrypted">ROMãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™</string> 239 <string name="loader_error_encrypted">ROMãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™</string>
187 <string name="loader_error_encrypted_roms_description"><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">ゲームカートリッジ</a>ã‚„<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">インストール済ã¿ã®ã‚¿ã‚¤ãƒˆãƒ«</a>ã‚’å†åº¦ãƒ€ãƒ³ãƒ—ã™ã‚‹ãŸã‚ã®ã‚¬ã‚¤ãƒ‰ã«å¾“ã£ã¦ãã ã•ã„。]]></string> 240 <string name="loader_error_encrypted_keys_description"><![CDATA[ゲームã®å¾©å·åŒ–ã«å¿…è¦ãª <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> ファイルãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。]]></string>
188 <string name="loader_error_encrypted_keys_description"><![CDATA[ゲームを復å·åŒ–ã™ã‚‹ãŸã‚ã« <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> ファイルãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。]]></string>
189 <string name="loader_error_video_core">ビデオコアã®åˆæœŸåŒ–中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ</string> 241 <string name="loader_error_video_core">ビデオコアã®åˆæœŸåŒ–中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ</string>
190 <string name="loader_error_video_core_description">ã“れã¯é€šå¸¸ã€äº’æ›æ€§ã®ãªã„GPUドライãƒãƒ¼ãŒåŽŸå› ã§ç™ºç”Ÿã—ã¾ã™ã€‚ カスタムGPUドライãƒãƒ¼ã‚’インストールã™ã‚‹ã¨ã€å•題ãŒè§£æ±ºã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string> 242 <string name="loader_error_video_core_description">ã“れã¯é€šå¸¸ã€äº’æ›æ€§ã®ãªã„GPUドライãƒãƒ¼ãŒåŽŸå› ã§ç™ºç”Ÿã—ã¾ã™ã€‚ カスタムGPUドライãƒãƒ¼ã‚’インストールã™ã‚‹ã¨ã€å•題ãŒè§£æ±ºã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string>
191 <string name="loader_error_invalid_format">ROMã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ</string> 243 <string name="loader_error_invalid_format">ROMã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ</string>
192 <string name="loader_error_file_not_found">ROMファイルãŒå­˜åœ¨ã—ã¾ã›ã‚“</string> 244 <string name="loader_error_file_not_found">ROMファイルãŒå­˜åœ¨ã—ã¾ã›ã‚“</string>
193 245
194 <!-- Emulation Menu --> 246 <!-- Emulation Menu -->
195 <string name="emulation_exit">エミュレーションを終了</string> 247 <string name="emulation_exit">終了</string>
196 <string name="emulation_done">完了</string> 248 <string name="emulation_done">完了</string>
197 <string name="emulation_fps_counter">FPSカウンター</string> 249 <string name="emulation_fps_counter">FPSカウンター</string>
198 <string name="emulation_toggle_controls">コントロールを切り替ãˆ</string> 250 <string name="emulation_toggle_controls">ボタンã®è¡¨ç¤ºè¨­å®š</string>
199 <string name="emulation_dpad_slide">å字キーã®ã‚¹ãƒ©ã‚¤ãƒ‰æ“作</string> 251 <string name="emulation_rel_stick_center">スティックを固定ã—ãªã„</string>
200 <string name="emulation_haptics">振動</string> 252 <string name="emulation_dpad_slide">å字キーをスライドæ“作</string>
201 <string name="emulation_show_overlay">オーãƒãƒ¼ãƒ¬ã‚¤ã‚’表示</string> 253 <string name="emulation_haptics">ã‚¿ãƒƒãƒæŒ¯å‹•</string>
202 <string name="emulation_toggle_all">ã™ã¹ã¦é¸æŠž</string> 254 <string name="emulation_show_overlay">ボタンを表示</string>
203 <string name="emulation_control_adjust">オーãƒãƒ¼ãƒ¬ã‚¤ã‚’調整</string> 255 <string name="emulation_toggle_all">ã™ã¹ã¦åˆ‡æ›¿</string>
256 <string name="emulation_control_adjust">見ãŸç›®ã‚’調整</string>
204 <string name="emulation_control_scale">大ãã•</string> 257 <string name="emulation_control_scale">大ãã•</string>
205 <string name="emulation_control_opacity">ä¸é€æ˜Žåº¦</string> 258 <string name="emulation_control_opacity">ä¸é€æ˜Žåº¦</string>
206 <string name="emulation_touch_overlay_reset">リセット</string> 259 <string name="emulation_touch_overlay_reset">リセット</string>
207 <string name="emulation_touch_overlay_edit">オーãƒãƒ¼ãƒ¬ã‚¤ã‚’編集</string> 260 <string name="emulation_touch_overlay_edit">ä½ç½®ã‚’編集</string>
208 <string name="emulation_pause">ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ä¸€æ™‚åœæ­¢</string> 261 <string name="emulation_pause">ä¸€æ™‚åœæ­¢</string>
209 <string name="emulation_unpause">エミュレーションをå†é–‹</string> 262 <string name="emulation_unpause">å†é–‹</string>
210 <string name="emulation_input_overlay">オーãƒãƒ¼ãƒ¬ã‚¤ã‚ªãƒ—ション</string> 263 <string name="emulation_input_overlay">表示オプション</string>
211 264
212 <string name="load_settings">設定をロード中…</string> 265 <string name="load_settings">設定をロード中…</string>
213 266
@@ -220,10 +273,13 @@
220 <string name="system_archive_not_found">システムアーカイブãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</string> 273 <string name="system_archive_not_found">システムアーカイブãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</string>
221 <string name="system_archive_not_found_message">%s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。システムアーカイブをダンプã—ã¦ãã ã•ã„。\nエミュレーションを続行ã™ã‚‹ã¨ã€ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚„ãƒã‚°ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string> 274 <string name="system_archive_not_found_message">%s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。システムアーカイブをダンプã—ã¦ãã ã•ã„。\nエミュレーションを続行ã™ã‚‹ã¨ã€ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚„ãƒã‚°ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string>
222 <string name="system_archive_general">システムアーカイブ</string> 275 <string name="system_archive_general">システムアーカイブ</string>
223 <string name="save_load_error">セーブ/ロード エラー</string> 276 <string name="save_load_error">セーブ/ロードエラー</string>
224 <string name="fatal_error">致命的ãªã‚¨ãƒ©ãƒ¼</string> 277 <string name="fatal_error">致命的ãªã‚¨ãƒ©ãƒ¼</string>
225 <string name="fatal_error_message">致命的ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚詳細ã¯ãƒ­ã‚°ã‚’確èªã—ã¦ãã ã•ã„。\nエミュレーションを続行ã™ã‚‹ã¨ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚„ãƒã‚°ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string> 278 <string name="fatal_error_message">致命的ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚詳細ã¯ãƒ­ã‚°ã‚’確èªã—ã¦ãã ã•ã„。\nエミュレーションを続行ã™ã‚‹ã¨ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚„ãƒã‚°ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚</string>
226 <string name="performance_warning">ã“ã®è¨­å®šã‚’オフã«ã™ã‚‹ã¨ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ãƒ‘フォーマンスãŒè‘—ã—ã低下ã—ã¾ã™ï¼æœ€é«˜ã®ä½“験を得るãŸã‚ã«ã¯ã€ã“ã®è¨­å®šã‚’有効ã«ã—ã¦ãŠãã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚</string> 279 <string name="performance_warning">ã“ã®è¨­å®šã‚’オフã«ã™ã‚‹ã¨ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ãƒ‘フォーマンスãŒè‘—ã—ã低下ã—ã¾ã™ï¼æœ€é«˜ã®ä½“験を得るãŸã‚ã«ã¯ã€ã“ã®è¨­å®šã‚’有効ã«ã—ã¦ãŠãã“ã¨ã‚’推奨ã—ã¾ã™ã€‚</string>
280 <string name="device_memory_inadequate">デãƒã‚¤ã‚¹ RAM: %1$s\n推奨: %2$s</string>
281 <string name="memory_formatted">%1$s %2$s</string>
282 <string name="no_game_present">èµ·å‹•ã§ãるゲームãŒã‚りã¾ã›ã‚“!</string>
227 283
228 <!-- Region Names --> 284 <!-- Region Names -->
229 <string name="region_japan">日本</string> 285 <string name="region_japan">日本</string>
@@ -234,7 +290,14 @@
234 <string name="region_korea">韓国</string> 290 <string name="region_korea">韓国</string>
235 <string name="region_taiwan">å°æ¹¾</string> 291 <string name="region_taiwan">å°æ¹¾</string>
236 292
237 <!-- Language Names --> 293 <!-- Memory Sizes -->
294 <string name="memory_byte">Byte</string>
295 <string name="memory_kilobyte">KB</string>
296 <string name="memory_megabyte">MB</string>
297 <string name="memory_gigabyte">GB</string>
298 <string name="memory_terabyte">TB</string>
299 <string name="memory_petabyte">PB</string>
300 <string name="memory_exabyte">EB</string>
238 301
239 <!-- Renderer APIs --> 302 <!-- Renderer APIs -->
240 <string name="renderer_vulkan">Vulkan</string> 303 <string name="renderer_vulkan">Vulkan</string>
@@ -242,7 +305,7 @@
242 305
243 <!-- Renderer Accuracy --> 306 <!-- Renderer Accuracy -->
244 <string name="renderer_accuracy_normal">標準</string> 307 <string name="renderer_accuracy_normal">標準</string>
245 <string name="renderer_accuracy_high">高ã„</string> 308 <string name="renderer_accuracy_high">高</string>
246 <string name="renderer_accuracy_extreme">最高 (低速)</string> 309 <string name="renderer_accuracy_extreme">最高 (低速)</string>
247 310
248 <!-- Resolutions --> 311 <!-- Resolutions -->
@@ -272,12 +335,17 @@
272 <string name="anti_aliasing_fxaa">FXAA</string> 335 <string name="anti_aliasing_fxaa">FXAA</string>
273 <string name="anti_aliasing_smaa">SMAA</string> 336 <string name="anti_aliasing_smaa">SMAA</string>
274 337
338 <!-- Screen Layouts -->
339 <string name="screen_layout_landscape">横長</string>
340 <string name="screen_layout_portrait">縦長</string>
341 <string name="screen_layout_auto">自動</string>
342
275 <!-- Aspect Ratios --> 343 <!-- Aspect Ratios -->
276 <string name="ratio_default">デフォルト (16:9)</string> 344 <string name="ratio_default">デフォルト (16:9)</string>
277 <string name="ratio_force_four_three">強制 4:3</string> 345 <string name="ratio_force_four_three">強制 4:3</string>
278 <string name="ratio_force_twenty_one_nine">強制 21:9</string> 346 <string name="ratio_force_twenty_one_nine">強制 21:9</string>
279 <string name="ratio_force_sixteen_ten">強制 16:10</string> 347 <string name="ratio_force_sixteen_ten">強制 16:10</string>
280 <string name="ratio_stretch">ウィンドウã«åˆã‚ã›ã‚‹</string> 348 <string name="ratio_stretch">ç”»é¢ã«åˆã‚ã›ã‚‹</string>
281 349
282 <!-- CPU Accuracy --> 350 <!-- CPU Accuracy -->
283 <string name="cpu_accuracy_accurate">正確</string> 351 <string name="cpu_accuracy_accurate">正確</string>
@@ -289,7 +357,7 @@
289 <string name="gamepad_left_stick">Lスティック</string> 357 <string name="gamepad_left_stick">Lスティック</string>
290 <string name="gamepad_right_stick">Rスティック</string> 358 <string name="gamepad_right_stick">Rスティック</string>
291 <string name="gamepad_home">HOMEボタン</string> 359 <string name="gamepad_home">HOMEボタン</string>
292 <string name="gamepad_screenshot">スクリーンショット</string> 360 <string name="gamepad_screenshot">キャãƒãƒãƒ£ãƒ¼ãƒœã‚¿ãƒ³</string>
293 361
294 <!-- Disk shader cache --> 362 <!-- Disk shader cache -->
295 <string name="preparing_shaders">シェーダーを準備ã—ã¦ã„ã¾ã™</string> 363 <string name="preparing_shaders">シェーダーを準備ã—ã¦ã„ã¾ã™</string>
@@ -306,8 +374,22 @@
306 <string name="theme_mode_light">ライト</string> 374 <string name="theme_mode_light">ライト</string>
307 <string name="theme_mode_dark">ダーク</string> 375 <string name="theme_mode_dark">ダーク</string>
308 376
309 <!-- Black backgrounds theme --> 377 <!-- Audio output engines -->
310 <string name="use_black_backgrounds">黒色ã®èƒŒæ™¯ã‚’使用</string> 378 <string name="cubeb">cubeb</string>
311 <string name="use_black_backgrounds_description">ダークテーマã®ä½¿ç”¨æ™‚ã¯ã€é»’色ã®èƒŒæ™¯ã‚’有効ã«ã—ã¦ãã ã•ã„。</string>
312 379
313</resources> 380 <!-- Black backgrounds theme -->
381 <string name="use_black_backgrounds">完全ãªé»’を使用</string>
382 <string name="use_black_backgrounds_description">ダークテーマã®èƒŒæ™¯è‰²ã«é»’ãŒé©ç”¨ã•れã¾ã™ã€‚</string>
383
384 <!-- Picture-In-Picture -->
385 <string name="picture_in_picture">ピクãƒãƒ£ãƒ¼ã‚¤ãƒ³ãƒ”クãƒãƒ£ãƒ¼</string>
386 <string name="picture_in_picture_description">ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰æ™‚ã«ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã‚’最å°åŒ–ã™ã‚‹</string>
387 <string name="pause">中断</string>
388 <string name="play">プレイ</string>
389 <string name="mute">消音</string>
390 <string name="unmute">消音解除</string>
391
392 <!-- Licenses screen strings -->
393 <string name="licenses">ライセンス</string>
394 <string name="license_fidelityfx_fsr_description">AMDã®é«˜å“質アップスケーリング</string>
395 </resources>
diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml
index 214f95706..1b9160a23 100644
--- a/src/android/app/src/main/res/values-ko/strings.xml
+++ b/src/android/app/src/main/res/values-ko/strings.xml
@@ -1,9 +1,9 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">ì´ ì†Œí”„íŠ¸ì›¨ì–´ëŠ” 닌í…ë„ ìŠ¤ìœ„ì¹˜ 게임 콘솔용 ê²Œìž„ì„ ì‹¤í–‰í•©ë‹ˆë‹¤. 게임 타ì´í‹€ì´ë‚˜ keys는 í¬í•¨ë˜ì–´ 있지 않습니다.&lt;br /&gt;&lt;br /&gt;시작하기 ì „ì— ìž¥ì¹˜ 저장소ì—서 <![CDATA[<b> prod.keys </b>]]> 파ì¼ì„ 찾아주세요.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">ìžì„¸ížˆ 알아보기</a>]]></string> 4 <string name="app_disclaimer">ì´ ì†Œí”„íŠ¸ì›¨ì–´ëŠ” Nintendo Switch ê²Œìž„ì„ ì‹¤í–‰í•©ë‹ˆë‹¤. 게임 타ì´í‹€ì´ë‚˜ 키는 í¬í•¨ë˜ì–´ 있지 않습니다.&lt;br /&gt;&lt;br /&gt;시작하기 ì „ì— ìž¥ì¹˜ 저장소ì—서 <![CDATA[<b> prod.keys </b>]]> 파ì¼ì„ 찾아주세요.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">ìžì„¸ížˆ 알아보기</a>]]></string>
5 <string name="emulation_notification_channel_name">ì—뮬레ì´ì…˜ì´ 활성화ë¨</string> 5 <string name="emulation_notification_channel_name">ì—뮬레ì´ì…˜ì´ 활성화ë¨</string>
6 <string name="emulation_notification_channel_description">ì—뮬레ì´ì…˜ì´ 실행 ì¤‘ì¼ ë•Œ ì˜êµ¬ ì•Œë¦¼ì„ í‘œì‹œí•©ë‹ˆë‹¤.</string> 6 <string name="emulation_notification_channel_description">ì—뮬레ì´ì…˜ì´ 실행 ì¤‘ì¼ ë•Œ ì§€ì†ì ìœ¼ë¡œ ì•Œë¦¼ì„ í‘œì‹œí•©ë‹ˆë‹¤.</string>
7 <string name="emulation_notification_running">yuzu가 실행 중입니다.</string> 7 <string name="emulation_notification_running">yuzu가 실행 중입니다.</string>
8 <string name="notice_notification_channel_name">알림 ë° ì˜¤ë¥˜</string> 8 <string name="notice_notification_channel_name">알림 ë° ì˜¤ë¥˜</string>
9 <string name="notice_notification_channel_description">문제가 ë°œìƒí•˜ë©´ ì•Œë¦¼ì„ í‘œì‹œí•©ë‹ˆë‹¤.</string> 9 <string name="notice_notification_channel_description">문제가 ë°œìƒí•˜ë©´ ì•Œë¦¼ì„ í‘œì‹œí•©ë‹ˆë‹¤.</string>
@@ -11,26 +11,25 @@
11 11
12 <!-- Setup strings --> 12 <!-- Setup strings -->
13 <string name="welcome">환ì˜í•©ë‹ˆë‹¤!</string> 13 <string name="welcome">환ì˜í•©ë‹ˆë‹¤!</string>
14 <string name="welcome_description">&lt;b>yuzu&lt;/b> 를 설정하고 ì—뮬레ì´ì…˜ìœ¼ë¡œ ì´ë™í•˜ëŠ” ë°©ë²•ì„ ì•Œì•„ë³´ì„¸ìš”.</string> 14 <string name="welcome_description">&lt;b>yuzu&lt;/b>를 설정하고 ì—뮬레ì´ì…˜ì„ 시작하세요.</string>
15 <string name="get_started">시작하기</string> 15 <string name="get_started">시작하기</string>
16 <string name="keys">Keys</string> 16 <string name="keys">키 설정</string>
17 <string name="keys_description">아래 버튼ì 사용하여 &lt;b>prod.keys&lt;/b> 파ì¼ì„ ì„ íƒí•©ë‹ˆë‹¤.</string> 17 <string name="keys_description">아래 버튼으로 &lt;b>prod.keys&lt;/b> 파ì¼ì„ ì„ íƒí•©ë‹ˆë‹¤.</string>
18 <string name="select_keys">keys ì„ íƒ</string> 18 <string name="select_keys">키 ì„ íƒ</string>
19 <string name="games">게임</string> 19 <string name="games">게임</string>
20 <string name="games_description">아래 버튼으로 &lt;b>게임&lt;/b> í´ë”를 ì„ íƒí•©ë‹ˆë‹¤.</string> 20 <string name="games_description">아래 버튼으로 &lt;b>게임&lt;/b> í´ë”를 ì„ íƒí•©ë‹ˆë‹¤.</string>
21 <string name="done">완료</string> 21 <string name="done">완료</string>
22 <string name="done_description">모든 준비가 완료ë˜ì—ˆìŠµë‹ˆë‹¤.\nê²Œìž„ì„ ì¦ê¸°ì„¸ìš”!</string> 22 <string name="done_description">모ë 준비ë˜ì—ˆìŠµë‹ˆë‹¤.\nê²Œìž„ì„ ì¦ê¸°ì„¸ìš”!</string>
23 <string name="text_continue">계ì†</string> 23 <string name="text_continue">계ì†</string>
24 <string name="next">다ìŒ</string> 24 <string name="next">다ìŒ</string>
25 <string name="back">뒤로</string> 25 <string name="back">ì´ì „</string>
26 <string name="add_games">게임 추가</string> 26 <string name="add_games">게임 추가</string>
27 <string name="add_games_description">게임 í´ë” ì„ íƒ</string> 27 <string name="add_games_description">게임 í´ë” ì„ íƒ</string>
28
29 <!-- Home strings --> 28 <!-- Home strings -->
30 <string name="home_games">게임</string> 29 <string name="home_games">게임</string>
31 <string name="home_search">검색</string> 30 <string name="home_search">검색</string>
32 <string name="home_settings">설정</string> 31 <string name="home_settings">설정</string>
33 <string name="empty_gamelist">파ì¼ì„ ì°¾ì„ ìˆ˜ 없거나 ì•„ì§ ê²Œìž„ 디렉토리를 ì„ íƒí•˜ì§€ 않았습니다.</string> 32 <string name="empty_gamelist">파ì¼ì„ ì°¾ì„ ìˆ˜ 없거나 ì•„ì§ ê²Œìž„ 디렉터리를 ì„ íƒí•˜ì§€ 않았습니다.</string>
34 <string name="search_and_filter_games">게임 검색 ë° í•„í„°ë§</string> 33 <string name="search_and_filter_games">게임 검색 ë° í•„í„°ë§</string>
35 <string name="select_games_folder">게임 í´ë” ì„ íƒ</string> 34 <string name="select_games_folder">게임 í´ë” ì„ íƒ</string>
36 <string name="select_games_folder_description">yuzuê°€ 게임 목ë¡ì„ 채울 수 있ë„ë¡ í—ˆìš©</string> 35 <string name="select_games_folder_description">yuzuê°€ 게임 목ë¡ì„ 채울 수 있ë„ë¡ í—ˆìš©</string>
@@ -38,140 +37,160 @@
38 <string name="add_games_warning_description">í´ë”를 ì„ íƒí•˜ì§€ 않으면 게임 목ë¡ì— ê²Œìž„ì´ í‘œì‹œë˜ì§€ 않습니다.</string> 37 <string name="add_games_warning_description">í´ë”를 ì„ íƒí•˜ì§€ 않으면 게임 목ë¡ì— ê²Œìž„ì´ í‘œì‹œë˜ì§€ 않습니다.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 38 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">게임 검색</string> 39 <string name="home_search_games">게임 검색</string>
41 <string name="games_dir_selected">게임 디렉터리 ì„ íƒ</string> 40 <string name="games_dir_selected">게임 디렉터리를 설ì í–ˆìŠµë‹ˆë‹¤.</string>
42 <string name="install_prod_keys">prod.keys 설치</string> 41 <string name="install_prod_keys">prod.keys 설치</string>
43 <string name="install_prod_keys_description">íŒë§¤ìš© 게임 암호 í•´ë…ì— ìš”êµ¬</string> 42 <string name="install_prod_keys_description">패키지 게임 암호 í•´ë…ì— í•„ìš”</string>
44 <string name="install_prod_keys_warning">keys 추가를 건너뛰겠습니까?</string> 43 <string name="install_prod_keys_warning">키 추가를 건너뛰겠습니까?</string>
45 <string name="install_prod_keys_warning_description">ì •í’ˆ ê²Œìž„ì„ ì—뮬레ì´íŠ¸í•˜ë ¤ë©´ 유효한 keysê°€ 필요합니다. 계ì†í•˜ë©´ ìžì²´ 제작 앱만 ìž‘ë™í•©ë‹ˆë‹¤.</string> 44 <string name="install_prod_keys_warning_description">패키지 ê²Œìž„ì„ ì—뮬레ì´íŠ¸í•˜ë ¤ë©´ 유효한 키 ê°’ì´ í•„ìš”í•©ë‹ˆë‹¤. ì´ ë‹¨ê³„ë¥¼ 건너뛰면 홈브류 게임만 실행할 수 있습니다.</string>
46 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> 45 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
47 <string name="notifications">알림</string> 46 <string name="notifications">알림</string>
48 <string name="notifications_description">아래 버튼으로 알림 ê¶Œí•œì„ ë¶€ì—¬í•©ë‹ˆë‹¤.</string> 47 <string name="notifications_description">아래 버튼으로 알림 ê¶Œí•œì„ ë¶€ì—¬í•©ë‹ˆë‹¤.</string>
49 <string name="give_permission">ê¶Œíœ ë¶€ì—¬</string> 48 <string name="give_permission">ìŒë¦¼ 켜기</string>
50 <string name="notification_warning">알림 권한 부여를 건너뛰겠습니까?</string> 49 <string name="notification_warning">알림ì ë„겠습니까?</string>
51 <string name="notification_warning_description">yuzu는 중요한 정보를 알려드리지 않습니다.</string> 50 <string name="notification_warning_description">yuzu가 중요한 정보를 알려드리지 않습니다.</string>
52 <string name="permission_denied">권한 ê±°ë¶€ë¨</string> 51 <string name="permission_denied">권한 ê±°ë¶€ë¨</string>
53 <string name="permission_denied_description">ì´ ê¶Œí•œì„ ë„ˆë¬´ ë§Žì´ ê±°ë¶€í–ˆìœ¼ë¯€ë¡œ ì´ì œ 시스템 설정ì—서 수ë™ìœ¼ë¡œ ê¶Œí•œì„ ë¶€ì—¬í•´ì•¼ 합니다.</string> 52 <string name="permission_denied_description">권한 í—ˆìš©ì„ ë„ˆë¬´ ë§Žì´ ê±°ë¶€í•˜ì—¬ 시스템 설정ì—서 수ë™ìœ¼ë¡œ ê¶Œí•œì„ ë¶€ì—¬í•´ì•¼ 합니다.</string>
54 <string name="about">ì •ë³´</string> 53 <string name="about">ì •ë³´</string>
55 <string name="about_description">빌드 버전, í¬ë ˆë”§ 등</string> 54 <string name="about_description">빌드 버전, í¬ë ˆë”§ 등</string>
56 <string name="warning_help">ë„움ë§</string> 55 <string name="warning_help">ë„움ë§</string>
57 <string name="warning_skip">건너뛰기</string> 56 <string name="warning_skip">건너뛰기</string>
58 <string name="warning_cancel">취소</string> 57 <string name="warning_cancel">취소</string>
59 <string name="install_amiibo_keys">Amiibo keys 설치</string> 58 <string name="install_amiibo_keys">amiibo 키 설치</string>
60 <string name="install_amiibo_keys_description">게임ì—서 아미보 사용 시 í•„ìš”</string> 59 <string name="install_amiibo_keys_description">게임ì—서 amiibo 사용 시 í•„ìš”</string>
61 <string name="invalid_keys_file">ìž˜ëª»ëœ keys íŒŒì¼ ì„ íƒ</string> 60 <string name="invalid_keys_file">ìž˜ëª»ëœ í‚¤ 파ì¼ì´ ì„ íƒë¨</string>
62 <string name="install_keys_success">keysê°€ 성공ì ìœ¼ë¡œ 설치ë¨</string> 61 <string name="install_keys_success">키 ê°’ì„ ì„¤ì¹˜í–ˆìŠµë‹ˆë‹¤.</string>
63 <string name="reading_keys_failure">암호화 keys ì½ê¸° 오류</string> 62 <string name="reading_keys_failure">암호화 키 ì½ê¸° 오류</string>
64 <string name="invalid_keys_error">ìž˜ëª»ëœ ì•”í˜¸í™” keys</string> 63 <string name="install_prod_keys_failure_extension_description">키 파ì¼ì˜ 확장ìžê°€ .keysì¸ì§€ 확ì¸í•˜ê³  다시 시ë„하세요.</string>
64 <string name="install_amiibo_keys_failure_extension_description">키 파ì¼ì˜ 확장ìžê°€ .binì¸ì§€ 확ì¸í•˜ê³  다시 시ë„하세요.</string>
65 <string name="invalid_keys_error">암호화 키가 올바르지 않ìŒ</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">ì„ íƒí•œ 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤. keys를 다시 ë¤í”„하세요.</string> 67 <string name="install_keys_failure_description">ì„ íƒí•œ 파ì¼ì´ 잘못ë˜ì—ˆê±°ë‚˜ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤. 키를 다시 ë¤í”„하세요.</string>
67 <string name="install_gpu_driver">GPU 드ë¼ì´ë²„ 설치</string> 68 <string name="install_gpu_driver">GPU 드ë¼ì´ë²„ 설치</string>
68 <string name="install_gpu_driver_description">잠재ì ìœ¼ë¡œ ë” ë‚˜ì€ ì„±ëŠ¥ ë˜ëŠ” ì •í™•ì„±ì„ ìœ„í•´ 대체 드ë¼ì´ë²„를 설치하세요.</string> 69 <string name="install_gpu_driver_description">잠재ì ìœ¼ë¡œ ë” ë‚˜ì€ ì„±ëŠ¥ ë˜ëŠ” ì •í™•ì„±ì„ ìœ„í•´ 대체 드ë¼ì´ë²„를 설치하세요.</string>
69 <string name="advanced_settings">고급 설정</string> 70 <string name="advanced_settings">고급 설정</string>
70 <string name="settings_description">ì—뮬레ì´í„° 설정 구성</string> 71 <string name="settings_description">ì—뮬레ì´í„° 설정 구성</string>
71 <string name="search_recently_played">최근 플레ì´í•œ 게임</string> 72 <string name="search_recently_played">최근 플레ì´</string>
72 <string name="search_recently_added">최근 추가한 게임</string> 73 <string name="search_recently_added">최근 추가</string>
73 <string name="search_retail">íŒë§¤ìš©</string> 74 <string name="search_retail">패키지</string>
74 <string name="search_homebrew">홈브류</string> 75 <string name="search_homebrew">홈브류</string>
75 <string name="open_user_folder">yuzu í´ë” 열기</string> 76 <string name="open_user_folder">yuzu í´ë” 열기</string>
76 <string name="open_user_folder_description">yuzuì˜ ë‚´ë¶€ íŒŒì¼ ê´€ë¦¬</string> 77 <string name="open_user_folder_description">yuzuì˜ ë‚´ë¶€ íŒŒì¼ ê´€ë¦¬</string>
77 <string name="theme_and_color_description">앱 모양 수정</string> 78 <string name="theme_and_color_description">앱 ë””ìžì¸ 편집</string>
78 <string name="no_file_manager">íŒŒì¼ ê´€ë¦¬ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ</string> 79 <string name="no_file_manager">íŒŒì¼ ê´€ë¦¬ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ</string>
79 <string name="notification_no_directory_link">yuzu 디렉토리를 ì—´ 수 ì—†ìŒ</string> 80 <string name="notification_no_directory_link">yuzu 디렉터리를 ì—´ 수 ì—†ìŒ</string>
80 <string name="notification_no_directory_link_description">íŒŒì¼ ê´€ë¦¬ìžì˜ 사ì´ë“œ 패ë„ì—서 ì‚¬ìš©ìž í´ë”를 수ë™ìœ¼ë¡œ 찾아주세요.</string> 81 <string name="notification_no_directory_link_description">íŒŒì¼ ê´€ë¦¬ìžì˜ 사ì´ë“œ 패ë„ì—서 ì‚¬ìš©ìž í´ë”를 수ë™ìœ¼ë¡œ 찾아주세요.</string>
81 <string name="manage_save_data">저장 ë°ì´í„° 관리</string> 82 <string name="manage_save_data">저장 ë°ì´í„° 관리</string>
82 <string name="manage_save_data_description">ë°ì´í„°ë¥¼ 저장했습니다. 아래ì—서 ì˜µì…˜ì„ ì„ íƒí•˜ì„¸ìš”.</string> 83 <string name="manage_save_data_description">저장 ë°ì´í„°ë¥¼ 발견했습니다. 아래ì—서 ì˜µì…˜ì„ ì„ íƒí•˜ì„¸ìš”.</string>
83 <string name="import_export_saves_description">저장 íŒŒì¼ ê°€ì ¸ì˜¤ê¸° ë˜ëŠ” 내보내기</string> 84 <string name="import_export_saves_description">저장 íŒŒì¼ ê°€ì ¸ì˜¤ê¸° ë˜ëŠ” 내보내기</string>
84 <string name="save_file_imported_success">ê°ì ¸ì˜¤ê¸° 성공</string> 85 <string name="save_file_imported_success">ë°ì´í„°ë¥¼ 불러왔습니다.</string>
85 <string name="save_file_invalid_zip_structure">저장 디렉터리 구조가 잘못ë¨</string> 86 <string name="save_file_invalid_zip_structure">올바르지 ì•Šì€ ì €ìž¥ 디렉터리 구조</string>
86 <string name="save_file_invalid_zip_structure_description">첫 번째 하위 í´ë” ì´ë¦„ì€ ê²Œìž„ì˜ íƒ€ì´í‹€ ID여야 합니다.</string> 87 <string name="save_file_invalid_zip_structure_description">첫 번째 하위 í´ë” ì´ë¦„ì€ ê²Œìž„ì˜ íƒ€ì´í‹€ ID여야 합니다.</string>
87 <string name="import_saves">가져오기</string> 88 <string name="import_saves">가져오기</string>
88 <string name="export_saves">내보내기</string> 89 <string name="export_saves">내보내기</string>
89 90 <string name="install_firmware">펌웨어 설치</string>
91 <string name="install_firmware_description">펌웨어는 ZIP 파ì¼ì´ë©° ì¼ë¶€ ê²Œìž„ì„ ë¶€íŒ…í•˜ëŠ” ë° í•„ìš”í•©ë‹ˆë‹¤.</string>
92 <string name="firmware_installing">펌웨어 설치</string>
93 <string name="firmware_installed_success">펌웨어를 설치했습니다.</string>
94 <string name="firmware_installed_failure">펌웨어 설치 실패</string>
95 <string name="share_log">디버그 로그 공유</string>
96 <string name="share_log_description">yuzuì˜ ë¡œê·¸ 파ì¼ì„ 공유하여 문제 디버깅하기</string>
97 <string name="share_log_missing">로그 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다.</string>
98 <string name="install_game_content">게임 콘í…츠 설치</string>
99 <string name="install_game_content_description">게임 ì—…ë°ì´íЏ ë˜ëŠ” DLC 설치</string>
100 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
90 <!-- About screen strings --> 101 <!-- About screen strings -->
91 <string name="gaia_is_not_real">ê°€ì´ì•„는 진짜가 아님</string> 102 <string name="gaia_is_not_real">ê°€ì´ì•„는 진짜가 아님</string>
92 <string name="copied_to_clipboard">í´ë¦½ë³´ë“œì— 복사</string> 103 <string name="copied_to_clipboard">í´ë¦½ë³´ë“œì— 복사ë˜ì—ˆìŠµë‹ˆë‹¤.</string>
93 <string name="about_app_description">오픈 소스 스위치 ì—뮬레ì´í„°</string> 104 <string name="about_app_description">오픈 소스 Switch ì—뮬레ì´í„°</string>
94 <string name="contributors">기여ìž</string> 105 <string name="contributors">기여ìž</string>
95 <string name="contributors_description">yuzu íŒ€ì˜ \u2764로 제작</string> 106 <string name="contributors_description">yuzu íŒ€ì˜ \u2764로 제작</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 107 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
108 <string name="licenses_description">Androidìš© yuzu를 가능하게 하는 프로ì íЏ</string>
97 <string name="build">빌드</string> 109 <string name="build">빌드</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 110 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 111 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 112 <string name="github_link">https://github.com/yuzu-emu</string>
101 113
102 <!-- Early access upgrade strings --> 114 <!-- Early access upgrade strings -->
103 <string name="early_access">미리 ì²´í—˜í˜ê¸°</string> 115 <string name="early_access">앞서 해보기</string>
104 <string name="get_early_access">미리 ì²´í—˜í˜ê¸° ì‹ ì²­</string> 116 <string name="get_early_access">앞서 해보기 ì‹ ì²­</string>
105 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string> 117 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
106 <string name="get_early_access_description">ìµœì²¨ë¨ ê¸°ëŠ¥, 미리 체험하기 ì—…ë°ì´íЏ 등</string> 118 <string name="get_early_access_description">최신 기능, ì—…ë°ì´íЏ 미리 ì²´í—˜ 등</string>
107 <string name="early_access_benefits">미리 ì²´í—˜í˜ê¸° 혜íƒ</string> 119 <string name="early_access_benefits">앞서 해보기 혜íƒ</string>
108 <string name="cutting_edge_features">ìµœì²¨ë¨ ê¸°ëŠ¥</string> 120 <string name="cutting_edge_features">최신 기능</string>
109 <string name="early_access_updates">미리 체험하기 ì—…ë°ì´íЏ</string> 121 <string name="early_access_updates">ì—…ë°ì´íЏ 미리 ì²´í—˜</string>
110 <string name="no_manual_installation">ìˆ˜ë™ ì„¤ì¹˜ 불필요</string> 122 <string name="no_manual_installation">ìˆ˜ë™ ì„¤ì¹˜ 불필요</string>
111 <string name="prioritized_support">ìš°ì„  ì§€ì›</string> 123 <string name="prioritized_support">ìš°ì„  ì§€ì›</string>
112 <string name="helping_game_preservation">게임 ë³´ì¡´ ë„ì€ì£¼ê¸°</string> 124 <string name="helping_game_preservation">게임 ë³´ì¡´ ì§€ì</string>
113 <string name="our_eternal_gratitude">ì˜ì›í•œ ê°ì‚¬ì˜ 마ìŒì„ 전합니다</string> 125 <string name="our_eternal_gratitude">ìš°ë¦¬ì˜ ì˜ì›í•œ ê°ì‚¬ì˜ 마ìŒ</string>
114 <string name="are_you_interested">관심 있으세요?</string> 126 <string name="are_you_interested">관심 있으세요?</string>
115 127
116 <!-- General settings strings --> 128 <!-- General settings strings -->
117 <string name="frame_limit_enable">제한 ì†ë„ 활성화</string> 129 <string name="frame_limit_enable">ì†ë„ 제한</string>
118 <string name="frame_limit_enable_description">활성화하면 ì—뮬레ì´ì…˜ ì†ë„ê°€ ì •ìƒ ì†ë„ì˜ ì§€ì •ëœ ë¹„ìœ¨ë¡œ 제한ë©ë‹ˆë‹¤.</string> 130 <string name="frame_limit_enable_description">ì—뮬레ì´ì…˜ ì†ë„를 ì •ìƒ ì†ë„ì˜ ì§€ì •ëœ ë¹„ìœ¨ë¡œ 제한합니다.</string>
119 <string name="frame_limit_slider">ì†ë„ 제한 비율</string> 131 <string name="frame_limit_slider">ì†ë„ 제한 비율</string>
120 <string name="frame_limit_slider_description">ì—뮬레ì´ì…˜ ì†ë„를 제한할 ë¹„ìœ¨ì„ ì§€ì •í•©ë‹ˆë‹¤. ê¸°ë³¸ê°’ì¸ 100%로 설정하면 ì—뮬레ì´ì…˜ì´ ì •ìƒ ì†ë„로 제한ë©ë‹ˆë‹¤. ê°’ì´ ë†’ê±°ë‚˜ 낮으면 ì†ë„ ì œí•œì´ ì¦ê°€í•˜ê±°ë‚˜ ê°ì†Œí•©ë‹ˆë‹¤.</string> 132 <string name="frame_limit_slider_description">ì—뮬레ì´ì…˜ ì†ë„ì˜ ì œí•œ ë¹„ìœ¨ì„ ì§€ì •í•©ë‹ˆë‹¤. 100%ê°€ ì •ìƒ ì†ë„입니다. ê°’ì´ ë†’ê±°ë‚˜ 낮으면 ì†ë„ ì œí•œì´ ì¦ê°€í•˜ê±°ë‚˜ ê°ì†Œí•©ë‹ˆë‹¤.</string>
121 <string name="cpu_accuracy">CPU 정확ë„</string> 133 <string name="cpu_accuracy">CPU 정확ë„</string>
122
123 <!-- System settings strings --> 134 <!-- System settings strings -->
124 <string name="use_docked_mode">ë„킹 모드</string> 135 <string name="use_docked_mode">ë 모드</string>
125 <string name="use_docked_mode_description">ë„킹 모드ì—서 ì—뮬레ì´ì…˜í•˜ë©´ ì„±ëŠ¥ì´ ì €í•˜ë˜ëŠ” 대신 í•´ìƒë„ê°€ í–¥ìƒë©ë‹ˆë‹¤.</string> 136 <string name="use_docked_mode_description">í•´ìƒë„를 높ì´ë©° ì„±ëŠ¥ì´ ì €í•˜ë©ë‹ˆë‹¤. 비활성화시 휴대 모드가 사용ë˜ë©° í•´ìƒë„는 낮아지고 ì„±ëŠ¥ì€ í–¥ìƒë©ë‹ˆë‹¤.</string>
126 <string name="emulated_region">ì—뮬레ì´íŠ¸ëœ ì§€ì—­</string> 137 <string name="emulated_region">ì—뮬레ì´íЏ 지역</string>
127 <string name="emulated_language">ì—뮬레ì´íŠ¸ëœ ì–¸ì–´</string> 138 <string name="emulated_language">ì—뮬레ì´íЏ 언어</string>
128 <string name="select_rtc_date">RTC ë‚ ì§œ ì„ íƒ</string> 139 <string name="select_rtc_date">RTC ë‚ ì§œ ì„ íƒ</string>
129 <string name="select_rtc_time">RTC 시간 ì„ íƒ</string> 140 <string name="select_rtc_time">RTC 시간 ì„ íƒ</string>
130 <string name="use_custom_rtc">커스텀 RTC 활성화</string> 141 <string name="use_custom_rtc">ì‚¬ìš©ìž ì§ì • RTC</string>
131 <string name="use_custom_rtc_description">ì´ ì„¤ì •ì„ ì‚¬ìš©í•˜ë©´ 현재 시스템 시간과 별ë„로 ì‚¬ìš©ìž ì§€ì • 실시간 시계를 설정할 수 있ìŒ</string> 142 <string name="use_custom_rtc_description">현재 시스템 시간과 별ë„로 ì‚¬ìš©ìž ì§€ì • 실시간 시계를 설정할 수 있습니다.</string>
132 <string name="set_custom_rtc">커스텀 RTC 설정</string> 143 <string name="set_custom_rtc">ì‚¬ìš©ìž ì§ì • RTC 설정</string>
133 144
134 <!-- Graphics settings strings --> 145 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">ì •í™•ë„ ìˆ˜ì¤€</string> 146 <string name="renderer_accuracy">ì •í™•ë„ ìˆ˜ì¤€</string>
137 <string name="renderer_resolution">í•´ìƒë„</string> 147 <string name="renderer_resolution">í•´ìƒë„ (휴대 모드/ë… ëª¨ë“œ)</string>
138 <string name="renderer_vsync">수ì§ë™ê¸°í™” 모드</string> 148 <string name="renderer_vsync">수ì§ë™ê¸°í™” 모드</string>
139 <string name="renderer_aspect_ratio">화면비</string> 149 <string name="renderer_aspect_ratio">화면비</string>
140 <string name="renderer_scaling_filter">ì°½ ì ì‘ í•„í„°</string> 150 <string name="renderer_scaling_filter">윈ë„ìš° ì ì‘ í•„í„°</string>
141 <string name="renderer_anti_aliasing">안티-ì—ì¼ë¦¬ì–´ì‹± 방법</string> 151 <string name="renderer_anti_aliasing">안티ì—ì¼ë¦¬ì–´ì‹± 방법</string>
142 <string name="renderer_force_max_clock">최대 í´ëŸ­ ê°•ì œ 설정 (아드레노만 해당)</string> 152 <string name="renderer_force_max_clock">최대 í´ëŸ­ ê°•ì œ 설정 (아드레노 ì „ìš©)</string>
143 <string name="renderer_force_max_clock_description">GPUê°€ 가능한 최대 í´ëŸ­ìœ¼ë¡œ 실행ë˜ë„ë¡ ê°•ì œí•©ë‹ˆë‹¤ (ì—´ 제약 ì¡°ê±´ì€ ì—¬ì „ížˆ ì ìš©ë©ë‹ˆë‹¤).</string> 153 <string name="renderer_force_max_clock_description">GPUê°€ 가능한 최대 í´ëŸ­ìœ¼ë¡œ 실행ë˜ë„ë¡ ê°•ì œí•©ë‹ˆë‹¤ (ì—´ 제약 ì¡°ê±´ì€ ì—¬ì „ížˆ ì ìš©ë©ë‹ˆë‹¤).</string>
144 <string name="renderer_asynchronous_shaders">비ë™ê¸° ì…°ì´ë” 사용</string> 154 <string name="renderer_asynchronous_shaders">비ë™ê¸° ì…°ì´ë” 사용</string>
145 <string name="renderer_asynchronous_shaders_description">ì…°ì´ë”를 비ë™ê¸°ì‹ìœ¼ë¡œ 컴파ì¼í•˜ë¯€ë¡œ ëŠê¹€ 현ìƒì´ 줄어들지만 글리치가 ë°œìƒí•  수 있습니다.</string> 155 <string name="renderer_asynchronous_shaders_description">ì…°ì´ë”를 비ë™ê¸°ì‹ìœ¼ë¡œ 컴파ì¼í•˜ì—¬ ëŠê¹€ 현ìƒì„ 줄ì´ì§€ë§Œ 글리치가 ë°œìƒí•  수 있습니다.</string>
146 <string name="renderer_debug">그래픽 디버깅 활성화</string> 156 <string name="renderer_reactive_flushing">ë°˜ì‘형 플러싱 사용</string>
147 <string name="renderer_debug_description">ì´ ì˜µì…˜ì„ ì„ íƒí•˜ë©´ 그래픽 APIê°€ ëŠë¦° 디버깅 모드로 전환ë©ë‹ˆë‹¤.</string> 157 <string name="renderer_reactive_flushing_description">ì¼ë¶€ 게임ì—서 성능 저하를 ê°ìˆ˜í•˜ê³  ë Œë”ë§ ì •í™•ë„를 í–¥ìƒí•©ë‹ˆë‹¤.</string>
148 <string name="use_disk_shader_cache">ë””ìŠ¤í¬ ì…°ì´ë” ìºì‹œ 사용</string> 158 <string name="use_disk_shader_cache">ë””ìŠ¤í¬ ì…°ì´ë” ìºì‹œ</string>
149 <string name="use_disk_shader_cache_description">ìƒì„±ëœ ì…°ì´ë”를 디스í¬ì— 저장하고 불러오기하여 ëŠê¹€ 현ìƒì„ 줄입니다.</string> 159 <string name="use_disk_shader_cache_description">ìƒì„±ëœ ì…°ì´ë”를 ë¡œì»¬ì— ì €ìž¥í•˜ê³  로드하여 ëŠê¹€ 현ìƒì„ 줄입니다.</string>
150 160
151 <!-- Audio settings strings --> 161 <!-- Debug settings strings -->
162 <string name="cpu">CPU</string>
163 <string name="renderer_api">API</string>
164 <string name="renderer_debug">그래픽 디버깅</string>
165 <string name="renderer_debug_description">그래픽 API를 ëŠë¦° 디버깅 모드로 설정합니다.</string>
152 <string name="audio_volume">볼륨</string> 166 <string name="audio_volume">볼륨</string>
153 <string name="audio_volume_description">오디오 ì¶œë ¥ì˜ ë³¼ë¥¨ì„ ì§€ì •í•©ë‹ˆë‹¤.</string> 167 <string name="audio_volume_description">오디오 ì¶œë ¥ì˜ ë³¼ë¥¨ì„ ì§€ì •í•©ë‹ˆë‹¤.</string>
154 168
155 <!-- Miscellaneous --> 169 <!-- Miscellaneous -->
156 <string name="slider_default">기본값</string> 170 <string name="slider_default">기본값</string>
157 <string name="ini_saved">ì €ìž¥ëœ ì„¤ì •</string> 171 <string name="ini_saved">ì„¤ì •ì´ ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤.</string>
158 <string name="gameid_saved">%1$s를 ìœí•´ ì €ìž¥ëœ ì„¤ì •</string> 172 <string name="gameid_saved">%1$s ì ìš© 설ì ì´ 저장ë˜ì—ˆìŠµë‹ˆë‹¤.</string>
159 <string name="error_saving">%1$s.ini 저장 중 오류: %2$s</string> 173 <string name="error_saving">%1$s.ini 저장 중 오류 ë°œìƒ: %2$s</string>
160 <string name="loading">불러오기 중...</string> 174 <string name="loading">불러오는 중...</string>
161 <string name="reset_setting_confirmation">ì´ ì„¤ì •ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ ë˜ëŒë¦¬ê² ìŠµë‹ˆê¹Œ?</string> 175 <string name="reset_setting_confirmation">ì´ ì„¤ì •ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ 재설정하겠습니까?</string>
162 <string name="reset_to_default">기본값으로 재설정</string> 176 <string name="reset_to_default">기본값으로 재설정</string>
163 <string name="reset_all_settings">모든 ì„¤ì •ì„ ì´ˆê¸°í™”í•˜ê² ìŠµë‹ˆê¹Œ?</string> 177 <string name="reset_all_settings">모든 ì„¤ì •ì„ ì´ˆê¸°í™”í•˜ê² ìŠµë‹ˆê¹Œ?</string>
164 <string name="reset_all_settings_description">모든 고급 ì„¤ì •ì´ ê¸°ë³¸ 구성으로 재설정ë©ë‹ˆë‹¤. ì´ ì„¤ì •ì€ ë˜ëŒë¦´ 수 없습니다.</string> 178 <string name="reset_all_settings_description">모든 고급 ì„¤ì •ì´ ê¸°ë³¸ 구성으로 재설정ë©ë‹ˆë‹¤. ì´ ìž‘ì—…ì€ ë˜ëŒë¦´ 수 없습니다.</string>
165 <string name="settings_reset">설정 초기화</string> 179 <string name="settings_reset">설정 초기화</string>
166 <string name="close">닫기</string> 180 <string name="close">닫기</string>
167 <string name="learn_more">ìžì„¸ížˆ 알아보기</string> 181 <string name="learn_more">ìžì„¸ížˆ</string>
168 182 <string name="auto">ìžë™</string>
183 <string name="submit">제출</string>
184 <string name="string_null">Null</string>
185 <string name="string_import">가져오기</string>
186 <string name="export">내보내기</string>
169 <!-- GPU driver installation --> 187 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">GPU 드ë¼ì´ë²„ ì„ íƒ</string> 188 <string name="select_gpu_driver">GPU 드ë¼ì´ë²„ ì„ íƒ</string>
171 <string name="select_gpu_driver_title">현재 사용 ì¤‘ì¸ GPU 드ë¼ì´ë²„를 êµì²´í•˜ê² ìŠµë‹ˆê¹Œ?</string> 189 <string name="select_gpu_driver_title">현재 ì‚¬ìš©ì¤‘ì¸ GPU 드ë¼ì´ë²„를 변경하겠습니까?</string>
172 <string name="select_gpu_driver_install">설치</string> 190 <string name="select_gpu_driver_install">설치</string>
173 <string name="select_gpu_driver_default">기본값</string> 191 <string name="select_gpu_driver_default">기본값</string>
174 <string name="select_gpu_driver_use_default">기본 GPU 드ë¼ì´ë²„ 사용</string> 192 <string name="select_gpu_driver_use_default">기본 GPU 드ë¼ì´ë²„를 사용합니다.</string>
193 <string name="select_gpu_driver_error">ìž˜ëª»ëœ ë“œë¼ì´ë¸Œê°€ ì„ íƒë˜ì—ˆìŠµë‹ˆë‹¤. 시스템 ê¸°ë³¸ê°’ì„ ì‚¬ìš©í•©ë‹ˆë‹¤.</string>
175 <string name="system_gpu_driver">시스템 GPU 드ë¼ì´ë²„</string> 194 <string name="system_gpu_driver">시스템 GPU 드ë¼ì´ë²„</string>
176 <string name="installing_driver">드ë¼ì´ë²„ 설치 중...</string> 195 <string name="installing_driver">드ë¼ì´ë²„ 설치 중...</string>
177 196
@@ -182,51 +201,50 @@
182 <string name="preferences_graphics">그래픽</string> 201 <string name="preferences_graphics">그래픽</string>
183 <string name="preferences_audio">오디오</string> 202 <string name="preferences_audio">오디오</string>
184 <string name="preferences_theme">테마 ë° ìƒ‰ìƒ</string> 203 <string name="preferences_theme">테마 ë° ìƒ‰ìƒ</string>
204 <string name="preferences_debug">디버그</string>
185 205
186 <!-- ROM loading errors --> 206 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">ë¡¬ì´ ì•”í˜¸í™”ë˜ì—ˆìŒ</string> 207 <string name="loader_error_encrypted">롬 파ì¼ì´ 암호화ë˜ì–´ìžˆìŒ</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[ê°€ì´ë“œì— ë”°ë¼ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">게임 카트리지</a> ë˜ëŠ” <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">ì„¤ì¹˜ëœ íƒ€ì´í‹€</a>를 다시 ë¤í”„하세요.]]></string> 208 <string name="loader_error_encrypted_keys_description"><![CDATA[ê²Œìž„ì„ í•´ë…í•  수 있ë„ë¡ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 파ì¼ì´ 설치ë˜ì–´ 있는지 확ì¸í•˜ì„¸ìš”.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Pê²Œìž„ì„ í•´ë…í•  수 있ë„ë¡ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 파ì¼ì´ 설치ë˜ì–´ 있는지 확ì¸í•˜ì„¸ìš”.]]></string>
190 <string name="loader_error_video_core">비디오 코어를 초기화하는 ë™ì•ˆ 오류 ë°œìƒ</string> 209 <string name="loader_error_video_core">비디오 코어를 초기화하는 ë™ì•ˆ 오류 ë°œìƒ</string>
191 <string name="loader_error_video_core_description">ì´ ë¬¸ì œëŠ” ì¼ë°˜ì ìœ¼ë¡œ 호환ë˜ì§€ 않는 GPU 드ë¼ì´ë²„로 ì¸í•´ ë°œìƒí•©ë‹ˆë‹¤. ì‚¬ìš©ìž ì§€ì • GPU 드ë¼ì´ë²„를 설치하면 ì´ ë¬¸ì œê°€ í•´ê²°ë  ìˆ˜ 있습니다.</string> 210 <string name="loader_error_video_core_description">ì¼ë°˜ì ìœ¼ë¡œ ì´ ë¬¸ì œëŠ” 호환ë˜ì§€ 않는 GPU 드ë¼ì´ë²„로 ì¸í•´ ë°œìƒí•©ë‹ˆë‹¤. ì‚¬ìš©ìž ì§€ì • GPU 드ë¼ì´ë²„를 설치하면 ì´ ë¬¸ì œê°€ í•´ê²°ë  ìˆ˜ 있습니다.</string>
192 <string name="loader_error_invalid_format">ë¡¬ì„ ë¶ˆëŸ¬ì˜¬ 수 ì—†ìŒ</string> 211 <string name="loader_error_invalid_format">롬 파ì¼ì„ 불러올 수 ì—†ìŒ</string>
193 <string name="loader_error_file_not_found">롬 파ì¼ì´ 존재하지 않ìŒ</string> 212 <string name="loader_error_file_not_found">롬 파ì¼ì´ 존재하지 않ìŒ</string>
194 213
195 <!-- Emulation Menu --> 214 <!-- Emulation Menu -->
196 <string name="emulation_exit">ì—뮬레ì´ì…˜ 종료</string> 215 <string name="emulation_exit">ì—뮬레ì´ì…˜ 종료</string>
197 <string name="emulation_done">완료</string> 216 <string name="emulation_done">완료</string>
198 <string name="emulation_fps_counter">FPS 카운터</string> 217 <string name="emulation_fps_counter">FPS 표시</string>
199 <string name="emulation_toggle_controls">í† ê¸ ì œì–´</string> 218 <string name="emulation_toggle_controls">컨트롤러 ì íƒ</string>
200 <string name="emulation_rel_stick_center">ìƒëŒ€ 스틱 센터</string> 219 <string name="emulation_rel_stick_center">ìŠ¤í‹±ì˜ ì¤‘ì‹¬ ì´ë™</string>
201 <string name="emulation_dpad_slide">ì‹­ìžíŒ¨ë“œ 슬ë¼ì´ë“œ</string> 220 <string name="emulation_dpad_slide">ì‹­ìží‚¤ 슬ë¼ì´ë“œ</string>
202 <string name="emulation_haptics">햅틱</string> 221 <string name="emulation_haptics">터치 햅틱</string>
203 <string name="emulation_show_overlay">ì˜¤ë²„ë ˆì´ í‘œì‹œ</string> 222 <string name="emulation_show_overlay">컨트롤러 표시</string>
204 <string name="emulation_toggle_all">ëª¨ë‘ í† ê¸€</string> 223 <string name="emulation_toggle_all">ëª¨ë‘ ì„ íƒ</string>
205 <string name="emulation_control_adjust">ì˜¤ë²„ë ˆì´ ì¡°ì •</string> 224 <string name="emulation_control_adjust">컨트롤러 ì¡°ì •</string>
206 <string name="emulation_control_scale">스케ì¼</string> 225 <string name="emulation_control_scale">í¬ê¸°</string>
207 <string name="emulation_control_opacity">불투명ë„</string> 226 <string name="emulation_control_opacity">불투명ë„</string>
208 <string name="emulation_touch_overlay_reset">ì˜¤ë²„ë ˆì´ ìž¬ì„¤ì •</string> 227 <string name="emulation_touch_overlay_reset">컨트롤러 설정 초기화</string>
209 <string name="emulation_touch_overlay_edit">오ë²ë ˆì´ 편집</string> 228 <string name="emulation_touch_overlay_edit">컨트롤러 위치 편집</string>
210 <string name="emulation_pause">ì—뮬레ì´ì…˜ ì¼ì‹œ 중지</string> 229 <string name="emulation_pause">ì—뮬레ì´ì…˜ ì¼ì‹œ 중지</string>
211 <string name="emulation_unpause">ì—뮬레ì´ì…˜ ì¼ì‹œ 중지 í•´ì œ</string> 230 <string name="emulation_unpause">ì—뮬레ì´ì…˜ ì¼ì‹œ 중지 í•´ì œ</string>
212 <string name="emulation_input_overlay">ì˜¤ë²„ë ˆì´ ì˜µì…˜</string> 231 <string name="emulation_input_overlay">화면 ì˜¤ë²„ë ˆì´ ì„¤ì •</string>
213 232
214 <string name="load_settings">설정 불러오기 중...</string> 233 <string name="load_settings">설정 불러오는 중...</string>
215 234
216 <!-- Software keyboard --> 235 <!-- Software keyboard -->
217 <string name="software_keyboard">ê°€ìƒ í‚¤ë³´ë“œ</string> 236 <string name="software_keyboard">소프트웨어 키보드</string>
218 237
219 <!-- Errors and warnings --> 238 <!-- Errors and warnings -->
220 <string name="abort_button">정보</string> 239 <string name="abort_button">중단</string>
221 <string name="continue_button">계ì†</string> 240 <string name="continue_button">계ì†</string>
222 <string name="system_archive_not_found">시스템 ì•„ì¹´ì´ë¸Œë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ</string> 241 <string name="system_archive_not_found">시스템 ì•„ì¹´ì´ë¸Œë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ</string>
223 <string name="system_archive_not_found_message">%sê°€ 누ë½ë˜ì—ˆìŠµë‹ˆë‹¤. 시스템 ì•„ì¹´ì´ë¸Œë¥¼ ë¤í”„하세요.\nì—뮬레ì´ì…˜ì„ 계ì†í•˜ë©´ ì¶©ëŒ ë° ë²„ê·¸ê°€ ë°œìƒí•  수 있습니다.</string> 242 <string name="system_archive_not_found_message">%sê°€ 누ë½ë˜ì—ˆìŠµë‹ˆë‹¤. 시스템 ì•„ì¹´ì´ë¸Œë¥¼ ë¤í”„하세요.\nì—뮬레ì´ì…˜ì„ 계ì†í•˜ë©´ ì¶©ëŒ ë° ë²„ê·¸ê°€ ë°œìƒí•  수 있습니다.</string>
224 <string name="system_archive_general">시스템 ì•„ì¹´ì´ë¸Œ</string> 243 <string name="system_archive_general">시스템 ì•„ì¹´ì´ë¸Œ</string>
225 <string name="save_load_error">저장하기/불러오기 오류</string> 244 <string name="save_load_error">저장하기/불러오기 오류</string>
226 <string name="fatal_error">치명ì ì¸ 오류</string> 245 <string name="fatal_error">ì¹˜ëª…ì  ì˜¤ë¥˜</string>
227 <string name="fatal_error_message">치명ì ì¸ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ìžì„¸í•œ ë‚´ìš©ì€ ë¡œê·¸ë¥¼ 확ì¸í•˜ì‹­ì‹œì˜¤.\nì—뮬레ì´ì…˜ì„ 계ì†í•˜ë©´ ì¶©ëŒ ë° ë²„ê·¸ê°€ ë°œìƒí•  수 있습니다.</string> 246 <string name="fatal_error_message">ì¹˜ëª…ì  ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. ìžì„¸í•œ ë‚´ìš©ì€ ë¡œê·¸ë¥¼ 확ì¸í•˜ì‹­ì‹œì˜¤.\nì—뮬레ì´ì…˜ì„ 계ì†í•˜ë©´ ì¶©ëŒ ë° ë²„ê·¸ê°€ ë°œìƒí•  수 있습니다.</string>
228 <string name="performance_warning">ì´ ì„¤ì •ì„ ë„ë©´ ì—뮬레ì´ì…˜ ì„±ëŠ¥ì´ í¬ê²Œ 저하ë©ë‹ˆë‹¤! 최ìƒì˜ í™˜ê²½ì„ ìœ„í•´ ì´ ì„¤ì •ì„ í™œì„±í™”ëœ ìƒíƒœë¡œ ë‘는 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤.</string> 247 <string name="performance_warning">ì´ ì„¤ì •ì„ ë„ë©´ ì—뮬레ì´ì…˜ ì„±ëŠ¥ì´ í¬ê²Œ 저하ë©ë‹ˆë‹¤! 최ìƒì˜ í™˜ê²½ì„ ìœ„í•´ ì´ ì„¤ì •ì„ í™œì„±í™”ëœ ìƒíƒœë¡œ ë‘는 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤.</string>
229
230 <!-- Region Names --> 248 <!-- Region Names -->
231 <string name="region_japan">ì¼ë³¸</string> 249 <string name="region_japan">ì¼ë³¸</string>
232 <string name="region_usa">미국</string> 250 <string name="region_usa">미국</string>
@@ -234,12 +252,11 @@
234 <string name="region_australia">호주</string> 252 <string name="region_australia">호주</string>
235 <string name="region_china">중국</string> 253 <string name="region_china">중국</string>
236 <string name="region_korea">대한민국</string> 254 <string name="region_korea">대한민국</string>
237 <string name="region_taiwan">타ì´ì™„</string> 255 <string name="region_taiwan">대만</string>
238
239 <!-- Language Names -->
240 256
257 <string name="memory_gigabyte">ì˜êµ­ 하계 표준시(GB)</string>
241 <!-- Renderer APIs --> 258 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">불칸</string> 259 <string name="renderer_vulkan">Vulcan</string>
243 <string name="renderer_none">ì—†ìŒ</string> 260 <string name="renderer_none">ì—†ìŒ</string>
244 261
245 <!-- Renderer Accuracy --> 262 <!-- Renderer Accuracy -->
@@ -256,17 +273,17 @@
256 <string name="resolution_four">4X (2880p/4320p) (ëŠë¦¼)</string> 273 <string name="resolution_four">4X (2880p/4320p) (ëŠë¦¼)</string>
257 274
258 <!-- Renderer VSync --> 275 <!-- Renderer VSync -->
259 <string name="renderer_vsync_immediate">즉시 (ë)</string> 276 <string name="renderer_vsync_immediate">ì¦‰ê° í‘œì‹œ (ë„기)</string>
260 <string name="renderer_vsync_mailbox">ë©”ì¼ë°•스</string> 277 <string name="renderer_vsync_mailbox">ë©”ì¼ë°•스</string>
261 <string name="renderer_vsync_fifo">FIFO (켬)</string> 278 <string name="renderer_vsync_fifo">FIFO (켜기)</string>
262 <string name="renderer_vsync_fifo_relaxed">FIFO 릴랙스</string> 279 <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
263 280
264 <!-- Scaling Filters --> 281 <!-- Scaling Filters -->
265 <string name="scaling_filter_nearest_neighbor">가장 가까운 ì´ì›ƒ</string> 282 <string name="scaling_filter_nearest_neighbor">최근접 ë³´ê°„</string>
266 <string name="scaling_filter_bilinear">ì´ì¤‘선형</string> 283 <string name="scaling_filter_bilinear">ìŒì„ í˜• ë³´ê°„</string>
267 <string name="scaling_filter_bicubic">고등차수보간</string> 284 <string name="scaling_filter_bicubic">ìŒìž…ë°© ë³´ê°„</string>
268 <string name="scaling_filter_gaussian">가우시안</string> 285 <string name="scaling_filter_gaussian">가우시안</string>
269 <string name="scaling_filter_scale_force">스케ì¼í¬ìФ</string> 286 <string name="scaling_filter_scale_force">ScaleForce</string>
270 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ 초고해ìƒë„</string> 287 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ 초고해ìƒë„</string>
271 288
272 <!-- Anti-Aliasing --> 289 <!-- Anti-Aliasing -->
@@ -274,27 +291,29 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 291 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 292 <string name="anti_aliasing_smaa">SMAA</string>
276 293
294 <string name="screen_layout_auto">ìžë™</string>
295
277 <!-- Aspect Ratios --> 296 <!-- Aspect Ratios -->
278 <string name="ratio_default">기본 (16:9)</string> 297 <string name="ratio_default">기본 (16:9)</string>
279 <string name="ratio_force_four_three">강제 4:3</string> 298 <string name="ratio_force_four_three">강제 4:3</string>
280 <string name="ratio_force_twenty_one_nine">강제 21:9</string> 299 <string name="ratio_force_twenty_one_nine">강제 21:9</string>
281 <string name="ratio_force_sixteen_ten">강제 16:10</string> 300 <string name="ratio_force_sixteen_ten">강제 16:10</string>
282 <string name="ratio_stretch">ì°½ì— ë§žê²Œ 늘림</string> 301 <string name="ratio_stretch">í™”ë©´ì— ë§žì¶¤</string>
283 302
284 <!-- CPU Accuracy --> 303 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">정확함</string> 304 <string name="cpu_accuracy_accurate">정확함</string>
286 <string name="cpu_accuracy_unsafe">안전하지 않ìŒ</string> 305 <string name="cpu_accuracy_unsafe">최ì í™” (안전하지 않ìŒ)</string>
287 <string name="cpu_accuracy_paranoid">편ì§ì¦ (ëŠë¦¼)</string> 306 <string name="cpu_accuracy_paranoid">최ì í™”하ì§ì•ŠìŒ (ëŠë¦¼)</string>
288 307
289 <!-- Gamepad Buttons --> 308 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">ì‹­ìžíŒ¨ë“œ</string> 309 <string name="gamepad_d_pad">ì‹­ìží‚¤</string>
291 <string name="gamepad_left_stick">L 스틱</string> 310 <string name="gamepad_left_stick">L 스틱</string>
292 <string name="gamepad_right_stick">R 스틱</string> 311 <string name="gamepad_right_stick">R 스틱</string>
293 <string name="gamepad_home">홈</string> 312 <string name="gamepad_home">홈</string>
294 <string name="gamepad_screenshot">스í¬ë¦°ìƒ·</string> 313 <string name="gamepad_screenshot">스í¬ë¦°ìƒ·</string>
295 314
296 <!-- Disk shader cache --> 315 <!-- Disk shader cache -->
297 <string name="preparing_shaders">ì…°ì´ë” 준비하기</string> 316 <string name="preparing_shaders">ì…°ì´ë” 준비하는 중</string>
298 <string name="building_shaders">ì…°ì´ë” 빌드 중</string> 317 <string name="building_shaders">ì…°ì´ë” 빌드 중</string>
299 318
300 <!-- Theme options --> 319 <!-- Theme options -->
@@ -303,13 +322,19 @@
303 <string name="theme_material_you">Material You</string> 322 <string name="theme_material_you">Material You</string>
304 323
305 <!-- Theme Modes --> 324 <!-- Theme Modes -->
306 <string name="change_theme_mode">테마 모드 변경</string> 325 <string name="change_theme_mode">ë‹¤í¬ ëª¨ë“œ 설정</string>
307 <string name="theme_mode_follow_system">팔로우 시스템</string> 326 <string name="theme_mode_follow_system">시스템 값 사용</string>
308 <string name="theme_mode_light">ë°ìŒ</string> 327 <string name="theme_mode_light">ë¼ì´íЏ 모드</string>
309 <string name="theme_mode_dark">ì–´ë‘움</string> 328 <string name="theme_mode_dark">ë‹¤í¬ ëª¨ë“œ</string>
310 329
311 <!-- Black backgrounds theme --> 330 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">ê²€ì€ìƒ‰ ë°°ê²½ 사용</string> 331 <string name="use_black_backgrounds">검정 ë°°ê²½</string>
313 <string name="use_black_backgrounds_description">ì–´ë‘ìš´ 테마를 사용할 때는 ê²€ì€ìƒ‰ ë°°ê²½ì„ ì ìš©í•©ë‹ˆë‹¤.</string> 332 <string name="use_black_backgrounds_description">ì–´ë‘ìš´ 테마를 사용할 때는 검정 ë°°ê²½ì„ ì ìš©í•©ë‹ˆë‹¤.</string>
333
334 <string name="mute">ìŒì†Œê±°</string>
335 <string name="unmute">ìŒì†Œê±° í•´ì œ</string>
314 336
315</resources> 337 <!-- Licenses screen strings -->
338 <string name="licenses">ë¼ì´ì„¼ìФ</string>
339 <string name="license_fidelityfx_fsr_description">AMDì˜ ê³ í’ˆì§ˆ 업스케ì¼ë§</string>
340 </resources>
diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml
index 5443cef42..3162a9d41 100644
--- a/src/android/app/src/main/res/values-nb/strings.xml
+++ b/src/android/app/src/main/res/values-nb/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Denne programvaren vil kjøre spill for Nintendo Switch-spillkonsollen. Ingen spilltitler eller nøkler er inkludert.&lt;br /&gt;&lt;br /&gt;Før du begynner, må du finne <![CDATA[<b> prod.keys </b>]]> filen din på enhetslagringen.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Lær mer</a>]]></string> 4 <string name="app_disclaimer">Denne programvaren vil kjøre spill for Nintendo Switch-spillkonsollen. Ingen spilltitler eller nøkler er inkludert.&lt;br /&gt;&lt;br /&gt;Før du begynner, må du finne <![CDATA[<b> prod.keys </b>]]> filen din på enhetslagringen.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Lær mer</a>]]></string>
5 <string name="emulation_notification_channel_name">Emulering er aktiv</string> 5 <string name="emulation_notification_channel_name">Emulering er aktiv</string>
@@ -25,7 +25,6 @@
25 <string name="back">Tilbake</string> 25 <string name="back">Tilbake</string>
26 <string name="add_games">Legg til spill</string> 26 <string name="add_games">Legg til spill</string>
27 <string name="add_games_description">Velg din spillmappe</string> 27 <string name="add_games_description">Velg din spillmappe</string>
28
29 <!-- Home strings --> 28 <!-- Home strings -->
30 <string name="home_games">Spill</string> 29 <string name="home_games">Spill</string>
31 <string name="home_search">Søk</string> 30 <string name="home_search">Søk</string>
@@ -37,7 +36,7 @@
37 <string name="add_games_warning">Hoppe over valg av spillmappe?</string> 36 <string name="add_games_warning">Hoppe over valg av spillmappe?</string>
38 <string name="add_games_warning_description">Spill vises ikke i Spill-listen hvis en mappe ikke er valgt.</string> 37 <string name="add_games_warning_description">Spill vises ikke i Spill-listen hvis en mappe ikke er valgt.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 38 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Søk i spill</string> 39 <string name="home_search_games">Søk i spill|</string>
41 <string name="games_dir_selected">Spillkatalogen er valgt</string> 40 <string name="games_dir_selected">Spillkatalogen er valgt</string>
42 <string name="install_prod_keys">Installer prod.keys</string> 41 <string name="install_prod_keys">Installer prod.keys</string>
43 <string name="install_prod_keys_description">Nødvendig for å dekryptere spill</string> 42 <string name="install_prod_keys_description">Nødvendig for å dekryptere spill</string>
@@ -61,6 +60,8 @@
61 <string name="invalid_keys_file">Ugyldig nøkkelfil valgt</string> 60 <string name="invalid_keys_file">Ugyldig nøkkelfil valgt</string>
62 <string name="install_keys_success">Nøkler vellykket installert</string> 61 <string name="install_keys_success">Nøkler vellykket installert</string>
63 <string name="reading_keys_failure">Feil ved lesing av krypteringsnøkler</string> 62 <string name="reading_keys_failure">Feil ved lesing av krypteringsnøkler</string>
63 <string name="install_prod_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .keys, og prøv igjen.</string>
64 <string name="install_amiibo_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .bin, og prøv igjen.</string>
64 <string name="invalid_keys_error">Ugyldige krypteringsnøkler</string> 65 <string name="invalid_keys_error">Ugyldige krypteringsnøkler</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.</string> 67 <string name="install_keys_failure_description">Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.</string>
@@ -86,7 +87,17 @@
86 <string name="save_file_invalid_zip_structure_description">Det første undermappenavnet må være spillets tittel-ID.</string> 87 <string name="save_file_invalid_zip_structure_description">Det første undermappenavnet må være spillets tittel-ID.</string>
87 <string name="import_saves">Importer</string> 88 <string name="import_saves">Importer</string>
88 <string name="export_saves">Eksporter</string> 89 <string name="export_saves">Eksporter</string>
89 90 <string name="install_firmware">Installer fastvare</string>
91 <string name="install_firmware_description">Fastvaren må være i et ZIP-arkiv og er nødvendig for å starte noen spill.</string>
92 <string name="firmware_installing">Installering av fastvare</string>
93 <string name="firmware_installed_success">Fastvaren er vellykket installert</string>
94 <string name="firmware_installed_failure">Installasjon av fastvare mislyktes</string>
95 <string name="share_log">Del feilsøkingslogger</string>
96 <string name="share_log_description">Del yuzus loggfil for å feilsøke problemer</string>
97 <string name="share_log_missing">Ingen loggfil funnet</string>
98 <string name="install_game_content">Installer spillinnhold</string>
99 <string name="install_game_content_description">Installer spilloppdateringer eller DLC</string>
100 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
90 <!-- About screen strings --> 101 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia er ikke ekte</string> 102 <string name="gaia_is_not_real">Gaia er ikke ekte</string>
92 <string name="copied_to_clipboard">Kopiert til utklippstavlen</string> 103 <string name="copied_to_clipboard">Kopiert til utklippstavlen</string>
@@ -94,6 +105,7 @@
94 <string name="contributors">Bidragsytere</string> 105 <string name="contributors">Bidragsytere</string>
95 <string name="contributors_description">Laget med \u2764 fra yuzu-teamet</string> 106 <string name="contributors_description">Laget med \u2764 fra yuzu-teamet</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 107 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
108 <string name="licenses_description">Prosjekter som gjør yuzu for Android mulig</string>
97 <string name="build">Bygg</string> 109 <string name="build">Bygg</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 110 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 111 <string name="website_link">https://yuzu-emu.org/</string>
@@ -114,41 +126,43 @@
114 <string name="are_you_interested">Er du interessert?</string> 126 <string name="are_you_interested">Er du interessert?</string>
115 127
116 <!-- General settings strings --> 128 <!-- General settings strings -->
117 <string name="frame_limit_enable">Aktiver hastighetsbegrensning</string> 129 <string name="frame_limit_enable">Begrense hastigheten</string>
118 <string name="frame_limit_enable_description">NÃ¥r aktivert, begrenses emuleringshastigheten til en angitt prosentandel av normal hastighet.</string> 130 <string name="frame_limit_enable_description">Begrenser emuleringshastigheten til en spesifisert prosentandel av normal hastighet.</string>
119 <string name="frame_limit_slider">Hastighetsbegrensning i prosent</string> 131 <string name="frame_limit_slider">Hastighetsbegrensning i prosent</string>
120 <string name="frame_limit_slider_description">Angir prosentandelen som skal begrense emuleringshastigheten. Med standardverdien 100 % vil emuleringen være begrenset til normal hastighet. Høyere eller lavere verdier vil øke eller redusere hastighetsbegrensningen.</string> 132 <string name="frame_limit_slider_description">Angir prosentandelen som skal begrense emuleringshastigheten. 100 % er normal hastighet. Høyere eller lavere verdier vil øke eller redusere hastighetsgrensen.</string>
121 <string name="cpu_accuracy">CPU-nøyaktighet</string> 133 <string name="cpu_accuracy">CPU-nøyaktighet</string>
122
123 <!-- System settings strings --> 134 <!-- System settings strings -->
124 <string name="use_docked_mode">Dokket modus</string> 135 <string name="use_docked_mode">Dokket modus</string>
125 <string name="use_docked_mode_description">Emulerer i dokket modus, noe som øker oppløsningen på bekostning av ytelsen.</string> 136 <string name="use_docked_mode_description">Øker oppløsningen, men reduserer ytelsen. Håndholdt modus brukes når den er deaktivert, noe som reduserer oppløsningen og øker ytelsen.</string>
126 <string name="emulated_region">Emulert region</string> 137 <string name="emulated_region">Emulert region</string>
127 <string name="emulated_language">Emulert språk</string> 138 <string name="emulated_language">Emulert språk</string>
128 <string name="select_rtc_date">Velg RTC-dato</string> 139 <string name="select_rtc_date">Velg RTC-dato</string>
129 <string name="select_rtc_time">Velg RTC-tid</string> 140 <string name="select_rtc_time">Velg RTC-tid</string>
130 <string name="use_custom_rtc">Aktiver egendefinert RTC</string> 141 <string name="use_custom_rtc">Tilpasset Sannhetstidsklokke</string>
131 <string name="use_custom_rtc_description">Med denne innstillingen kan du stille inn en egendefinert sanntidsklokke som er atskilt fra gjeldende systemtid.</string> 142 <string name="use_custom_rtc_description">Gjør det mulig å stille inn en egendefinert sanntidsklokke separat fra den gjeldende systemtiden.</string>
132 <string name="set_custom_rtc">Angi egendefinert RTC</string> 143 <string name="set_custom_rtc">Angi tilpasset RTC</string>
133 144
134 <!-- Graphics settings strings --> 145 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Nøyaktighetsnivå</string> 146 <string name="renderer_accuracy">Nøyaktighetsnivå</string>
137 <string name="renderer_resolution">Oppløsning</string> 147 <string name="renderer_resolution">Oppløsning (håndholdt/dokket)</string>
138 <string name="renderer_vsync">VSync-modus</string> 148 <string name="renderer_vsync">VSync-modus</string>
139 <string name="renderer_aspect_ratio">Størrelsesforhold</string> 149 <string name="renderer_aspect_ratio">Størrelsesforhold</string>
140 <string name="renderer_scaling_filter">Filter for vindustilpasning</string> 150 <string name="renderer_scaling_filter">Filter for vindustilpasning</string>
141 <string name="renderer_anti_aliasing">Anti-Aliasing-metode</string> 151 <string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
142 <string name="renderer_force_max_clock">Tving fram maksimal klokkefrekvens (kun Adreno)</string> 152 <string name="renderer_force_max_clock">Tving fram maksimal klokkefrekvens (kun Adreno)</string>
143 <string name="renderer_force_max_clock_description">Tvinger GPU-en til å kjøre med maksimal klokkefrekvens (termiske begrensninger vil fortsatt gjelde).</string> 153 <string name="renderer_force_max_clock_description">Tvinger GPU-en til å kjøre med maksimal klokkefrekvens (termiske begrensninger vil fortsatt gjelde).</string>
144 <string name="renderer_asynchronous_shaders">Bruk asynkrone shaders</string> 154 <string name="renderer_asynchronous_shaders">Bruk asynkrone shaders</string>
145 <string name="renderer_asynchronous_shaders_description">Kompilerer shaders asynkront, noe som reduserer hakkingen, men kan føre til feil.</string> 155 <string name="renderer_asynchronous_shaders_description">Kompilerer shaders asynkront, noe som reduserer hakking, men kan føre til feil.</string>
146 <string name="renderer_debug">Aktiver feilsøking av grafikk</string> 156 <string name="renderer_reactive_flushing">Bruk reaktiv spyling</string>
147 <string name="renderer_debug_description">Når dette er merket av, går grafikk-API-et inn i en langsommere feilsøkingsmodus.</string> 157 <string name="renderer_reactive_flushing_description">Forbedrer gjengivelsesnøyaktigheten i enkelte spill på bekostning av ytelsen.</string>
148 <string name="use_disk_shader_cache">Bruk disk shader-cache</string> 158 <string name="use_disk_shader_cache">Disk shader-hurtigbuffer</string>
149 <string name="use_disk_shader_cache_description">Reduser hakking ved å lagre og laste inn genererte shaders på disken.</string> 159 <string name="use_disk_shader_cache_description">Reduserer hakking ved å lagre og laste inn genererte shaders lokalt.</string>
150 160
151 <!-- Audio settings strings --> 161 <!-- Debug settings strings -->
162 <string name="cpu">CPU</string>
163 <string name="renderer_api">API</string>
164 <string name="renderer_debug">Feilsøking av grafikk</string>
165 <string name="renderer_debug_description">Setter grafikk-API-et til en langsom feilsøkingsmodus.</string>
152 <string name="audio_volume">Volum</string> 166 <string name="audio_volume">Volum</string>
153 <string name="audio_volume_description">Angir volumet på lydutgangen.</string> 167 <string name="audio_volume_description">Angir volumet på lydutgangen.</string>
154 168
@@ -164,14 +178,19 @@
164 <string name="reset_all_settings_description">Alle avanserte innstillinger tilbakestilles til standardkonfigurasjonen. Dette kan ikke angres.</string> 178 <string name="reset_all_settings_description">Alle avanserte innstillinger tilbakestilles til standardkonfigurasjonen. Dette kan ikke angres.</string>
165 <string name="settings_reset">Tilbakestilling av innstillinger</string> 179 <string name="settings_reset">Tilbakestilling av innstillinger</string>
166 <string name="close">Lukk</string> 180 <string name="close">Lukk</string>
167 <string name="learn_more">Lær Mer</string> 181 <string name="learn_more">Lær mer</string>
168 182 <string name="auto">Auto</string>
183 <string name="submit">Send inn</string>
184 <string name="string_null">Null</string>
185 <string name="string_import">Importer</string>
186 <string name="export">Eksporter</string>
169 <!-- GPU driver installation --> 187 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Velg GPU-driver</string> 188 <string name="select_gpu_driver">Velg GPU-driver</string>
171 <string name="select_gpu_driver_title">Ønsker du å bytte ut din nåværende GPU-driver?</string> 189 <string name="select_gpu_driver_title">Ønsker du å bytte ut din nåværende GPU-driver?</string>
172 <string name="select_gpu_driver_install">Installer</string> 190 <string name="select_gpu_driver_install">Installer</string>
173 <string name="select_gpu_driver_default">Standard</string> 191 <string name="select_gpu_driver_default">Standard</string>
174 <string name="select_gpu_driver_use_default">Bruk av standard GPU-driver</string> 192 <string name="select_gpu_driver_use_default">Bruk av standard GPU-driver</string>
193 <string name="select_gpu_driver_error">Ugyldig driver valgt, bruker systemstandard!</string>
175 <string name="system_gpu_driver">Systemets GPU-driver</string> 194 <string name="system_gpu_driver">Systemets GPU-driver</string>
176 <string name="installing_driver">Installerer driver...</string> 195 <string name="installing_driver">Installerer driver...</string>
177 196
@@ -182,10 +201,10 @@
182 <string name="preferences_graphics">Grafikk</string> 201 <string name="preferences_graphics">Grafikk</string>
183 <string name="preferences_audio">Lyd</string> 202 <string name="preferences_audio">Lyd</string>
184 <string name="preferences_theme">Tema og farge</string> 203 <string name="preferences_theme">Tema og farge</string>
204 <string name="preferences_debug">Feilsøk</string>
185 205
186 <!-- ROM loading errors --> 206 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">ROM-en din er kryptert</string> 207 <string name="loader_error_encrypted">ROM-en din er kryptert</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Følg veiledningene for å redumpe dine <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">spillkassetter</a> eller <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">installerte titler</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Vennligst sørg for at <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> filen er installert slik at spillene kan dekrypteres.]]></string> 208 <string name="loader_error_encrypted_keys_description"><![CDATA[Vennligst sørg for at <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> filen er installert slik at spillene kan dekrypteres.]]></string>
190 <string name="loader_error_video_core">Det oppstod en feil ved initialisering av videokjernen</string> 209 <string name="loader_error_video_core">Det oppstod en feil ved initialisering av videokjernen</string>
191 <string name="loader_error_video_core_description">Dette skyldes vanligvis en inkompatibel GPU-driver. Installering av en tilpasset GPU-driver kan løse problemet.</string> 210 <string name="loader_error_video_core_description">Dette skyldes vanligvis en inkompatibel GPU-driver. Installering av en tilpasset GPU-driver kan løse problemet.</string>
@@ -196,25 +215,25 @@
196 <string name="emulation_exit">Avslutt emulering</string> 215 <string name="emulation_exit">Avslutt emulering</string>
197 <string name="emulation_done">Ferdig</string> 216 <string name="emulation_done">Ferdig</string>
198 <string name="emulation_fps_counter">FPS-teller</string> 217 <string name="emulation_fps_counter">FPS-teller</string>
199 <string name="emulation_toggle_controls">Veksle kontroller</string> 218 <string name="emulation_toggle_controls">Veksle mellom kontrollene</string>
200 <string name="emulation_rel_stick_center">Relativt senter for stikken</string> 219 <string name="emulation_rel_stick_center">Relativt pinnesenter</string>
201 <string name="emulation_dpad_slide">DPad-skyveplate</string> 220 <string name="emulation_dpad_slide">D-pad-skyving</string>
202 <string name="emulation_haptics">Haptikk</string> 221 <string name="emulation_haptics">Berøringshaptikk</string>
203 <string name="emulation_show_overlay">Vis overlegg</string> 222 <string name="emulation_show_overlay">Vis overlegg</string>
204 <string name="emulation_toggle_all">Slå av alt</string> 223 <string name="emulation_toggle_all">Veksle mellom alle</string>
205 <string name="emulation_control_adjust">Juster overlegg</string> 224 <string name="emulation_control_adjust">Juster overlegg</string>
206 <string name="emulation_control_scale">Skaler</string> 225 <string name="emulation_control_scale">Skaler</string>
207 <string name="emulation_control_opacity">Gjennomsiktighet</string> 226 <string name="emulation_control_opacity">Gjennomsiktighet</string>
208 <string name="emulation_touch_overlay_reset">Tilbakestill overlegg</string> 227 <string name="emulation_touch_overlay_reset">Tilbakestill overlegg</string>
209 <string name="emulation_touch_overlay_edit">Rediger overlegg</string> 228 <string name="emulation_touch_overlay_edit">Rediger overlegg</string>
210 <string name="emulation_pause">Pause Emulering</string> 229 <string name="emulation_pause">Pause emulering</string>
211 <string name="emulation_unpause">Opphev pausing av emulering</string> 230 <string name="emulation_unpause">Ta emuleringen ut av pause</string>
212 <string name="emulation_input_overlay">Alternativer for overlegg</string> 231 <string name="emulation_input_overlay">Overlay-alternativer</string>
213 232
214 <string name="load_settings">Laster inn innstillinger...</string> 233 <string name="load_settings">Laster inn innstillinger...</string>
215 234
216 <!-- Software keyboard --> 235 <!-- Software keyboard -->
217 <string name="software_keyboard">Programvare Tastatur</string> 236 <string name="software_keyboard">Programvaretastatur</string>
218 237
219 <!-- Errors and warnings --> 238 <!-- Errors and warnings -->
220 <string name="abort_button">Avbryt</string> 239 <string name="abort_button">Avbryt</string>
@@ -226,7 +245,6 @@
226 <string name="fatal_error">Fatal Feil</string> 245 <string name="fatal_error">Fatal Feil</string>
227 <string name="fatal_error_message">Det oppstod en fatal feil. Sjekk loggen for mer informasjon.\nFortsatt emulering kan føre til krasj og feil.</string> 246 <string name="fatal_error_message">Det oppstod en fatal feil. Sjekk loggen for mer informasjon.\nFortsatt emulering kan føre til krasj og feil.</string>
228 <string name="performance_warning">Hvis du slår av denne innstillingen, reduseres emuleringsytelsen betydelig! Vi anbefaler at du lar denne innstillingen være aktivert for å få den beste opplevelsen.</string> 247 <string name="performance_warning">Hvis du slår av denne innstillingen, reduseres emuleringsytelsen betydelig! Vi anbefaler at du lar denne innstillingen være aktivert for å få den beste opplevelsen.</string>
229
230 <!-- Region Names --> 248 <!-- Region Names -->
231 <string name="region_japan">Japan</string> 249 <string name="region_japan">Japan</string>
232 <string name="region_usa">USA</string> 250 <string name="region_usa">USA</string>
@@ -236,8 +254,7 @@
236 <string name="region_korea">Korea</string> 254 <string name="region_korea">Korea</string>
237 <string name="region_taiwan">Taiwan</string> 255 <string name="region_taiwan">Taiwan</string>
238 256
239 <!-- Language Names --> 257 <string name="memory_gigabyte">GB</string>
240
241 <!-- Renderer APIs --> 258 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 259 <string name="renderer_vulkan">Vulkan</string>
243 <string name="renderer_none">Ingen</string> 260 <string name="renderer_none">Ingen</string>
@@ -274,12 +291,14 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 291 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 292 <string name="anti_aliasing_smaa">SMAA</string>
276 293
294 <string name="screen_layout_auto">Auto</string>
295
277 <!-- Aspect Ratios --> 296 <!-- Aspect Ratios -->
278 <string name="ratio_default">Standard (16:9)</string> 297 <string name="ratio_default">Standard (16:9)</string>
279 <string name="ratio_force_four_three">Tving 4:3</string> 298 <string name="ratio_force_four_three">Tving 4:3</string>
280 <string name="ratio_force_twenty_one_nine">Tving 21:9</string> 299 <string name="ratio_force_twenty_one_nine">Tving 21:9</string>
281 <string name="ratio_force_sixteen_ten">Tving 16:10</string> 300 <string name="ratio_force_sixteen_ten">Tving 16:10</string>
282 <string name="ratio_stretch">Strekk til Vindu</string> 301 <string name="ratio_stretch">Strekk til vindu</string>
283 302
284 <!-- CPU Accuracy --> 303 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Nøyaktig</string> 304 <string name="cpu_accuracy_accurate">Nøyaktig</string>
@@ -287,9 +306,9 @@
287 <string name="cpu_accuracy_paranoid">Paranoid (Langsom)</string> 306 <string name="cpu_accuracy_paranoid">Paranoid (Langsom)</string>
288 307
289 <!-- Gamepad Buttons --> 308 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">D-Pad</string> 309 <string name="gamepad_d_pad">D-pad</string>
291 <string name="gamepad_left_stick">Venstre Pinne</string> 310 <string name="gamepad_left_stick">Venstre spak</string>
292 <string name="gamepad_right_stick">Høyre Pinne</string> 311 <string name="gamepad_right_stick">Høyre spak</string>
293 <string name="gamepad_home">Hjem</string> 312 <string name="gamepad_home">Hjem</string>
294 <string name="gamepad_screenshot">Skjermbilde</string> 313 <string name="gamepad_screenshot">Skjermbilde</string>
295 314
@@ -298,7 +317,7 @@
298 <string name="building_shaders">Bygging av shaders</string> 317 <string name="building_shaders">Bygging av shaders</string>
299 318
300 <!-- Theme options --> 319 <!-- Theme options -->
301 <string name="change_app_theme">Endre appens tema</string> 320 <string name="change_app_theme">Endre app-tema</string>
302 <string name="theme_default">Standard</string> 321 <string name="theme_default">Standard</string>
303 <string name="theme_material_you">Material You</string> 322 <string name="theme_material_you">Material You</string>
304 323
@@ -309,7 +328,13 @@
309 <string name="theme_mode_dark">Mørk</string> 328 <string name="theme_mode_dark">Mørk</string>
310 329
311 <!-- Black backgrounds theme --> 330 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Bruk svart bakgrunn</string> 331 <string name="use_black_backgrounds">Svart bakgrunn</string>
313 <string name="use_black_backgrounds_description">Bruk svart bakgrunn når du bruker det mørke temaet.</string> 332 <string name="use_black_backgrounds_description">Bruk svart bakgrunn når du bruker det mørke temaet.</string>
314 333
315</resources> 334 <string name="mute">Lydløs</string>
335 <string name="unmute">Slå på lyden</string>
336
337 <!-- Licenses screen strings -->
338 <string name="licenses">Lisenser</string>
339 <string name="license_fidelityfx_fsr_description">Oppskalering av høy kvalitet fra AMD</string>
340 </resources>
diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml
index 899e233d0..f4d9920c2 100644
--- a/src/android/app/src/main/res/values-pl/strings.xml
+++ b/src/android/app/src/main/res/values-pl/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">To oprogramowanie umożliwia uruchomienie gier z konsoli Nintendo Switch. Nie zawiera gier ani wymaganych kluczy.&lt;br /&gt;&lt;br /&gt;Zanim zaczniesz, wybierz plik kluczy <![CDATA[<b> prod.keys </b>]]> z katalogu w pamięci masowej.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Dowiedz się więcej</a>]]></string> 4 <string name="app_disclaimer">To oprogramowanie umożliwia uruchomienie gier z konsoli Nintendo Switch. Nie zawiera gier ani wymaganych kluczy.&lt;br /&gt;&lt;br /&gt;Zanim zaczniesz, wybierz plik kluczy <![CDATA[<b> prod.keys </b>]]> z katalogu w pamięci masowej.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Dowiedz się więcej</a>]]></string>
5 <string name="emulation_notification_channel_name">Emulacja jest uruchomiona</string> 5 <string name="emulation_notification_channel_name">Emulacja jest uruchomiona</string>
@@ -25,7 +25,6 @@
25 <string name="back">Wstecz</string> 25 <string name="back">Wstecz</string>
26 <string name="add_games">Dodaj gry</string> 26 <string name="add_games">Dodaj gry</string>
27 <string name="add_games_description">Wybierz folder zawierajÄ…cy Twoje gry</string> 27 <string name="add_games_description">Wybierz folder zawierajÄ…cy Twoje gry</string>
28
29 <!-- Home strings --> 28 <!-- Home strings -->
30 <string name="home_games">Gry</string> 29 <string name="home_games">Gry</string>
31 <string name="home_search">Szukaj</string> 30 <string name="home_search">Szukaj</string>
@@ -61,6 +60,8 @@
61 <string name="invalid_keys_file">Wybrano niepoprawne klucze</string> 60 <string name="invalid_keys_file">Wybrano niepoprawne klucze</string>
62 <string name="install_keys_success">Klucze zainstalowane pomyślnie</string> 61 <string name="install_keys_success">Klucze zainstalowane pomyślnie</string>
63 <string name="reading_keys_failure">Błąd podczas odczytu kluczy</string> 62 <string name="reading_keys_failure">Błąd podczas odczytu kluczy</string>
63 <string name="install_prod_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .keys i spróbuj ponownie.</string>
64 <string name="install_amiibo_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .bin i spróbuj ponownie.</string>
64 <string name="invalid_keys_error">Niepoprawne klucze</string> 65 <string name="invalid_keys_error">Niepoprawne klucze</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.</string> 67 <string name="install_keys_failure_description">Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.</string>
@@ -86,7 +87,17 @@
86 <string name="save_file_invalid_zip_structure_description">Pierwszy podkatalog musi zawierać w nazwie numer ID tytułu gry.</string> 87 <string name="save_file_invalid_zip_structure_description">Pierwszy podkatalog musi zawierać w nazwie numer ID tytułu gry.</string>
87 <string name="import_saves">Importuj</string> 88 <string name="import_saves">Importuj</string>
88 <string name="export_saves">Eksportuj</string> 89 <string name="export_saves">Eksportuj</string>
89 90 <string name="install_firmware">Zainstaluj firmware</string>
91 <string name="install_firmware_description">Firmware musi być w postaci archiwum ZIP, niektóre gry wymagają go do uruchomienia/prawidłowego działania</string>
92 <string name="firmware_installing">InstalujÄ™ firmware</string>
93 <string name="firmware_installed_success">Zainstalowano pomyślnie</string>
94 <string name="firmware_installed_failure">Błąd podczas instalacji firmware</string>
95 <string name="share_log">Udostępnij logi debugowania</string>
96 <string name="share_log_description">Podziel się logami yuzu, pomoże to twórcom w poprawie działania emulatora</string>
97 <string name="share_log_missing">Nie znaleziono plików logów</string>
98 <string name="install_game_content">Zainstaluj zawartość gry</string>
99 <string name="install_game_content_description">Zainstaluj aktualizacjÄ™ gry lub dodatek DLC</string>
100 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
90 <!-- About screen strings --> 101 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia isn\'t real</string> 102 <string name="gaia_is_not_real">Gaia isn\'t real</string>
92 <string name="copied_to_clipboard">Skopiowano do schowka</string> 103 <string name="copied_to_clipboard">Skopiowano do schowka</string>
@@ -94,6 +105,7 @@
94 <string name="contributors">Współtwórcy</string> 105 <string name="contributors">Współtwórcy</string>
95 <string name="contributors_description">Stworzone z \u2764 przez zespół yuzu</string> 106 <string name="contributors_description">Stworzone z \u2764 przez zespół yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 107 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
108 <string name="licenses_description">Projekty dzięki którym yuzu mógł zostać stworzony</string>
97 <string name="build">Wersja</string> 109 <string name="build">Wersja</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 110 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 111 <string name="website_link">https://yuzu-emu.org/</string>
@@ -114,27 +126,25 @@
114 <string name="are_you_interested">JesteÅ› zainteresowany?</string> 126 <string name="are_you_interested">JesteÅ› zainteresowany?</string>
115 127
116 <!-- General settings strings --> 128 <!-- General settings strings -->
117 <string name="frame_limit_enable">Włącz limit szybkości emulacji</string> 129 <string name="frame_limit_enable">Limit szybkość</string>
118 <string name="frame_limit_enable_description">Włącz, aby ustawić procentowy limit szybkości emulacji</string> 130 <string name="frame_limit_enable_description">Włącz, aby ustawić procentowy limit szybkości emulacji</string>
119 <string name="frame_limit_slider">Procentowy limit szybkości emulacji</string> 131 <string name="frame_limit_slider">Procentowy limit szybkości emulacji</string>
120 <string name="frame_limit_slider_description">Określa limit szybkości emulacji gier. Domyślna wartość 100% oznacza normalną szybkość z jaką działa gra. Wartości niższe lub wyższe zmniejszą lub zwiększą limit szybkości.</string> 132 <string name="frame_limit_slider_description">Określa limit szybkości emulacji gier. Domyślna wartość 100% oznacza normalną szybkość z jaką działa gra. Wartości niższe lub wyższe zmniejszą lub zwiększą limit szybkości.</string>
121 <string name="cpu_accuracy">Dokładność procesora CPU</string> 133 <string name="cpu_accuracy">Dokładność procesora CPU</string>
122
123 <!-- System settings strings --> 134 <!-- System settings strings -->
124 <string name="use_docked_mode">Tryb zadokowany</string> 135 <string name="use_docked_mode">Tryb zadokowany</string>
125 <string name="use_docked_mode_description">Emulacja w trybie stacji dokującej, zwiększa rozdzielczość kosztem wydajności.</string> 136 <string name="use_docked_mode_description">Zwiększa rozdzielczość kosztem wydajności. Kiedy wyłączone, używany jest tryb Handheld, który obniża rozdzielczość i dzięki temu zwiększa wydajność.</string>
126 <string name="emulated_region">Region emulacji</string> 137 <string name="emulated_region">Region emulacji</string>
127 <string name="emulated_language">Język emulacji</string> 138 <string name="emulated_language">Język emulacji</string>
128 <string name="select_rtc_date">Ustaw datÄ™ RTC</string> 139 <string name="select_rtc_date">Ustaw datÄ™ RTC</string>
129 <string name="select_rtc_time">Ustaw czas RTC</string> 140 <string name="select_rtc_time">Ustaw czas RTC</string>
130 <string name="use_custom_rtc">Włącz niestandardowy zegar RTC</string> 141 <string name="use_custom_rtc">Niestandardowy RTC</string>
131 <string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string> 142 <string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
132 <string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string> 143 <string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
133 144
134 <!-- Graphics settings strings --> 145 <!-- Graphics settings strings -->
135 <string name="renderer_api">Interfejs graficzny</string>
136 <string name="renderer_accuracy">Poziom precyzji emulacji</string> 146 <string name="renderer_accuracy">Poziom precyzji emulacji</string>
137 <string name="renderer_resolution">Rozdzielczość</string> 147 <string name="renderer_resolution">Rozdzielczość (Handheld/Zadokowany)</string>
138 <string name="renderer_vsync">Synchronizacja pionowa VSync</string> 148 <string name="renderer_vsync">Synchronizacja pionowa VSync</string>
139 <string name="renderer_aspect_ratio">Proporcje ekranu</string> 149 <string name="renderer_aspect_ratio">Proporcje ekranu</string>
140 <string name="renderer_scaling_filter">Filtr adaptacji rozdzielczości</string> 150 <string name="renderer_scaling_filter">Filtr adaptacji rozdzielczości</string>
@@ -143,12 +153,16 @@
143 <string name="renderer_force_max_clock_description">Wymusza uruchomienie maksymalnego taktowania układu graficznego (zabezpieczenia termiczne będą dalej aktywne).</string> 153 <string name="renderer_force_max_clock_description">Wymusza uruchomienie maksymalnego taktowania układu graficznego (zabezpieczenia termiczne będą dalej aktywne).</string>
144 <string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string> 154 <string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string>
145 <string name="renderer_asynchronous_shaders_description">Kompiluj oświetlenie bez synchronizacji, poprawi wydajność ale może powodować błędy.</string> 155 <string name="renderer_asynchronous_shaders_description">Kompiluj oświetlenie bez synchronizacji, poprawi wydajność ale może powodować błędy.</string>
146 <string name="renderer_debug">Włącz debugowanie grafiki</string> 156 <string name="renderer_reactive_flushing">Użyj spłukiwania reaktywnego - reactive flushing</string>
147 <string name="renderer_debug_description">Kiedy włączone, interfejs graficzny korzysta z wolnego trybu debugowania błędów.</string> 157 <string name="renderer_reactive_flushing_description">Poprawia jakość renderowania w kilku grach, kosztem wydajności.</string>
148 <string name="use_disk_shader_cache">Użyj pamięci podręcznej shaderów na dysku</string> 158 <string name="use_disk_shader_cache">Pamięć podręczna shaderów</string>
149 <string name="use_disk_shader_cache_description">Zmniejsza przycięcia przez przechowywanie gotowych wygenerowanych plików oświetlenia w pamięci urządzenia.</string> 159 <string name="use_disk_shader_cache_description">Zmniejsza przycięcia przez przechowywanie gotowych wygenerowanych plików oświetlenia w pamięci urządzenia.</string>
150 160
151 <!-- Audio settings strings --> 161 <!-- Debug settings strings -->
162 <string name="cpu">CPU</string>
163 <string name="renderer_api">Interfejs graficzny</string>
164 <string name="renderer_debug">Debugowanie grafiki</string>
165 <string name="renderer_debug_description">Kiedy włączone, interfejs graficzny korzysta z wolnego trybu debugowania błędów.</string>
152 <string name="audio_volume">Głośność</string> 166 <string name="audio_volume">Głośność</string>
153 <string name="audio_volume_description">Ustala poziom głośności wyjścia dźwięku.</string> 167 <string name="audio_volume_description">Ustala poziom głośności wyjścia dźwięku.</string>
154 168
@@ -161,17 +175,21 @@
161 <string name="reset_setting_confirmation">Przywrócić wartość tego ustawienia do wartości domyślnej?</string> 175 <string name="reset_setting_confirmation">Przywrócić wartość tego ustawienia do wartości domyślnej?</string>
162 <string name="reset_to_default">Przywróć ustawienia domyślne</string> 176 <string name="reset_to_default">Przywróć ustawienia domyślne</string>
163 <string name="reset_all_settings">Przywrócić WSZYSTKIE ustawienia?</string> 177 <string name="reset_all_settings">Przywrócić WSZYSTKIE ustawienia?</string>
164 <string name="reset_all_settings_description">Wszystkie zaawansowane opcje zostaną przywrócone do wartości domyślnych. Czynności nie będzie można cofnąć.</string> 178 <string name="reset_all_settings_description">Wszystkie zaawansowane opcje zostaną przywrócone do wartości domyślnych. Czynności nie będzie można cofnąć</string>
165 <string name="settings_reset">Reset ustawień</string> 179 <string name="settings_reset">Reset ustawień</string>
166 <string name="close">Zamknij</string> 180 <string name="close">Zamknij</string>
167 <string name="learn_more">Dowiedz się więcej</string> 181 <string name="learn_more">Dowiedz się więcej</string>
168 182 <string name="auto">Automatyczny</string>
183 <string name="submit">Zatwierdź</string>
184 <string name="string_import">Importuj</string>
185 <string name="export">Eksportuj</string>
169 <!-- GPU driver installation --> 186 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Wybierz sterownik GPU </string> 187 <string name="select_gpu_driver">Wybierz sterownik GPU </string>
171 <string name="select_gpu_driver_title">Chcesz zastąpić obecny sterownik układu graficznego?</string> 188 <string name="select_gpu_driver_title">Chcesz zastąpić obecny sterownik układu graficznego?</string>
172 <string name="select_gpu_driver_install">Zainstaluj</string> 189 <string name="select_gpu_driver_install">Zainstaluj</string>
173 <string name="select_gpu_driver_default">Domyślne</string> 190 <string name="select_gpu_driver_default">Domyślne</string>
174 <string name="select_gpu_driver_use_default">Aktywny domyślny sterownik GPU</string> 191 <string name="select_gpu_driver_use_default">Aktywny domyślny sterownik GPU</string>
192 <string name="select_gpu_driver_error">Wybrano błędny sterownik, powrót do domyślnego. </string>
175 <string name="system_gpu_driver">Systemowy sterownik GPU</string> 193 <string name="system_gpu_driver">Systemowy sterownik GPU</string>
176 <string name="installing_driver">Instalowanie sterownika...</string> 194 <string name="installing_driver">Instalowanie sterownika...</string>
177 195
@@ -182,10 +200,10 @@
182 <string name="preferences_graphics">Grafika</string> 200 <string name="preferences_graphics">Grafika</string>
183 <string name="preferences_audio">Dźwięk</string> 201 <string name="preferences_audio">Dźwięk</string>
184 <string name="preferences_theme">Motyw i kolor</string> 202 <string name="preferences_theme">Motyw i kolor</string>
203 <string name="preferences_debug">Debug</string>
185 204
186 <!-- ROM loading errors --> 205 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">Twój ROM jest zakodowany</string> 206 <string name="loader_error_encrypted">Twój ROM jest zakodowany</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Użyj przewodnika aby wykonać zrzuty <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">kardridży</a> lub <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">zainstalowanych gier</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Upewnij się że plik kluczy <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> jest zainstalowany aby gry mogły zostać odczytane.]]></string> 207 <string name="loader_error_encrypted_keys_description"><![CDATA[Upewnij się że plik kluczy <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> jest zainstalowany aby gry mogły zostać odczytane.]]></string>
190 <string name="loader_error_video_core">Błąd inicjacji podsystemu graficznego</string> 208 <string name="loader_error_video_core">Błąd inicjacji podsystemu graficznego</string>
191 <string name="loader_error_video_core_description">Zazwyczaj spowodowane niekompatybilnym sterownikiem GPU, instalacja niestandardowego sterownika może rozwiązać ten problem.</string> 209 <string name="loader_error_video_core_description">Zazwyczaj spowodowane niekompatybilnym sterownikiem GPU, instalacja niestandardowego sterownika może rozwiązać ten problem.</string>
@@ -198,23 +216,23 @@
198 <string name="emulation_fps_counter">Licznik FPS</string> 216 <string name="emulation_fps_counter">Licznik FPS</string>
199 <string name="emulation_toggle_controls">Wybierz przyciski</string> 217 <string name="emulation_toggle_controls">Wybierz przyciski</string>
200 <string name="emulation_rel_stick_center">Wycentruj gałki</string> 218 <string name="emulation_rel_stick_center">Wycentruj gałki</string>
201 <string name="emulation_dpad_slide">Ruchomy DPad</string> 219 <string name="emulation_dpad_slide">Ruchomy D-pad</string>
202 <string name="emulation_haptics">Wibracje haptyczne</string> 220 <string name="emulation_haptics">Wibracje haptyczne</string>
203 <string name="emulation_show_overlay">Pokaż przyciski</string> 221 <string name="emulation_show_overlay">Pokaż przyciski</string>
204 <string name="emulation_toggle_all">Zaznacz wszystkie</string> 222 <string name="emulation_toggle_all">Włącz wszystkie</string>
205 <string name="emulation_control_adjust">Dostosuj nakładkę</string> 223 <string name="emulation_control_adjust">Dostosuj nakładkę</string>
206 <string name="emulation_control_scale">Skala</string> 224 <string name="emulation_control_scale">Skala</string>
207 <string name="emulation_control_opacity">Przeźroczystość</string> 225 <string name="emulation_control_opacity">Przeźroczystość</string>
208 <string name="emulation_touch_overlay_reset">Resetuj</string> 226 <string name="emulation_touch_overlay_reset">Resetuj nakładkę</string>
209 <string name="emulation_touch_overlay_edit">Edytuj nakładkę</string> 227 <string name="emulation_touch_overlay_edit">Edytuj nakładkę</string>
210 <string name="emulation_pause">Wstrzymaj emulacjÄ™</string> 228 <string name="emulation_pause">Wstrzymaj emulacjÄ™</string>
211 <string name="emulation_unpause">Wznów emulację</string> 229 <string name="emulation_unpause">Wznów emulację</string>
212 <string name="emulation_input_overlay">Opcje nakładki</string> 230 <string name="emulation_input_overlay">Opcje nakładki</string>
213 231
214 <string name="load_settings">Wczytywanie ustawień...</string> 232 <string name="load_settings">Wczytuję ustawienia...</string>
215 233
216 <!-- Software keyboard --> 234 <!-- Software keyboard -->
217 <string name="software_keyboard">Klawiatura systemowa</string> 235 <string name="software_keyboard">Klawiatura programowa</string>
218 236
219 <!-- Errors and warnings --> 237 <!-- Errors and warnings -->
220 <string name="abort_button">Przerwij</string> 238 <string name="abort_button">Przerwij</string>
@@ -226,7 +244,6 @@
226 <string name="fatal_error">Błąd krytyczny</string> 244 <string name="fatal_error">Błąd krytyczny</string>
227 <string name="fatal_error_message">Wystąpił błąd krytyczny. Szczegóły znajdziesz w pliku log.\nKontynuowanie może spowodować błędy lub przerwanie emulacji. </string> 245 <string name="fatal_error_message">Wystąpił błąd krytyczny. Szczegóły znajdziesz w pliku log.\nKontynuowanie może spowodować błędy lub przerwanie emulacji. </string>
228 <string name="performance_warning">Wyłączenie tej opcji znacząco ograniczy wydajność! Dla najlepszego doświadczenia, zaleca się zostawienie tej opcji włączonej.</string> 246 <string name="performance_warning">Wyłączenie tej opcji znacząco ograniczy wydajność! Dla najlepszego doświadczenia, zaleca się zostawienie tej opcji włączonej.</string>
229
230 <!-- Region Names --> 247 <!-- Region Names -->
231 <string name="region_japan">Japonia</string> 248 <string name="region_japan">Japonia</string>
232 <string name="region_usa">USA</string> 249 <string name="region_usa">USA</string>
@@ -236,8 +253,7 @@
236 <string name="region_korea">Korea</string> 253 <string name="region_korea">Korea</string>
237 <string name="region_taiwan">Tajwan</string> 254 <string name="region_taiwan">Tajwan</string>
238 255
239 <!-- Language Names --> 256 <string name="memory_gigabyte">GB</string>
240
241 <!-- Renderer APIs --> 257 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 258 <string name="renderer_vulkan">Vulkan</string>
243 <string name="renderer_none">Żadny</string> 259 <string name="renderer_none">Żadny</string>
@@ -274,12 +290,14 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 290 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 291 <string name="anti_aliasing_smaa">SMAA</string>
276 292
293 <string name="screen_layout_auto">Automatyczny</string>
294
277 <!-- Aspect Ratios --> 295 <!-- Aspect Ratios -->
278 <string name="ratio_default">Domyślne (16:9)</string> 296 <string name="ratio_default">Domyślne (16:9)</string>
279 <string name="ratio_force_four_three">WymuÅ› 4:3</string> 297 <string name="ratio_force_four_three">WymuÅ› 4:3</string>
280 <string name="ratio_force_twenty_one_nine">WymuÅ› 21:9</string> 298 <string name="ratio_force_twenty_one_nine">WymuÅ› 21:9</string>
281 <string name="ratio_force_sixteen_ten">WymuÅ› 16:10</string> 299 <string name="ratio_force_sixteen_ten">WymuÅ› 16:10</string>
282 <string name="ratio_stretch">RozciÄ…gnij do Okna</string> 300 <string name="ratio_stretch">RozciÄ…gnij do okna</string>
283 301
284 <!-- CPU Accuracy --> 302 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Dokładny</string> 303 <string name="cpu_accuracy_accurate">Dokładny</string>
@@ -287,7 +305,7 @@
287 <string name="cpu_accuracy_paranoid">Paranoid (Wolny)</string> 305 <string name="cpu_accuracy_paranoid">Paranoid (Wolny)</string>
288 306
289 <!-- Gamepad Buttons --> 307 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">D-Pad</string> 308 <string name="gamepad_d_pad">D-pad</string>
291 <string name="gamepad_left_stick">Lewa gałka</string> 309 <string name="gamepad_left_stick">Lewa gałka</string>
292 <string name="gamepad_right_stick">Prawa gałka</string> 310 <string name="gamepad_right_stick">Prawa gałka</string>
293 <string name="gamepad_home">Home</string> 311 <string name="gamepad_home">Home</string>
@@ -298,18 +316,21 @@
298 <string name="building_shaders">Budowanie shaderów</string> 316 <string name="building_shaders">Budowanie shaderów</string>
299 317
300 <!-- Theme options --> 318 <!-- Theme options -->
301 <string name="change_app_theme">Zmień motyw aplikacji</string> 319 <string name="change_app_theme">Ustaw motyw aplikacji</string>
302 <string name="theme_default">Domyślny</string> 320 <string name="theme_default">Domyślny</string>
303 <string name="theme_material_you">Material You</string> 321 <string name="theme_material_you">Material You</string>
304 322
305 <!-- Theme Modes --> 323 <!-- Theme Modes -->
306 <string name="change_theme_mode">Zmiana trybu motywu</string> 324 <string name="change_theme_mode">Zmień tryb motywu</string>
307 <string name="theme_mode_follow_system">Podążaj za systemowym</string> 325 <string name="theme_mode_follow_system">Podążaj za systemowym</string>
308 <string name="theme_mode_light">Jasny</string> 326 <string name="theme_mode_light">Jasny</string>
309 <string name="theme_mode_dark">Ciemny</string> 327 <string name="theme_mode_dark">Ciemny</string>
310 328
311 <!-- Black backgrounds theme --> 329 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Używaj czarnego tła</string> 330 <string name="use_black_backgrounds">Czarne tła</string>
313 <string name="use_black_backgrounds_description">Kiedy używany ciemny motyw, tła zostają zastąpione czernią.</string> 331 <string name="use_black_backgrounds_description">Kiedy używany ciemny motyw, tła zostają zastąpione czernią.</string>
314 332
315</resources> 333 <!-- Licenses screen strings -->
334 <string name="licenses">Licencje</string>
335 <string name="license_fidelityfx_fsr_description">Rozciąganie wysokiej jakości od AMD</string>
336 </resources>
diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml
index caa095364..8888fc750 100644
--- a/src/android/app/src/main/res/values-pt-rBR/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,30 +1,31 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Este software corre jogos para a consola Nintendo Switch. Não estão incluídas nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começares, por favor localiza o ficheiro <![CDATA[1 prod.keys 1]]> no armazenamento do teu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Learn more2]]></string> 4 <string name="app_disclaimer">Este software executa jogos do console Nintendo Switch. Não estão inclusos nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começar, por favor localize o arquivo <![CDATA[1 prod.keys 1]]> no armazenamento de seu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Saiba mais2]]></string>
5 <string name="emulation_notification_channel_name">Emulação está Ativa</string> 5 <string name="emulation_notification_channel_name">Emulação está Ativa</string>
6 <string name="emulation_notification_channel_description">Mostra uma notificação permanente enquanto a emulação está a correr.</string> 6 <string name="emulation_notification_channel_description">Mostra uma notificação permanente enquanto a emulação estiver em andamento.</string>
7 <string name="emulation_notification_running">Yuzu está em execução </string> 7 <string name="emulation_notification_running">Yuzu está em execução </string>
8 <string name="notice_notification_channel_name">Notificações e erros</string> 8 <string name="notice_notification_channel_name">Notificações e erros</string>
9 <string name="notice_notification_channel_description">Mostra notificações quendo algo corre mal.</string> 9 <string name="notice_notification_channel_description">Mostra notificações quando algo dá errado.</string>
10 <string name="notification_permission_not_granted">Permissões de notificação não permitidas </string> 10 <string name="notification_permission_not_granted">Acesso às notificações não concedido!</string>
11 11
12 <!-- Setup strings --> 12 <!-- Setup strings -->
13 <string name="welcome">Bemvindo! </string> 13 <string name="welcome">Bem-vindo! </string>
14 <string name="welcome_description">Aprende como configurar &lt;b>yuzu&lt;/b> e arranca a emulação.</string> 14 <string name="welcome_description">Aprenda como configurar o &lt;b>yuzu&lt;/b> e mergulhe na emulação.</string>
15 <string name="get_started">Começa</string> 15 <string name="get_started">Primeiros passos</string>
16 <string name="keys">Chaves</string> 16 <string name="keys">Keys</string>
17 <string name="keys_description">Seleciona o teu ficheiro &lt;b>prod.keys&lt;/b> com o botão abaixo.</string> 17 <string name="keys_description">Selecione seu arquivo &lt;b>prod.keys&lt;/b> com o botão abaixo.</string>
18 <string name="select_keys">Seleciona as Chaves</string> 18 <string name="select_keys">Selecione as Keys</string>
19 <string name="games">Jogos</string> 19 <string name="games">Jogos</string>
20 <string name="games_description">Seleciona a tua pasta &lt;b>Games&lt;/b> com o botão abaixo.</string> 20 <string name="games_description">Seleciona sua pasta &lt;b>Jogos&lt;/b> com o botão abaixo.</string>
21 <string name="done">Feito</string> 21 <string name="done">Feito</string>
22 <string name="done_description">Tudo pronto.\nDisfruta dos teus jogos!</string> 22 <string name="done_description">Tudo pronto.\nAproveite seus jogos!</string>
23 <string name="text_continue">Continuar</string> 23 <string name="text_continue">Continuar</string>
24 <string name="next">Próximo</string> 24 <string name="next">Próximo</string>
25 <string name="back">Voltar</string> 25 <string name="back">Voltar</string>
26 <string name="add_games">Adiciona Jogos</string> 26 <string name="add_games">Adicionar Jogos</string>
27 <string name="add_games_description">Seleciona a tua pasta de Jogos</string> 27 <string name="add_games_description">Selecione sua pasta de Jogos</string>
28 <string name="step_complete">Completo!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Jogos</string> 31 <string name="home_games">Jogos</string>
@@ -37,7 +38,8 @@
37 <string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string> 38 <string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string>
38 <string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string> 39 <string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Procurar Jogos</string> 41 <string name="home_search_games">Procurar jogos</string>
42 <string name="search_settings">Procurar nas definições</string>
41 <string name="games_dir_selected">Pasta de Jogos selecionada</string> 43 <string name="games_dir_selected">Pasta de Jogos selecionada</string>
42 <string name="install_prod_keys">Instala prod.keys</string> 44 <string name="install_prod_keys">Instala prod.keys</string>
43 <string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string> 45 <string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string>
@@ -61,15 +63,18 @@
61 <string name="invalid_keys_file">Ficheiro de chaves inválido</string> 63 <string name="invalid_keys_file">Ficheiro de chaves inválido</string>
62 <string name="install_keys_success">Chaves instaladas com sucesso</string> 64 <string name="install_keys_success">Chaves instaladas com sucesso</string>
63 <string name="reading_keys_failure">Erro ao ler chaves de encriptação</string> 65 <string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
66 <string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
64 <string name="invalid_keys_error">Chaves de encriptação inválidas</string> 68 <string name="invalid_keys_error">Chaves de encriptação inválidas</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string> 70 <string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
67 <string name="install_gpu_driver">Instala driver para GPU</string> 71 <string name="install_gpu_driver">Instala driver para GPU</string>
68 <string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string> 72 <string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
69 <string name="advanced_settings">Definições avançadas</string> 73 <string name="advanced_settings">Definições avançadas</string>
74 <string name="advanced_settings_game">Definições avançadas: %1$s</string>
70 <string name="settings_description">Configura definições do emulador</string> 75 <string name="settings_description">Configura definições do emulador</string>
71 <string name="search_recently_played">Jogos recentes</string> 76 <string name="search_recently_played">Jogado recentemente</string>
72 <string name="search_recently_added">Adicionados recentemente</string> 77 <string name="search_recently_added">Adicionado recentemente</string>
73 <string name="search_retail">Jogos comerciais</string> 78 <string name="search_retail">Jogos comerciais</string>
74 <string name="search_homebrew">Homebrew</string> 79 <string name="search_homebrew">Homebrew</string>
75 <string name="open_user_folder">Abre a pasta Yuzu</string> 80 <string name="open_user_folder">Abre a pasta Yuzu</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string> 91 <string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string>
87 <string name="import_saves">Importar</string> 92 <string name="import_saves">Importar</string>
88 <string name="export_saves">Exportar</string> 93 <string name="export_saves">Exportar</string>
94 <string name="install_firmware">Instalar firmware</string>
95 <string name="install_firmware_description">O firmware deve estar em um arquivo ZIP e é necessário para iniciar alguns jogos.</string>
96 <string name="firmware_installing">Instalando firmware</string>
97 <string name="firmware_installed_success">Firmware instalado com sucesso.</string>
98 <string name="firmware_installed_failure">Falha na instalação do firmware</string>
99 <string name="firmware_installed_failure_description">Cofirma que os ficheiros firmware nca estão no root do finheiro zip e tenta de novo.</string>
100 <string name="share_log">Compartilhe registros de debug.</string>
101 <string name="share_log_description">Compartilhe o arquivo de registro do yuzu para obter ajuda com problemas</string>
102 <string name="share_log_missing">Arquivo de registro não encontrado</string>
103 <string name="install_game_content">Instalar conteúdo de jogos</string>
104 <string name="install_game_content_description">Instalar atualizações de jogos ou DLC</string>
105 <string name="installing_game_content">A instalar conteúdo...</string>
106 <string name="install_game_content_failure">Erro ao instalar ficheiro(s) para NAND</string>
107 <string name="install_game_content_failure_description">Por favor confitma que o conteúdo(s) é válido e que as prod.keys estão instaladas.</string>
108 <string name="install_game_content_failure_base">A instalação de jogos base não é permitida para evitar possíveis conflitos.</string>
109 <string name="install_game_content_failure_file_extension">Sò conteúdos NSP e XCI são suportados. Por favor verifica que o conteúdo(s) do jogo são válidos.</string>
110 <string name="install_game_content_failed_count">%1$d erro(s) de instalação</string>
111 <string name="install_game_content_success">Conteúdo(s) de jogo instalados com sucesso</string>
112 <string name="install_game_content_success_install">%1$d instalado com sucesso</string>
113 <string name="install_game_content_success_overwrite">%1$d substituída com êxito</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">Drivers personalizados não suportados</string>
116 <string name="custom_driver_not_supported_description">Carrea«gamento de drivers personalizados não é suportado pr este dispositivo. \nCheck verifica esta opção de futuro para confirmar se o suporte foi adicionado!</string>
117 <string name="manage_yuzu_data">Administrar dados yuzu</string>
118 <string name="manage_yuzu_data_description">Importa/exporta firmware, chaves, dados do usuário e mais!</string>
119 <string name="share_save_file">Partilha ficheiro duardado</string>
120 <string name="export_save_failed">Erro ao exportar dados guardados</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia não é real</string> 123 <string name="gaia_is_not_real">Gaia não é real</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">Contribuidores</string> 126 <string name="contributors">Contribuidores</string>
95 <string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string> 127 <string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Projetos que tornam o yuzu para Android possível</string>
97 <string name="build">Versão</string> 130 <string name="build">Versão</string>
131 <string name="user_data">Dado de utilizados</string>
132 <string name="user_data_description">Importar/exportar todos dados da aplicação data.\n\n Ao importar dados do utilizados, todos os dados existentes do utilizados serão excluídos!</string>
133 <string name="exporting_user_data">A exportar dados de utilizados...</string>
134 <string name="importing_user_data">A importar dados de utilizador...</string>
135 <string name="import_user_data">Importar dados de utilizados...</string>
136 <string name="invalid_yuzu_backup">Backup yuzu inválido</string>
137 <string name="user_data_export_success">Dados de utilizados exportados com sucesso</string>
138 <string name="user_data_import_success">Dados de utilizador importado com sucesso</string>
139 <string name="user_data_export_cancelled">Exportação cancelada</string>
140 <string name="user_data_import_failed_description">Verifiqua se as pastas de dados do utilizados estão na raiz da pasta zip e contêm um arquivo de configuração em config/config.ini e tenta novamente.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
114 <string name="are_you_interested">Estás interessado?</string> 157 <string name="are_you_interested">Estás interessado?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">Ativar limite de velocidade</string> 160 <string name="frame_limit_enable">Limite de velocidade</string>
118 <string name="frame_limit_enable_description">Quando ativada, a velocidade da emulação será limitada à percentagem definida da velocidade normal.</string> 161 <string name="frame_limit_enable_description">Limita a velocidade da emulação a uma porcentagem específica da velocidade normal.</string>
119 <string name="frame_limit_slider">Percentagem do limite de velocidade</string> 162 <string name="frame_limit_slider">Percentagem do limite de velocidade</string>
120 <string name="frame_limit_slider_description">Especifica o limite da percentagem da velocidade da emulação. Com a velocidade por defeito a 100% a emulação será limitada à velocidade normal. Valores maiores ou menores aumentarão ou diminuirão o limite de velocidade.</string> 163 <string name="frame_limit_slider_description">Especifica a porcentagem para limitar a velocidade de emulação. 100% é o normal. Valores mais altos ou mais baixos irão aumentar ou diminuir o limite de velocidade.</string>
121 <string name="cpu_accuracy">Precisão do CPU</string> 164 <string name="cpu_accuracy">Precisão do CPU</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">Modo ancorado</string> 168 <string name="use_docked_mode">Modo Ancorado</string>
125 <string name="use_docked_mode_description">Emula em modo ancorado, que aumenta a resolução ás custas da performance.</string> 169 <string name="use_docked_mode_description">Aumenta a resolução, diminuindo o desempenho. O Modo Portátil é utilizado quando estiver desabilitado, diminuindo a resolução e melhorando o desempenho.</string>
126 <string name="emulated_region">Região da emulação</string> 170 <string name="emulated_region">Região da emulação</string>
127 <string name="emulated_language">Idioma da emulação</string> 171 <string name="emulated_language">Idioma da emulação</string>
128 <string name="select_rtc_date">Seleciona a data RTC</string> 172 <string name="select_rtc_date">Selecione a data do sistema</string>
129 <string name="select_rtc_time">Seleciona a hora RTC</string> 173 <string name="select_rtc_time">Selecione a hora do sistema</string>
130 <string name="use_custom_rtc">Ativa RTC personalizado</string> 174 <string name="use_custom_rtc">Data e hora personalizada</string>
131 <string name="use_custom_rtc_description">Esta configuração permite definir um RTC personalizado diferente da hora atual do sistema</string> 175 <string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
132 <string name="set_custom_rtc">Define RTC personalizado</string> 176 <string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Nível de precisão</string> 179 <string name="renderer_accuracy">Nível de precisão</string>
137 <string name="renderer_resolution">Resolução</string> 180 <string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
138 <string name="renderer_vsync">Modo VSync</string> 181 <string name="renderer_vsync">Modo VSync</string>
139 <string name="renderer_aspect_ratio">Proporção do ecrã</string> 182 <string name="renderer_screen_layout">Oriantação</string>
183 <string name="renderer_aspect_ratio">Proporção da tela</string>
140 <string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string> 184 <string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
141 <string name="renderer_anti_aliasing">Método de Anti-Aliasing </string> 185 <string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
142 <string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string> 186 <string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string>
143 <string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string> 187 <string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string>
144 <string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string> 188 <string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string>
145 <string name="renderer_asynchronous_shaders_description">Compila shaders assincronamente, que aumentará a fluidez, mas poderá causar falhas.</string> 189 <string name="renderer_asynchronous_shaders_description">Compila os shaders de forma assíncrona, reduzindo travamentos, mas pode apresentar problemas.</string>
190 <string name="renderer_reactive_flushing">Usar flushing reativo</string>
191 <string name="renderer_reactive_flushing_description">Melhora a precisão da renderização em alguns jogos ao custo de desempenho.</string>
192 <string name="use_disk_shader_cache">Cache de shaders em disco</string>
193 <string name="use_disk_shader_cache_description">Reduz travamentos ao armazenar e carregar localmente os shaders.</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">Depuração da CPU</string>
198 <string name="cpu_debug_mode_description">Coloca a CPU em um modo de depuração lento.</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
146 <string name="renderer_debug">Ativar depuração de gráficos</string> 201 <string name="renderer_debug">Ativar depuração de gráficos</string>
147 <string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string> 202 <string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string>
148 <string name="use_disk_shader_cache">Usar cache de shaders em disco</string> 203 <string name="fastmem">Fastmem</string>
149 <string name="use_disk_shader_cache_description">Aumenta a fluidez ao guardar e carregar shaders gerados para o armazenamento.</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">Motor de saída</string>
152 <string name="audio_volume">Volume</string> 207 <string name="audio_volume">Volume</string>
153 <string name="audio_volume_description">Especifica o volume de saída.</string> 208 <string name="audio_volume_description">Especifica o volume de saída.</string>
154 209
@@ -157,14 +212,24 @@
157 <string name="ini_saved">Definições guardadas</string> 212 <string name="ini_saved">Definições guardadas</string>
158 <string name="gameid_saved">Definições guardadas para %1$s</string> 213 <string name="gameid_saved">Definições guardadas para %1$s</string>
159 <string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string> 214 <string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string>
215 <string name="unimplemented_menu">Menu não implementado</string>
160 <string name="loading">A carregar...</string> 216 <string name="loading">A carregar...</string>
217 <string name="shutting_down">A desligar...</string>
161 <string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string> 218 <string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string>
162 <string name="reset_to_default">Reverter para padrão</string> 219 <string name="reset_to_default">Reverter para padrão</string>
163 <string name="reset_all_settings">Redefinir todas as definições?</string> 220 <string name="reset_all_settings">Redefinir todas as definições?</string>
164 <string name="reset_all_settings_description">Todas as definições avançadas serão redefinidas para as definições padrão. Isto não pode ser revertido.</string> 221 <string name="reset_all_settings_description">Todas as configurações avançadas retornarão ao padrão. Isto não pode ser desfeito.</string>
165 <string name="settings_reset">Redefinir definições</string> 222 <string name="settings_reset">Redefinir definições</string>
166 <string name="close">Fechar</string> 223 <string name="close">Fechar</string>
167 <string name="learn_more">Saiba mais</string> 224 <string name="learn_more">Saiba mais</string>
225 <string name="auto">Automático</string>
226 <string name="submit">Enviar</string>
227 <string name="string_null">Nenhum (desativado)</string>
228 <string name="string_import">Importar</string>
229 <string name="export">Exportar</string>
230 <string name="export_failed">Exportação falhada</string>
231 <string name="import_failed">IMportação falhada</string>
232 <string name="cancelling">A cancelar</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Seleciona a driver para o GPU</string> 235 <string name="select_gpu_driver">Seleciona a driver para o GPU</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">Instalar</string> 237 <string name="select_gpu_driver_install">Instalar</string>
173 <string name="select_gpu_driver_default">Padrão</string> 238 <string name="select_gpu_driver_default">Padrão</string>
174 <string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string> 239 <string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string>
240 <string name="select_gpu_driver_error">Driver selecionado inválido, a usar o padrão do sistema!</string>
175 <string name="system_gpu_driver">Driver do GPU padrão</string> 241 <string name="system_gpu_driver">Driver do GPU padrão</string>
176 <string name="installing_driver">A instalar o Driver...</string> 242 <string name="installing_driver">A instalar o Driver...</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">Gráficos</string> 248 <string name="preferences_graphics">Gráficos</string>
183 <string name="preferences_audio">Ãudio</string> 249 <string name="preferences_audio">Ãudio</string>
184 <string name="preferences_theme">Cor e tema.</string> 250 <string name="preferences_theme">Cor e tema.</string>
251 <string name="preferences_debug">Depuração</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">A tua ROM está encriptada</string> 254 <string name="loader_error_encrypted">A tua ROM está encriptada</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor segue os guias para fazer redump das tuas<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">Cartidges de Jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">Jogos Instalados</a>.]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga os guias para despejar novamente o seu <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartucho de jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string>
190 <string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string> 257 <string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string>
191 <string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string> 258 <string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string>
@@ -193,25 +260,25 @@
193 <string name="loader_error_file_not_found">O ficheiro da ROM não existe</string> 260 <string name="loader_error_file_not_found">O ficheiro da ROM não existe</string>
194 261
195 <!-- Emulation Menu --> 262 <!-- Emulation Menu -->
196 <string name="emulation_exit">Sair da emulação</string> 263 <string name="emulation_exit">Parar emulação</string>
197 <string name="emulation_done">Feito</string> 264 <string name="emulation_done">Feito</string>
198 <string name="emulation_fps_counter">Contador de FPS</string> 265 <string name="emulation_fps_counter">Contador de FPS</string>
199 <string name="emulation_toggle_controls">Alterar Controlos</string> 266 <string name="emulation_toggle_controls">Alterar controles</string>
200 <string name="emulation_rel_stick_center">Centro do Analógico Relativo</string> 267 <string name="emulation_rel_stick_center">Centro Relativo de Analógico</string>
201 <string name="emulation_dpad_slide">Deslizar do DPad</string> 268 <string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
202 <string name="emulation_haptics">Hápticos </string> 269 <string name="emulation_haptics">Vibração ao tocar</string>
203 <string name="emulation_show_overlay">Mostrar sobreposição </string> 270 <string name="emulation_show_overlay">Mostrar overlay</string>
204 <string name="emulation_toggle_all">Alterar todos</string> 271 <string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
205 <string name="emulation_control_adjust">Ajustar a sobreposição </string> 272 <string name="emulation_control_adjust">Ajustar overlay</string>
206 <string name="emulation_control_scale">Escala</string> 273 <string name="emulation_control_scale">Escala</string>
207 <string name="emulation_control_opacity">Opacidade</string> 274 <string name="emulation_control_opacity">Opacidade</string>
208 <string name="emulation_touch_overlay_reset">Redefinir Sobreposição </string> 275 <string name="emulation_touch_overlay_reset">Restaurar overlay padrão</string>
209 <string name="emulation_touch_overlay_edit">Editar sobreposição </string> 276 <string name="emulation_touch_overlay_edit">Editar overlay</string>
210 <string name="emulation_pause">Pausa emulação</string> 277 <string name="emulation_pause">Pausar emulação</string>
211 <string name="emulation_unpause">Retomar emulação</string> 278 <string name="emulation_unpause">Retomar emulação</string>
212 <string name="emulation_input_overlay">Opções de sobreposição </string> 279 <string name="emulation_input_overlay">Opções de overlay</string>
213 280
214 <string name="load_settings">Configurações a carregar...</string> 281 <string name="load_settings">Carregando configurações...</string>
215 282
216 <!-- Software keyboard --> 283 <!-- Software keyboard -->
217 <string name="software_keyboard">Teclado de software</string> 284 <string name="software_keyboard">Teclado de software</string>
@@ -226,6 +293,9 @@
226 <string name="fatal_error">Erro fatal</string> 293 <string name="fatal_error">Erro fatal</string>
227 <string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string> 294 <string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string>
228 <string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string> 295 <string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string>
296 <string name="device_memory_inadequate">RAM do dispositivo: %1$s\nRecommended: %2$s</string>
297 <string name="memory_formatted">%1$s %2$s</string>
298 <string name="no_game_present">Nenhum jogo inicializável presente!</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">Japão</string> 301 <string name="region_japan">Japão</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">Coréia</string> 306 <string name="region_korea">Coréia</string>
237 <string name="region_taiwan">Taiwan</string> 307 <string name="region_taiwan">Taiwan</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">KB</string>
312 <string name="memory_megabyte">MB</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">TB</string>
315 <string name="memory_petabyte">PB</string>
316 <string name="memory_exabyte">EB</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulcano</string> 319 <string name="renderer_vulkan">Vulcano</string>
@@ -274,12 +351,17 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">Landscape</string>
356 <string name="screen_layout_portrait">Portrait</string>
357 <string name="screen_layout_auto">Automático</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">Padrão (16:9)</string> 360 <string name="ratio_default">Padrão (16:9)</string>
279 <string name="ratio_force_four_three">Forçar 4:3</string> 361 <string name="ratio_force_four_three">Forçar 4:3</string>
280 <string name="ratio_force_twenty_one_nine">Forçar 21:9</string> 362 <string name="ratio_force_twenty_one_nine">Forçar 21:9</string>
281 <string name="ratio_force_sixteen_ten">Forçar 16:10</string> 363 <string name="ratio_force_sixteen_ten">Forçar 16:10</string>
282 <string name="ratio_stretch">Esticar para a janela</string> 364 <string name="ratio_stretch">Esticar à janela</string>
283 365
284 <!-- CPU Accuracy --> 366 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Preciso</string> 367 <string name="cpu_accuracy_accurate">Preciso</string>
@@ -287,7 +369,7 @@
287 <string name="cpu_accuracy_paranoid">Paranoid (Lento)</string> 369 <string name="cpu_accuracy_paranoid">Paranoid (Lento)</string>
288 370
289 <!-- Gamepad Buttons --> 371 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">D-pad</string> 372 <string name="gamepad_d_pad">Botões Direcionais</string>
291 <string name="gamepad_left_stick">Analógico esquerdo</string> 373 <string name="gamepad_left_stick">Analógico esquerdo</string>
292 <string name="gamepad_right_stick">Analógico direito</string> 374 <string name="gamepad_right_stick">Analógico direito</string>
293 <string name="gamepad_home">Botão Home</string> 375 <string name="gamepad_home">Botão Home</string>
@@ -298,18 +380,32 @@
298 <string name="building_shaders">A criar shaders</string> 380 <string name="building_shaders">A criar shaders</string>
299 381
300 <!-- Theme options --> 382 <!-- Theme options -->
301 <string name="change_app_theme">Muda o Tema da App</string> 383 <string name="change_app_theme">Mudar o tema do aplicativo</string>
302 <string name="theme_default">Padrão</string> 384 <string name="theme_default">Padrão</string>
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
305 <!-- Theme Modes --> 387 <!-- Theme Modes -->
306 <string name="change_theme_mode">Altera o Modo do Tema</string> 388 <string name="change_theme_mode">Alterar o tema</string>
307 <string name="theme_mode_follow_system">Igual ao Sistema</string> 389 <string name="theme_mode_follow_system">Igual ao Sistema</string>
308 <string name="theme_mode_light">Claro</string> 390 <string name="theme_mode_light">Claro</string>
309 <string name="theme_mode_dark">Escuro</string> 391 <string name="theme_mode_dark">Escuro</string>
310 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
311 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Usa Fundos Negros</string> 397 <string name="use_black_backgrounds">Plano de fundo preto</string>
313 <string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string> 398 <string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string>
314 399
315</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">Picture in Picture</string>
402 <string name="picture_in_picture_description">Minimizar a janela quando colocada em segundo plano</string>
403 <string name="pause">Pausa</string>
404 <string name="play">Correr</string>
405 <string name="mute">Mudo</string>
406 <string name="unmute">Unmute</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">Licenças</string>
410 <string name="license_fidelityfx_fsr_description">Upscaling de alta qualidade da AMD</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml
index 0a1a47fbb..6afea9b03 100644
--- a/src/android/app/src/main/res/values-pt-rPT/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Este software corre jogos para a consola Nintendo Switch. Não estão incluídas nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começares, por favor localiza o ficheiro <![CDATA[1 prod.keys 1]]> no armazenamento do teu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Learn more2]]></string> 4 <string name="app_disclaimer">Este software corre jogos para a consola Nintendo Switch. Não estão incluídas nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começares, por favor localiza o ficheiro <![CDATA[1 prod.keys 1]]> no armazenamento do teu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Learn more2]]></string>
5 <string name="emulation_notification_channel_name">Emulação está Ativa</string> 5 <string name="emulation_notification_channel_name">Emulação está Ativa</string>
@@ -25,6 +25,7 @@
25 <string name="back">Voltar</string> 25 <string name="back">Voltar</string>
26 <string name="add_games">Adiciona Jogos</string> 26 <string name="add_games">Adiciona Jogos</string>
27 <string name="add_games_description">Seleciona a tua pasta de Jogos</string> 27 <string name="add_games_description">Seleciona a tua pasta de Jogos</string>
28 <string name="step_complete">Completo!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Jogos</string> 31 <string name="home_games">Jogos</string>
@@ -37,7 +38,8 @@
37 <string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string> 38 <string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string>
38 <string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string> 39 <string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Procurar Jogos</string> 41 <string name="home_search_games">Procurar jogos</string>
42 <string name="search_settings">Procurar nas definições</string>
41 <string name="games_dir_selected">Pasta de Jogos selecionada</string> 43 <string name="games_dir_selected">Pasta de Jogos selecionada</string>
42 <string name="install_prod_keys">Instala prod.keys</string> 44 <string name="install_prod_keys">Instala prod.keys</string>
43 <string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string> 45 <string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string>
@@ -61,15 +63,18 @@
61 <string name="invalid_keys_file">Ficheiro de chaves inválido</string> 63 <string name="invalid_keys_file">Ficheiro de chaves inválido</string>
62 <string name="install_keys_success">Chaves instaladas com sucesso</string> 64 <string name="install_keys_success">Chaves instaladas com sucesso</string>
63 <string name="reading_keys_failure">Erro ao ler chaves de encriptação</string> 65 <string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
66 <string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
67 <string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
64 <string name="invalid_keys_error">Chaves de encriptação inválidas</string> 68 <string name="invalid_keys_error">Chaves de encriptação inválidas</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string> 70 <string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
67 <string name="install_gpu_driver">Instala driver para GPU</string> 71 <string name="install_gpu_driver">Instala driver para GPU</string>
68 <string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string> 72 <string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
69 <string name="advanced_settings">Configurações avançadas</string> 73 <string name="advanced_settings">Configurações avançadas</string>
74 <string name="advanced_settings_game">Definições avançadas: %1$s</string>
70 <string name="settings_description">Configura configurações do emulador</string> 75 <string name="settings_description">Configura configurações do emulador</string>
71 <string name="search_recently_played">Jogos recentes</string> 76 <string name="search_recently_played">Jogado recentemente</string>
72 <string name="search_recently_added">Adicionados recentemente</string> 77 <string name="search_recently_added">Adicionado recentemente</string>
73 <string name="search_retail">Jogos comerciais</string> 78 <string name="search_retail">Jogos comerciais</string>
74 <string name="search_homebrew">Homebrew</string> 79 <string name="search_homebrew">Homebrew</string>
75 <string name="open_user_folder">Abre a pasta Yuzu</string> 80 <string name="open_user_folder">Abre a pasta Yuzu</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string> 91 <string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string>
87 <string name="import_saves">Importar</string> 92 <string name="import_saves">Importar</string>
88 <string name="export_saves">Exportar</string> 93 <string name="export_saves">Exportar</string>
94 <string name="install_firmware">Instalar firmware</string>
95 <string name="install_firmware_description">O firmware deve estar em um arquivo ZIP e é necessário para iniciar alguns jogos.</string>
96 <string name="firmware_installing">Instalando firmware</string>
97 <string name="firmware_installed_success">Firmware instalado com sucesso.</string>
98 <string name="firmware_installed_failure">Falha na instalação do firmware</string>
99 <string name="firmware_installed_failure_description">Cofirma que os ficheiros firmware nca estão no root do finheiro zip e tenta de novo.</string>
100 <string name="share_log">Compartilhe registros de debug.</string>
101 <string name="share_log_description">Compartilhe o arquivo de registro do yuzu para obter ajuda com problemas</string>
102 <string name="share_log_missing">Arquivo de registro não encontrado</string>
103 <string name="install_game_content">Instalar conteúdo adicional</string>
104 <string name="install_game_content_description">Instale atualizações de jogos ou DLC</string>
105 <string name="installing_game_content">A instalar conteúdo...</string>
106 <string name="install_game_content_failure">Erro ao instalar ficheiro(s) para NAND</string>
107 <string name="install_game_content_failure_description">Por favor confitma que o conteúdo(s) é válido e que as prod.keys estão instaladas.</string>
108 <string name="install_game_content_failure_base">A instalação de jogos base não é permitida para evitar possíveis conflitos.</string>
109 <string name="install_game_content_failure_file_extension">Sò conteúdos NSP e XCI são suportados. Por favor verifica que o conteúdo(s) do jogo são válidos.</string>
110 <string name="install_game_content_failed_count">%1$d erro(s) de instalação</string>
111 <string name="install_game_content_success">Conteúdo(s) de jogo instalados com sucesso</string>
112 <string name="install_game_content_success_install">%1$d instalado com sucesso</string>
113 <string name="install_game_content_success_overwrite">%1$d substituída com êxito</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">Drivers personalizados não suportados</string>
116 <string name="custom_driver_not_supported_description">Carrea«gamento de drivers personalizados não é suportado pr este dispositivo. \nCheck verifica esta opção de futuro para confirmar se o suporte foi adicionado!</string>
117 <string name="manage_yuzu_data">Administrar dados yuzu</string>
118 <string name="manage_yuzu_data_description">Importa/exporta firmware, chaves, dados do usuário e mais!</string>
119 <string name="share_save_file">Partilha ficheiro duardado</string>
120 <string name="export_save_failed">Erro ao exportar dados guardados</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia não é real</string> 123 <string name="gaia_is_not_real">Gaia não é real</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">Contribuidores</string> 126 <string name="contributors">Contribuidores</string>
95 <string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string> 127 <string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Projetos que tornam o yuzu para Android possível</string>
97 <string name="build">Versão</string> 130 <string name="build">Versão</string>
131 <string name="user_data">Dado de utilizados</string>
132 <string name="user_data_description">Importar/exportar todos dados da aplicação data.\n\n Ao importar dados do utilizados, todos os dados existentes do utilizados serão excluídos!</string>
133 <string name="exporting_user_data">A exportar dados de utilizados...</string>
134 <string name="importing_user_data">A importar dados de utilizador...</string>
135 <string name="import_user_data">Importar dados de utilizados...</string>
136 <string name="invalid_yuzu_backup">Backup yuzu inválido</string>
137 <string name="user_data_export_success">Dados de utilizados exportados com sucesso</string>
138 <string name="user_data_import_success">Dados de utilizador importado com sucesso</string>
139 <string name="user_data_export_cancelled">Exportação cancelada</string>
140 <string name="user_data_import_failed_description">Verifiqua se as pastas de dados do utilizados estão na raiz da pasta zip e contêm um arquivo de configuração em config/config.ini e tenta novamente.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
114 <string name="are_you_interested">Estás interessado?</string> 157 <string name="are_you_interested">Estás interessado?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">Ativar limite de velocidade</string> 160 <string name="frame_limit_enable">Limite de velocidade</string>
118 <string name="frame_limit_enable_description">Quando ativada, a velocidade da emulação será limitada à percentagem definida da velocidade normal.</string> 161 <string name="frame_limit_enable_description">Limita a velocidade da emulação a uma porcentagem específica da velocidade normal.</string>
119 <string name="frame_limit_slider">Percentagem do limite de velocidade</string> 162 <string name="frame_limit_slider">Percentagem do limite de velocidade</string>
120 <string name="frame_limit_slider_description">Especifica o limite da percentagem da velocidade da emulação. Com a velocidade por defeito a 100% a emulação será limitada à velocidade normal. Valores maiores ou menores aumentarão ou diminuirão o limite de velocidade.</string> 163 <string name="frame_limit_slider_description">Especifica a porcentagem para limitar a velocidade de emulação. 100% é o normal. Valores mais altos ou mais baixos irão aumentar ou diminuir o limite de velocidade.</string>
121 <string name="cpu_accuracy">Precisão do CPU</string> 164 <string name="cpu_accuracy">Precisão do CPU</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">Modo ancorado</string> 168 <string name="use_docked_mode">Modo Ancorado</string>
125 <string name="use_docked_mode_description">Emula em modo ancorado, que aumenta a resolução ás custas da performance.</string> 169 <string name="use_docked_mode_description">Aumenta a resolução, diminuindo o desempenho. O Modo Portátil é utilizado quando estiver desabilitado, diminuindo a resolução e melhorando o desempenho.</string>
126 <string name="emulated_region">Região da emulação</string> 170 <string name="emulated_region">Região da emulação</string>
127 <string name="emulated_language">Idioma da emulação</string> 171 <string name="emulated_language">Idioma da emulação</string>
128 <string name="select_rtc_date">Seleciona a data RTC</string> 172 <string name="select_rtc_date">Selecione a data do sistema</string>
129 <string name="select_rtc_time">Seleciona a hora RTC</string> 173 <string name="select_rtc_time">Selecione a hora do sistema</string>
130 <string name="use_custom_rtc">Ativa RTC personalizado</string> 174 <string name="use_custom_rtc">RTC personalizado</string>
131 <string name="use_custom_rtc_description">Esta configuração permite definir um RTC personalizado diferente da hora atual do sistema</string> 175 <string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
132 <string name="set_custom_rtc">Define RTC personalizado</string> 176 <string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Nível de precisão</string> 179 <string name="renderer_accuracy">Nível de precisão</string>
137 <string name="renderer_resolution">Resolução</string> 180 <string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
138 <string name="renderer_vsync">Modo VSync</string> 181 <string name="renderer_vsync">Modo VSync</string>
139 <string name="renderer_aspect_ratio">Proporção do ecrã</string> 182 <string name="renderer_screen_layout">Oriantação</string>
183 <string name="renderer_aspect_ratio">Proporção da tela</string>
140 <string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string> 184 <string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
141 <string name="renderer_anti_aliasing">Método de Anti-Aliasing </string> 185 <string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
142 <string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string> 186 <string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string>
143 <string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string> 187 <string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string>
144 <string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string> 188 <string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string>
145 <string name="renderer_asynchronous_shaders_description">Compila shaders assincronamente, que aumentará a fluidez, mas poderá causar falhas.</string> 189 <string name="renderer_asynchronous_shaders_description">Compila os shaders de forma assíncrona, reduzindo travamentos, mas pode apresentar problemas.</string>
190 <string name="renderer_reactive_flushing">Usar flushing reativo</string>
191 <string name="renderer_reactive_flushing_description">Melhora a precisão da renderização em alguns jogos ao custo de desempenho.</string>
192 <string name="use_disk_shader_cache">Cache de shaders em disco</string>
193 <string name="use_disk_shader_cache_description">Reduz travamentos ao armazenar e carregar localmente os shaders.</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">Depuração da CPU</string>
198 <string name="cpu_debug_mode_description">Coloca a CPU em um modo de depuração lento.</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
146 <string name="renderer_debug">Ativar depuração de gráficos</string> 201 <string name="renderer_debug">Ativar depuração de gráficos</string>
147 <string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string> 202 <string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string>
148 <string name="use_disk_shader_cache">Usar cache do disk shader</string> 203 <string name="fastmem">Fastmem</string>
149 <string name="use_disk_shader_cache_description">Aumenta a fluidez ao guardar e carregar shaders gerados para o armazenamento.</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">Motor de saída</string>
152 <string name="audio_volume">Volume</string> 207 <string name="audio_volume">Volume</string>
153 <string name="audio_volume_description">Especifica o volume de saída.</string> 208 <string name="audio_volume_description">Especifica o volume de saída.</string>
154 209
@@ -157,14 +212,24 @@
157 <string name="ini_saved">Configurações guardadas</string> 212 <string name="ini_saved">Configurações guardadas</string>
158 <string name="gameid_saved">Configurações guardadas para %1$s</string> 213 <string name="gameid_saved">Configurações guardadas para %1$s</string>
159 <string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string> 214 <string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string>
215 <string name="unimplemented_menu">Menu não implementado</string>
160 <string name="loading">A carregar...</string> 216 <string name="loading">A carregar...</string>
217 <string name="shutting_down">A desligar...</string>
161 <string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string> 218 <string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string>
162 <string name="reset_to_default">Reverter para padrão</string> 219 <string name="reset_to_default">Reverter para padrão</string>
163 <string name="reset_all_settings">Redefinir todas as configurações?</string> 220 <string name="reset_all_settings">Redefinir todas as configurações?</string>
164 <string name="reset_all_settings_description">Todas as configurações avançadas serão redefinidas para as definições padrão. Isto não pode ser revertido.</string> 221 <string name="reset_all_settings_description">Todas as configurações avançadas retornarão ao padrão. Isto não pode ser desfeito.</string>
165 <string name="settings_reset">Redefinir configurações </string> 222 <string name="settings_reset">Redefinir configurações </string>
166 <string name="close">Fechar</string> 223 <string name="close">Fechar</string>
167 <string name="learn_more">Saber Mais</string> 224 <string name="learn_more">Saber mais</string>
225 <string name="auto">Automático</string>
226 <string name="submit">Enviar</string>
227 <string name="string_null">Nenhum (desativado)</string>
228 <string name="string_import">Importar</string>
229 <string name="export">Exportar</string>
230 <string name="export_failed">Exportação falhada</string>
231 <string name="import_failed">IMportação falhada</string>
232 <string name="cancelling">A cancelar</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Seleciona a driver para o GPU</string> 235 <string name="select_gpu_driver">Seleciona a driver para o GPU</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">Instalar</string> 237 <string name="select_gpu_driver_install">Instalar</string>
173 <string name="select_gpu_driver_default">Padrão</string> 238 <string name="select_gpu_driver_default">Padrão</string>
174 <string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string> 239 <string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string>
240 <string name="select_gpu_driver_error">Driver selecionado inválido, a usar o padrão do sistema!</string>
175 <string name="system_gpu_driver">Driver do GPU padrão</string> 241 <string name="system_gpu_driver">Driver do GPU padrão</string>
176 <string name="installing_driver">A instalar o Driver...</string> 242 <string name="installing_driver">A instalar o Driver...</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">Gráficos</string> 248 <string name="preferences_graphics">Gráficos</string>
183 <string name="preferences_audio">Audio</string> 249 <string name="preferences_audio">Audio</string>
184 <string name="preferences_theme">Cor e tema.</string> 250 <string name="preferences_theme">Cor e tema.</string>
251 <string name="preferences_debug">Depurar</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">A tua ROM está encriptada</string> 254 <string name="loader_error_encrypted">A tua ROM está encriptada</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor segue os guias para fazer redump das tuas<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">Cartidges de Jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">Jogos Instalados</a>.]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga os guias para despejar novamente o seu <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartucho de jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string>
190 <string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string> 257 <string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string>
191 <string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string> 258 <string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string>
@@ -193,28 +260,28 @@
193 <string name="loader_error_file_not_found">O ficheiro da ROM não existe</string> 260 <string name="loader_error_file_not_found">O ficheiro da ROM não existe</string>
194 261
195 <!-- Emulation Menu --> 262 <!-- Emulation Menu -->
196 <string name="emulation_exit">Sair da emulação</string> 263 <string name="emulation_exit">Parar emulação</string>
197 <string name="emulation_done">Feito</string> 264 <string name="emulation_done">Feito</string>
198 <string name="emulation_fps_counter">Contador de FPS</string> 265 <string name="emulation_fps_counter">Contador de FPS</string>
199 <string name="emulation_toggle_controls">Alterar Controlos</string> 266 <string name="emulation_toggle_controls">Alterar controles</string>
200 <string name="emulation_rel_stick_center">Centro do Analógico Relativo</string> 267 <string name="emulation_rel_stick_center">Centro Relativo de Analógico</string>
201 <string name="emulation_dpad_slide">Deslizar do DPad</string> 268 <string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
202 <string name="emulation_haptics">Hápticos </string> 269 <string name="emulation_haptics">Vibração ao tocar</string>
203 <string name="emulation_show_overlay">Mostrar sobreposição </string> 270 <string name="emulation_show_overlay">Mostrar overlay</string>
204 <string name="emulation_toggle_all">Alterar todos</string> 271 <string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
205 <string name="emulation_control_adjust">Ajustar a sobreposição </string> 272 <string name="emulation_control_adjust">Ajustar overlay</string>
206 <string name="emulation_control_scale">Escala</string> 273 <string name="emulation_control_scale">Escala</string>
207 <string name="emulation_control_opacity">Opacidade</string> 274 <string name="emulation_control_opacity">Opacidade</string>
208 <string name="emulation_touch_overlay_reset">Redefinir Sobreposição </string> 275 <string name="emulation_touch_overlay_reset">Restaurar overlay padrão</string>
209 <string name="emulation_touch_overlay_edit">Editar sobreposição </string> 276 <string name="emulation_touch_overlay_edit">Editar overlay</string>
210 <string name="emulation_pause">Pausa emulação</string> 277 <string name="emulation_pause">Pausar emulação</string>
211 <string name="emulation_unpause">Retomar emulação</string> 278 <string name="emulation_unpause">Despausar emulação</string>
212 <string name="emulation_input_overlay">Opções de sobreposição </string> 279 <string name="emulation_input_overlay">Opções de overlay</string>
213 280
214 <string name="load_settings">Configurações a carregar...</string> 281 <string name="load_settings">Carregando configurações...</string>
215 282
216 <!-- Software keyboard --> 283 <!-- Software keyboard -->
217 <string name="software_keyboard">Teclado de Software</string> 284 <string name="software_keyboard">Teclado de software</string>
218 285
219 <!-- Errors and warnings --> 286 <!-- Errors and warnings -->
220 <string name="abort_button">Abortar</string> 287 <string name="abort_button">Abortar</string>
@@ -226,6 +293,9 @@
226 <string name="fatal_error">Erro fatal</string> 293 <string name="fatal_error">Erro fatal</string>
227 <string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string> 294 <string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string>
228 <string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string> 295 <string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string>
296 <string name="device_memory_inadequate">RAM do dispositivo: %1$s\nRecommended: %2$s</string>
297 <string name="memory_formatted">%1$s %2$s</string>
298 <string name="no_game_present">Nenhum jogo inicializável presente!</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">Japão</string> 301 <string name="region_japan">Japão</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">Coreia</string> 306 <string name="region_korea">Coreia</string>
237 <string name="region_taiwan">Taiwan</string> 307 <string name="region_taiwan">Taiwan</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">KB</string>
312 <string name="memory_megabyte">MB</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">TB</string>
315 <string name="memory_petabyte">PB</string>
316 <string name="memory_exabyte">EB</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulcano</string> 319 <string name="renderer_vulkan">Vulcano</string>
@@ -274,12 +351,17 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">Landscape</string>
356 <string name="screen_layout_portrait">Portrait</string>
357 <string name="screen_layout_auto">Automático</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">Padrão (16:9)</string> 360 <string name="ratio_default">Padrão (16:9)</string>
279 <string name="ratio_force_four_three">Forçar 4:3</string> 361 <string name="ratio_force_four_three">Forçar 4:3</string>
280 <string name="ratio_force_twenty_one_nine">Forçar 21:9</string> 362 <string name="ratio_force_twenty_one_nine">Forçar 21:9</string>
281 <string name="ratio_force_sixteen_ten">Forçar 16:10</string> 363 <string name="ratio_force_sixteen_ten">Forçar 16:10</string>
282 <string name="ratio_stretch">Esticar à Janela</string> 364 <string name="ratio_stretch">Esticar à janela</string>
283 365
284 <!-- CPU Accuracy --> 366 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Preciso</string> 367 <string name="cpu_accuracy_accurate">Preciso</string>
@@ -287,9 +369,9 @@
287 <string name="cpu_accuracy_paranoid">Paranoid (Lento)</string> 369 <string name="cpu_accuracy_paranoid">Paranoid (Lento)</string>
288 370
289 <!-- Gamepad Buttons --> 371 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">D-Pad</string> 372 <string name="gamepad_d_pad">Botões Direcionais</string>
291 <string name="gamepad_left_stick">Analógico Esquerdo</string> 373 <string name="gamepad_left_stick">Analógico esquerdo</string>
292 <string name="gamepad_right_stick">Analógico Direito</string> 374 <string name="gamepad_right_stick">Analógico direito</string>
293 <string name="gamepad_home">Home</string> 375 <string name="gamepad_home">Home</string>
294 <string name="gamepad_screenshot">Captura de ecrã</string> 376 <string name="gamepad_screenshot">Captura de ecrã</string>
295 377
@@ -298,18 +380,32 @@
298 <string name="building_shaders">A criar shaders</string> 380 <string name="building_shaders">A criar shaders</string>
299 381
300 <!-- Theme options --> 382 <!-- Theme options -->
301 <string name="change_app_theme">Muda o Tema da App</string> 383 <string name="change_app_theme">Mudar o tema do aplicativo</string>
302 <string name="theme_default">Padrão</string> 384 <string name="theme_default">Padrão</string>
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
305 <!-- Theme Modes --> 387 <!-- Theme Modes -->
306 <string name="change_theme_mode">Altera o Modo do Tema</string> 388 <string name="change_theme_mode">Alterar o tema</string>
307 <string name="theme_mode_follow_system">Igual ao Sistema</string> 389 <string name="theme_mode_follow_system">Igual ao Sistema</string>
308 <string name="theme_mode_light">Claro</string> 390 <string name="theme_mode_light">Claro</string>
309 <string name="theme_mode_dark">Escuro</string> 391 <string name="theme_mode_dark">Escuro</string>
310 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
311 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">Usa Fundos Escuros</string> 397 <string name="use_black_backgrounds">Plano de fundo preto</string>
313 <string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string> 398 <string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string>
314 399
315</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">Picture in Picture</string>
402 <string name="picture_in_picture_description">Minimizar a janela quando colocada em segundo plano</string>
403 <string name="pause">Pausa</string>
404 <string name="play">Correr</string>
405 <string name="mute">Mute</string>
406 <string name="unmute">Unmute</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">Licenças</string>
410 <string name="license_fidelityfx_fsr_description">Upscaling de alta qualidade da AMD</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml
index 0bef035d6..c614257a8 100644
--- a/src/android/app/src/main/res/values-ru/strings.xml
+++ b/src/android/app/src/main/res/values-ru/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Это программное обеÑпечение позволÑет запуÑкать игры Ð´Ð»Ñ Ð¸Ð³Ñ€Ð¾Ð²Ð¾Ð¹ конÑоли Nintendo Switch. Мы не предоÑтавлÑем Ñами игры или ключи.&lt;br /&gt;&lt;br /&gt;Перед началом работы найдите файл <![CDATA[<b> prod.keys </b>]]> в хранилище уÑтройÑтва..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Узнать больше</a>]]></string> 4 <string name="app_disclaimer">Это программное обеÑпечение позволÑет запуÑкать игры Ð´Ð»Ñ Ð¸Ð³Ñ€Ð¾Ð²Ð¾Ð¹ конÑоли Nintendo Switch. Мы не предоÑтавлÑем Ñами игры или ключи.&lt;br /&gt;&lt;br /&gt;Перед началом работы найдите файл <![CDATA[<b> prod.keys </b>]]> в хранилище уÑтройÑтва..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Узнать больше</a>]]></string>
5 <string name="emulation_notification_channel_name">ЭмулÑÑ†Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°</string> 5 <string name="emulation_notification_channel_name">ЭмулÑÑ†Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°</string>
@@ -7,7 +7,7 @@
7 <string name="emulation_notification_running">yuzu запущен</string> 7 <string name="emulation_notification_running">yuzu запущен</string>
8 <string name="notice_notification_channel_name">Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¸ ошибки</string> 8 <string name="notice_notification_channel_name">Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¸ ошибки</string>
9 <string name="notice_notification_channel_description">Показывать уведомлениÑ, когда что-то пошло не так</string> 9 <string name="notice_notification_channel_description">Показывать уведомлениÑ, когда что-то пошло не так</string>
10 <string name="notification_permission_not_granted">Ð’Ñ‹ не предоÑтавили разрешение уведомлений!</string> 10 <string name="notification_permission_not_granted">Ð’Ñ‹ не предоÑтавили разрешение на уведомлениÑ!</string>
11 11
12 <!-- Setup strings --> 12 <!-- Setup strings -->
13 <string name="welcome">Добро пожаловать!</string> 13 <string name="welcome">Добро пожаловать!</string>
@@ -25,6 +25,7 @@
25 <string name="back">Ðазад</string> 25 <string name="back">Ðазад</string>
26 <string name="add_games">Добавить игры</string> 26 <string name="add_games">Добавить игры</string>
27 <string name="add_games_description">Выберите папку Ñ Ð¸Ð³Ñ€Ð°Ð¼Ð¸</string> 27 <string name="add_games_description">Выберите папку Ñ Ð¸Ð³Ñ€Ð°Ð¼Ð¸</string>
28 <string name="step_complete">Выполнено!</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">Игры</string> 31 <string name="home_games">Игры</string>
@@ -38,6 +39,7 @@
38 <string name="add_games_warning_description">Игры не будут отображатьÑÑ Ð² ÑпиÑке Игры, еÑли папка не выбрана.</string> 39 <string name="add_games_warning_description">Игры не будут отображатьÑÑ Ð² ÑпиÑке Игры, еÑли папка не выбрана.</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">Ðайти игры</string> 41 <string name="home_search_games">Ðайти игры</string>
42 <string name="search_settings">ÐаÑтройки поиÑка</string>
41 <string name="games_dir_selected">Выбрана папка Ñ Ð¸Ð³Ñ€Ð°Ð¼Ð¸</string> 43 <string name="games_dir_selected">Выбрана папка Ñ Ð¸Ð³Ñ€Ð°Ð¼Ð¸</string>
42 <string name="install_prod_keys">УÑтановить prod.keys</string> 44 <string name="install_prod_keys">УÑтановить prod.keys</string>
43 <string name="install_prod_keys_description">ТребуетÑÑ Ð´Ð»Ñ Ñ€Ð°Ñшифровки розничных игр</string> 45 <string name="install_prod_keys_description">ТребуетÑÑ Ð´Ð»Ñ Ñ€Ð°Ñшифровки розничных игр</string>
@@ -61,14 +63,17 @@
61 <string name="invalid_keys_file">Выбран неверный файл ключей</string> 63 <string name="invalid_keys_file">Выбран неверный файл ключей</string>
62 <string name="install_keys_success">Ключи уÑпешно уÑтановлены</string> 64 <string name="install_keys_success">Ключи уÑпешно уÑтановлены</string>
63 <string name="reading_keys_failure">Ошибка при чтении ключей шифрованиÑ</string> 65 <string name="reading_keys_failure">Ошибка при чтении ключей шифрованиÑ</string>
66 <string name="install_prod_keys_failure_extension_description">УбедитеÑÑŒ, что файл ключей имеет раÑширение .keys, и повторите попытку.</string>
67 <string name="install_amiibo_keys_failure_extension_description">УбедитеÑÑŒ, что файл ключей имеет раÑширение .bin, и повторите попытку.</string>
64 <string name="invalid_keys_error">Ðеверные ключи шифрованиÑ</string> 68 <string name="invalid_keys_error">Ðеверные ключи шифрованиÑ</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Выбранный файл неверен или поврежден. ПожалуйÑта, пере-дампите ваши ключи.</string> 70 <string name="install_keys_failure_description">Выбранный файл неверен или поврежден. ПожалуйÑта, пере-дампите ваши ключи.</string>
67 <string name="install_gpu_driver">УÑтановить драйвер ГП</string> 71 <string name="install_gpu_driver">УÑтановить драйвер ГП</string>
68 <string name="install_gpu_driver_description">УÑтановите альтернативные драйверы Ð´Ð»Ñ Ð¿Ð¾Ñ‚ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾ лучшей производительноÑти и/или точноÑти</string> 72 <string name="install_gpu_driver_description">УÑтановите альтернативные драйверы Ð´Ð»Ñ Ð¿Ð¾Ñ‚ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾ лучшей производительноÑти и/или точноÑти</string>
69 <string name="advanced_settings">РаÑширенные наÑтройки</string> 73 <string name="advanced_settings">РаÑширенные наÑтройки</string>
74 <string name="advanced_settings_game">РаÑширенные наÑтройки: %1$s</string>
70 <string name="settings_description">ÐаÑтройка параметров ÑмулÑтора</string> 75 <string name="settings_description">ÐаÑтройка параметров ÑмулÑтора</string>
71 <string name="search_recently_played">Ðедавно Ñыграно</string> 76 <string name="search_recently_played">Ðедавно Ñыгранные</string>
72 <string name="search_recently_added">Ðедавно добавлено</string> 77 <string name="search_recently_added">Ðедавно добавлено</string>
73 <string name="search_retail">Розничные</string> 78 <string name="search_retail">Розничные</string>
74 <string name="search_homebrew">Homebrew</string> 79 <string name="search_homebrew">Homebrew</string>
@@ -86,6 +91,34 @@
86 <string name="save_file_invalid_zip_structure_description">Ðазвание первой вложенной папки должно быть идентификатором игры.</string> 91 <string name="save_file_invalid_zip_structure_description">Ðазвание первой вложенной папки должно быть идентификатором игры.</string>
87 <string name="import_saves">Импорт</string> 92 <string name="import_saves">Импорт</string>
88 <string name="export_saves">ЭкÑпорт</string> 93 <string name="export_saves">ЭкÑпорт</string>
94 <string name="install_firmware">УÑтановить прошивку</string>
95 <string name="install_firmware_description">Прошивка должна находитьÑÑ Ð² ZIP-архиве и необходима Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ некоторых игр</string>
96 <string name="firmware_installing">УÑтановка прошивки</string>
97 <string name="firmware_installed_success">Прошивка уÑпешно уÑтановлена</string>
98 <string name="firmware_installed_failure">Ðе удалоÑÑŒ уÑтановить прошивку</string>
99 <string name="firmware_installed_failure_description">УбедитеÑÑŒ что файлы прошивки nca находÑÑ‚ÑÑ Ð² корне zip-архива и повторите попытку.</string>
100 <string name="share_log">ПоделитьÑÑ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð¾Ð¼ отладки</string>
101 <string name="share_log_description">ПоделитьÑÑ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð¾Ð¼ отладки yuzu Ð´Ð»Ñ ÑƒÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼</string>
102 <string name="share_log_missing">Файл журнала не найден</string>
103 <string name="install_game_content">УÑтановить игровой контент</string>
104 <string name="install_game_content_description">УÑтановить Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð³Ñ€Ñ‹ или дополнений</string>
105 <string name="installing_game_content">УÑтановка контента...</string>
106 <string name="install_game_content_failure">Ошибка уÑтановки файл(ов) в NAND.</string>
107 <string name="install_game_content_failure_description">УбедитеÑÑŒ что Ñодержимое допуÑтимо и что файл prod.keys уÑтановлен.</string>
108 <string name="install_game_content_failure_base">УÑтановка базовых игр запрещена во избежание возможных конфликтов.</string>
109 <string name="install_game_content_failure_file_extension">ПоддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ контент NSP и XCI. ПожалуйÑта убедитеÑÑŒ что игровой контент дейÑтвителен.</string>
110 <string name="install_game_content_failed_count">%1$d ошибка уÑтановки</string>
111 <string name="install_game_content_success">Игровой контент уÑпешно уÑтановлен</string>
112 <string name="install_game_content_success_install">%1$d УÑпешно уÑтановлено</string>
113 <string name="install_game_content_success_overwrite">%1$d УÑпешно перезапиÑано</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">ПользовательÑкие драйверы не поддерживаютÑÑ</string>
116 <string name="custom_driver_not_supported_description">Загрузка пользовательÑкого драйвера в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½Ðµ поддерживаетÑÑ Ð´Ð»Ñ Ñтого уÑтройÑтва.\nПроверьте Ñтот параметр еще раз в будущем чтобы узнать была ли добавлена ​​поддержка!
117 </string>
118 <string name="manage_yuzu_data">Управление данными yuzu</string>
119 <string name="manage_yuzu_data_description">Импортируйте/ÑкÑпортируйте прошивку, ключи, пользовательÑкие данные и многое другое!</string>
120 <string name="share_save_file">ПоделитьÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ ÑохранениÑ</string>
121 <string name="export_save_failed">Ðе удалоÑÑŒ ÑкÑпортировать Ñохранение</string>
89 122
90 <!-- About screen strings --> 123 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia не ÑущеÑтвует</string> 124 <string name="gaia_is_not_real">Gaia не ÑущеÑтвует</string>
@@ -94,7 +127,18 @@
94 <string name="contributors">Контрибьюторы</string> 127 <string name="contributors">Контрибьюторы</string>
95 <string name="contributors_description">Сделано Ñ \u2764 от команды yuzu</string> 128 <string name="contributors_description">Сделано Ñ \u2764 от команды yuzu</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 129 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
130 <string name="licenses_description">Проекты, которые Ñделали yuzu Ð´Ð»Ñ Android возможным</string>
97 <string name="build">Сборка</string> 131 <string name="build">Сборка</string>
132 <string name="user_data">Данные пользователÑ</string>
133 <string name="user_data_description">Импортируйте/ÑкÑпортируйте вÑе данные приложениÑ.\n\nПри импорте пользовательÑких данных вÑе ÑущеÑтвующие пользовательÑкие данные будут удалены!</string>
134 <string name="exporting_user_data">ЭкÑпорт пользовательÑких данных…</string>
135 <string name="importing_user_data">Импорт пользовательÑких данных…</string>
136 <string name="import_user_data">Импортировать пользовательÑкие данные</string>
137 <string name="invalid_yuzu_backup">ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ yuzu</string>
138 <string name="user_data_export_success">ПользовательÑкие данные уÑпешно ÑкÑпортированы</string>
139 <string name="user_data_import_success">ПользовательÑкие данные уÑпешно импортированы</string>
140 <string name="user_data_export_cancelled">ЭкÑпорт отменен</string>
141 <string name="user_data_import_failed_description">УбедитеÑÑŒ что папки пользовательÑких данных находÑÑ‚ÑÑ Ð² корне zip-папки и Ñодержат файл конфигурации config/config.ini и повторите попытку.</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 142 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 143 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 144 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +158,51 @@
114 <string name="are_you_interested">Ð’Ñ‹ заинтереÑованы?</string> 158 <string name="are_you_interested">Ð’Ñ‹ заинтереÑованы?</string>
115 159
116 <!-- General settings strings --> 160 <!-- General settings strings -->
117 <string name="frame_limit_enable">Ðключить ограничение ÑкороÑти</string> 161 <string name="frame_limit_enable">Ограничить ÑкороÑть</string>
118 <string name="frame_limit_enable_description">ЕÑли Ñта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°, ÑкороÑть ÑмулÑции будет ограничена указанным процентом от нормальной ÑкороÑти.</string> 162 <string name="frame_limit_enable_description">Ограничивает ÑкороÑть ÑмулÑции указанным процентом от нормальной ÑкороÑти.</string>
119 <string name="frame_limit_slider">Ограничение процента cкороÑти</string> 163 <string name="frame_limit_slider">Ограничение процента cкороÑти</string>
120 <string name="frame_limit_slider_description">Указывает процент Ð´Ð»Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти ÑмулÑции. При значении по умолчанию 100% ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ ограничена нормальной ÑкороÑтью. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹ÑˆÐµ или ниже будут увеличивать или уменьшать ограничение ÑкороÑти.</string> 164 <string name="frame_limit_slider_description">Указывает процент Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти ÑмулÑции. 100% - Ñто Ð½Ð¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑкороÑть. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐµ или меньше увеличивают или уменьшают ограничение ÑкороÑти.</string>
121 <string name="cpu_accuracy">ТочноÑть ЦП</string> 165 <string name="cpu_accuracy">ТочноÑть ЦП</string>
166 <string name="value_with_units">%1$s%2$s</string>
122 167
123 <!-- System settings strings --> 168 <!-- System settings strings -->
124 <string name="use_docked_mode">Режим док-Ñтанции</string> 169 <string name="use_docked_mode">Режим док-Ñтанции</string>
125 <string name="use_docked_mode_description">ЭмулÑÑ†Ð¸Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° док-Ñтанции, что увеличивает разрешение за Ñчет ÑÐ½Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти.</string> 170 <string name="use_docked_mode_description">Увеличивает разрешение, ÑÐ½Ð¸Ð¶Ð°Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñть. Портативный режим иÑпользуетÑÑ Ð¿Ñ€Ð¸ отключении, ÑÐ½Ð¸Ð¶Ð°Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ и Ð¿Ð¾Ð²Ñ‹ÑˆÐ°Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñть.</string>
126 <string name="emulated_region">Эмулируемый регион</string> 171 <string name="emulated_region">Регион конÑоли</string>
127 <string name="emulated_language">ЭмулируемÑй Ñзык</string> 172 <string name="emulated_language">ЯзÑк конÑоли</string>
128 <string name="select_rtc_date">Выберите дату RTC</string> 173 <string name="select_rtc_date">Выберите дату RTC</string>
129 <string name="select_rtc_time">Выберите Ð²Ñ€ÐµÐ¼Ñ RTC</string> 174 <string name="select_rtc_time">Выберите Ð²Ñ€ÐµÐ¼Ñ RTC</string>
130 <string name="use_custom_rtc">Ðключить пользовательÑкий RTC</string> 175 <string name="use_custom_rtc">ПользовательÑкий RTC</string>
131 <string name="use_custom_rtc_description">Этот параметр позволÑет уÑтановить пользовательÑкие чаÑÑ‹ реального времени отдельно от текущего ÑиÑтемного времени</string> 176 <string name="use_custom_rtc_description">ПозволÑет уÑтановить пользовательÑкие чаÑÑ‹ реального времени отдельно от текущего ÑиÑтемного времени.</string>
132 <string name="set_custom_rtc">УÑтановить пользовательÑкий RTC</string> 177 <string name="set_custom_rtc">УÑтановить пользовательÑкий RTC</string>
133 178
134 <!-- Graphics settings strings --> 179 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Уровень точноÑти</string> 180 <string name="renderer_accuracy">Уровень точноÑти</string>
137 <string name="renderer_resolution">Разрешение</string> 181 <string name="renderer_resolution">Разрешение (портативное/в док-Ñтанции)</string>
138 <string name="renderer_vsync">Режим верт. Ñинхронизации</string> 182 <string name="renderer_vsync">Режим верт. Ñинхронизации</string>
183 <string name="renderer_screen_layout">ОриентациÑ</string>
139 <string name="renderer_aspect_ratio">Соотношение Ñторон</string> 184 <string name="renderer_aspect_ratio">Соотношение Ñторон</string>
140 <string name="renderer_scaling_filter">Фильтр адаптации окна</string> 185 <string name="renderer_scaling_filter">Фильтр адаптации окна</string>
141 <string name="renderer_anti_aliasing">Метод ÑглаживаниÑ</string> 186 <string name="renderer_anti_aliasing">Метод ÑглаживаниÑ</string>
142 <string name="renderer_force_max_clock">Принудительно заÑтавить макÑимальную тактовую чаÑтоту (только Ð´Ð»Ñ Adreno)</string> 187 <string name="renderer_force_max_clock">Принудительно заÑтавить макÑимальную тактовую чаÑтоту (только Ð´Ð»Ñ Adreno)</string>
143 <string name="renderer_force_max_clock_description">ЗаÑтавлÑет ГП работать на макÑимально возможных тактовых чаÑтотах (тепловые Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñе равно будут применÑтьÑÑ).</string> 188 <string name="renderer_force_max_clock_description">ЗаÑтавлÑет ГП работать на макÑимально возможных тактовых чаÑтотах (тепловые Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñе равно будут применÑтьÑÑ).</string>
144 <string name="renderer_asynchronous_shaders">ИÑпользовать аÑинхронные шейдеры</string> 189 <string name="renderer_asynchronous_shaders">ИÑпользовать аÑинхронные шейдеры</string>
145 <string name="renderer_asynchronous_shaders_description">Компилирует шейдеры аÑинхронно, что уменьшает завиÑаниÑ, но может взамен предоÑтавить визуальные баги.</string> 190 <string name="renderer_asynchronous_shaders_description">КомпилÑÑ†Ð¸Ñ ÑˆÐµÐ¹Ð´ÐµÑ€Ð¾Ð² проиÑходит аÑинхронно, что уменьшает завиÑаниÑ, но может привеÑти к поÑвлению багов.</string>
146 <string name="renderer_debug">Включить отладку графики</string> 191 <string name="renderer_reactive_flushing">Ð ÐµÐ°ÐºÑ‚Ð¸Ð²Ð½Ð°Ñ Ð¾Ñ‡Ð¸Ñтка</string>
147 <string name="renderer_debug_description">ЕÑли включено, графичеÑкий API переходит в более медленный режим отладки</string> 192 <string name="renderer_reactive_flushing_description">Повышение точноÑти рендеринга в некоторых играх за Ñчет ÑÐ½Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти.</string>
148 <string name="use_disk_shader_cache">ИÑпользовать кÑш шейдеров на диÑке</string> 193 <string name="use_disk_shader_cache">КÑш шейдеров на диÑке</string>
149 <string name="use_disk_shader_cache_description">Уменьшение завиÑаний за Ñчет Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ загрузки Ñгенерированных шейдеров на хранилище.</string> 194 <string name="use_disk_shader_cache_description">Уменьшение завиÑаний за Ñчет Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ загрузки Ñгенерированных шейдеров.</string>
195
196 <!-- Debug settings strings -->
197 <string name="cpu">ЦП</string>
198 <string name="cpu_debug_mode">Отладка ЦП</string>
199 <string name="cpu_debug_mode_description">Переводит ЦП в режим медленной отладки.</string>
200 <string name="gpu">графичеÑкий процеÑÑор</string>
201 <string name="renderer_api">API</string>
202 <string name="renderer_debug">Отладка графики</string>
203 <string name="renderer_debug_description">Переводит графичеÑкий API в режим медленной отладки.</string>
204 <string name="fastmem">Fastmem</string>
150 205
151 <!-- Audio settings strings -->
152 <string name="audio_volume">ГромкоÑть</string> 206 <string name="audio_volume">ГромкоÑть</string>
153 <string name="audio_volume_description">Задает громкоÑть аудиовыхода.</string> 207 <string name="audio_volume_description">Задает громкоÑть аудиовыхода.</string>
154 208
@@ -157,7 +211,9 @@
157 <string name="ini_saved">Сохраненные наÑтройки</string> 211 <string name="ini_saved">Сохраненные наÑтройки</string>
158 <string name="gameid_saved">ÐаÑтройки Ñохранены Ð´Ð»Ñ %1$s</string> 212 <string name="gameid_saved">ÐаÑтройки Ñохранены Ð´Ð»Ñ %1$s</string>
159 <string name="error_saving">Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ %1$s.ini: %2$s</string> 213 <string name="error_saving">Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ %1$s.ini: %2$s</string>
214 <string name="unimplemented_menu">Ðереализованное меню</string>
160 <string name="loading">Загрузка...</string> 215 <string name="loading">Загрузка...</string>
216 <string name="shutting_down">Выключение…</string>
161 <string name="reset_setting_confirmation">Хотите ли вы вернуть Ñтот параметр к значению по умолчанию?</string> 217 <string name="reset_setting_confirmation">Хотите ли вы вернуть Ñтот параметр к значению по умолчанию?</string>
162 <string name="reset_to_default">Ð¡Ð±Ñ€Ð¾Ñ Ðº наÑтройкам по умолчанию</string> 218 <string name="reset_to_default">Ð¡Ð±Ñ€Ð¾Ñ Ðº наÑтройкам по умолчанию</string>
163 <string name="reset_all_settings">СброÑить вÑе наÑтройки?</string> 219 <string name="reset_all_settings">СброÑить вÑе наÑтройки?</string>
@@ -165,6 +221,14 @@
165 <string name="settings_reset">ÐаÑтройки Ñброшены</string> 221 <string name="settings_reset">ÐаÑтройки Ñброшены</string>
166 <string name="close">Закрыть</string> 222 <string name="close">Закрыть</string>
167 <string name="learn_more">Узнать больше</string> 223 <string name="learn_more">Узнать больше</string>
224 <string name="auto">Ðвто</string>
225 <string name="submit">Отправить</string>
226 <string name="string_null">Null</string>
227 <string name="string_import">Импорт</string>
228 <string name="export">ЭкÑпорт</string>
229 <string name="export_failed">Ошибка ÑкÑпорта</string>
230 <string name="import_failed">Ошибка импортированиÑ</string>
231 <string name="cancelling">ОтменÑÑŽ</string>
168 232
169 <!-- GPU driver installation --> 233 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Выбрать драйвер ГП</string> 234 <string name="select_gpu_driver">Выбрать драйвер ГП</string>
@@ -172,6 +236,7 @@
172 <string name="select_gpu_driver_install">УÑтановить</string> 236 <string name="select_gpu_driver_install">УÑтановить</string>
173 <string name="select_gpu_driver_default">По умолчанию</string> 237 <string name="select_gpu_driver_default">По умолчанию</string>
174 <string name="select_gpu_driver_use_default">ИÑпользуетÑÑ Ñтандартный драйвер ГП </string> 238 <string name="select_gpu_driver_use_default">ИÑпользуетÑÑ Ñтандартный драйвер ГП </string>
239 <string name="select_gpu_driver_error">Выбран неверный драйвер, иÑпользуетÑÑ Ñтандартный ÑиÑтемный!</string>
175 <string name="system_gpu_driver">СиÑтемный драйвер ГП</string> 240 <string name="system_gpu_driver">СиÑтемный драйвер ГП</string>
176 <string name="installing_driver">УÑтановка драйвера...</string> 241 <string name="installing_driver">УÑтановка драйвера...</string>
177 242
@@ -182,10 +247,11 @@
182 <string name="preferences_graphics">Графика</string> 247 <string name="preferences_graphics">Графика</string>
183 <string name="preferences_audio">Ðудио</string> 248 <string name="preferences_audio">Ðудио</string>
184 <string name="preferences_theme">Тема и цвет</string> 249 <string name="preferences_theme">Тема и цвет</string>
250 <string name="preferences_debug">Отладка</string>
185 251
186 <!-- ROM loading errors --> 252 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">Ваш ROM зашифрованный</string> 253 <string name="loader_error_encrypted">Ваш ROM зашифрованный</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[ПожалуйÑта, Ñледуйте инÑтрукциÑм, чтобы пере-дампить ваши <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">игровые картриджи</a> или <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">уÑтановленные игры</a>.]]></string> 254 <string name="loader_error_encrypted_roms_description"><![CDATA[Следуйте инÑтрукциÑм, чтобы пере-дампить игровые картриджи <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\"> или <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\"> уÑтановленные игры</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[ПожалуйÑта, убедитеÑÑŒ, что ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> уÑтановлен, чтобы игры можно было раÑшифровать.]]></string> 255 <string name="loader_error_encrypted_keys_description"><![CDATA[ПожалуйÑта, убедитеÑÑŒ, что ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> уÑтановлен, чтобы игры можно было раÑшифровать.]]></string>
190 <string name="loader_error_video_core">Произошла ошибка при инициализации видеоÑдра.</string> 256 <string name="loader_error_video_core">Произошла ошибка при инициализации видеоÑдра.</string>
191 <string name="loader_error_video_core_description">Обычно Ñто вызвано неÑовмеÑтимым драйвером ГП. УÑтановка пользовательÑкого драйвера ГП может решить Ñту проблему.</string> 257 <string name="loader_error_video_core_description">Обычно Ñто вызвано неÑовмеÑтимым драйвером ГП. УÑтановка пользовательÑкого драйвера ГП может решить Ñту проблему.</string>
@@ -199,17 +265,17 @@
199 <string name="emulation_toggle_controls">Переключение управлениÑ</string> 265 <string name="emulation_toggle_controls">Переключение управлениÑ</string>
200 <string name="emulation_rel_stick_center">ОтноÑительный центр Ñтика</string> 266 <string name="emulation_rel_stick_center">ОтноÑительный центр Ñтика</string>
201 <string name="emulation_dpad_slide">Слайд креÑтовиной</string> 267 <string name="emulation_dpad_slide">Слайд креÑтовиной</string>
202 <string name="emulation_haptics">Ð¢Ð°ÐºÑ‚Ð¸Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь</string> 268 <string name="emulation_haptics">ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь от нажатий</string>
203 <string name="emulation_show_overlay">Показать оверлей</string> 269 <string name="emulation_show_overlay">Показать оверлей</string>
204 <string name="emulation_toggle_all">Переключить вÑÑ‘</string> 270 <string name="emulation_toggle_all">Переключить вÑÑ‘</string>
205 <string name="emulation_control_adjust">ÐаÑтроить оверлей</string> 271 <string name="emulation_control_adjust">Регулировка оверлеÑ</string>
206 <string name="emulation_control_scale">МаÑштаб</string> 272 <string name="emulation_control_scale">МаÑштаб</string>
207 <string name="emulation_control_opacity">ÐепрозрачноÑть</string> 273 <string name="emulation_control_opacity">ÐепрозрачноÑть</string>
208 <string name="emulation_touch_overlay_reset">СброÑить оверлей</string> 274 <string name="emulation_touch_overlay_reset">СброÑить оверлей</string>
209 <string name="emulation_touch_overlay_edit">Изменить оверлей</string> 275 <string name="emulation_touch_overlay_edit">Редактировать оверлей</string>
210 <string name="emulation_pause">Пауза ÑмулÑции</string> 276 <string name="emulation_pause">Пауза ÑмулÑции</string>
211 <string name="emulation_unpause">Возобновление ÑмулÑции</string> 277 <string name="emulation_unpause">Возобновить ÑмулÑцию</string>
212 <string name="emulation_input_overlay">ÐаÑтройки оверлеÑ</string> 278 <string name="emulation_input_overlay">ÐаÑтройка оверлеÑ</string>
213 279
214 <string name="load_settings">Загрузка наÑтроек...</string> 280 <string name="load_settings">Загрузка наÑтроек...</string>
215 281
@@ -226,6 +292,9 @@
226 <string name="fatal_error">Ð¤Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</string> 292 <string name="fatal_error">Ð¤Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</string>
227 <string name="fatal_error_message">Произошла Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Проверьте журнал Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ информации.\nПродолжение ÑмулÑции может привеÑти к ÑбоÑм и ошибкам.</string> 293 <string name="fatal_error_message">Произошла Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Проверьте журнал Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ информации.\nПродолжение ÑмулÑции может привеÑти к ÑбоÑм и ошибкам.</string>
228 <string name="performance_warning">Отключение Ñтой наÑтройки значительно Ñнизит производительноÑть ÑмулÑции! Ð”Ð»Ñ Ð´Ð¾ÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ð¸Ð»ÑƒÑ‡ÑˆÐ¸Ñ… результатов рекомендуетÑÑ Ð¾Ñтавить Ñту наÑтройку включенной.</string> 294 <string name="performance_warning">Отключение Ñтой наÑтройки значительно Ñнизит производительноÑть ÑмулÑции! Ð”Ð»Ñ Ð´Ð¾ÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ð¸Ð»ÑƒÑ‡ÑˆÐ¸Ñ… результатов рекомендуетÑÑ Ð¾Ñтавить Ñту наÑтройку включенной.</string>
295 <string name="device_memory_inadequate">ÐžÐ¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð¿Ð°Ð¼Ñть уÑтройÑтва: %1$s\nРекомендовано: %2$s</string>
296 <string name="memory_formatted">%1$s%2$s</string>
297 <string name="no_game_present">Загрузочной игры нету!</string>
229 298
230 <!-- Region Names --> 299 <!-- Region Names -->
231 <string name="region_japan">ЯпониÑ</string> 300 <string name="region_japan">ЯпониÑ</string>
@@ -236,7 +305,14 @@
236 <string name="region_korea">КореÑ</string> 305 <string name="region_korea">КореÑ</string>
237 <string name="region_taiwan">Тайвань</string> 306 <string name="region_taiwan">Тайвань</string>
238 307
239 <!-- Language Names --> 308 <!-- Memory Sizes -->
309 <string name="memory_byte">Байт</string>
310 <string name="memory_kilobyte">КБ</string>
311 <string name="memory_megabyte">МБ</string>
312 <string name="memory_gigabyte">GB</string>
313 <string name="memory_terabyte">ТБ</string>
314 <string name="memory_petabyte">ПБ</string>
315 <string name="memory_exabyte">ЕВ</string>
240 316
241 <!-- Renderer APIs --> 317 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 318 <string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +350,11 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 350 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 351 <string name="anti_aliasing_smaa">SMAA</string>
276 352
353 <!-- Screen Layouts -->
354 <string name="screen_layout_landscape">Пейзаж</string>
355 <string name="screen_layout_portrait">Портрет</string>
356 <string name="screen_layout_auto">Ðвто</string>
357
277 <!-- Aspect Ratios --> 358 <!-- Aspect Ratios -->
278 <string name="ratio_default">Стандартное (16:9)</string> 359 <string name="ratio_default">Стандартное (16:9)</string>
279 <string name="ratio_force_four_three">ЗаÑтавить 4:3</string> 360 <string name="ratio_force_four_three">ЗаÑтавить 4:3</string>
@@ -288,8 +369,8 @@
288 369
289 <!-- Gamepad Buttons --> 370 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">КреÑтовина</string> 371 <string name="gamepad_d_pad">КреÑтовина</string>
291 <string name="gamepad_left_stick">Левый мини-джойÑтик</string> 372 <string name="gamepad_left_stick">Левый Ñтик</string>
292 <string name="gamepad_right_stick">Правый мини-джойÑтик</string> 373 <string name="gamepad_right_stick">Правый Ñтик</string>
293 <string name="gamepad_home">Home</string> 374 <string name="gamepad_home">Home</string>
294 <string name="gamepad_screenshot">Скриншот</string> 375 <string name="gamepad_screenshot">Скриншот</string>
295 376
@@ -298,18 +379,32 @@
298 <string name="building_shaders">ПоÑтройка шейдеров</string> 379 <string name="building_shaders">ПоÑтройка шейдеров</string>
299 380
300 <!-- Theme options --> 381 <!-- Theme options -->
301 <string name="change_app_theme">Изменить тему приложениÑ</string> 382 <string name="change_app_theme">Сменить тему</string>
302 <string name="theme_default">По умолчанию</string> 383 <string name="theme_default">По умолчанию</string>
303 <string name="theme_material_you">Material You</string> 384 <string name="theme_material_you">Material You</string>
304 385
305 <!-- Theme Modes --> 386 <!-- Theme Modes -->
306 <string name="change_theme_mode">Изменить режим темы</string> 387 <string name="change_theme_mode">Сменить режим темы</string>
307 <string name="theme_mode_follow_system">СиÑтемнаÑ</string> 388 <string name="theme_mode_follow_system">СиÑтемнаÑ</string>
308 <string name="theme_mode_light">СветлаÑ</string> 389 <string name="theme_mode_light">СветлаÑ</string>
309 <string name="theme_mode_dark">ТемнаÑ</string> 390 <string name="theme_mode_dark">ТемнаÑ</string>
310 391
392 <!-- Audio output engines -->
393 <string name="cubeb">cubeb</string>
394
311 <!-- Black backgrounds theme --> 395 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">ИÑпользовать черный фон</string> 396 <string name="use_black_backgrounds">ЧÑрный фон</string>
313 <string name="use_black_backgrounds_description">При иÑпользовании темной темы применÑйте черный фон.</string> 397 <string name="use_black_backgrounds_description">При иÑпользовании темной темы применÑйте черный фон.</string>
314 398
315</resources> 399 <!-- Picture-In-Picture -->
400 <string name="picture_in_picture">Картинка в картинке</string>
401 <string name="picture_in_picture_description">Свернуть окно при размещении в фоновом режиме</string>
402 <string name="pause">Пауза</string>
403 <string name="play">Играть</string>
404 <string name="mute">Выключить звук</string>
405 <string name="unmute">Включить звук</string>
406
407 <!-- Licenses screen strings -->
408 <string name="licenses">Лицензии</string>
409 <string name="license_fidelityfx_fsr_description">Ð’Ñ‹ÑококачеÑтвенное маÑштабирование от AMD</string>
410 </resources>
diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml
index 5b789ee98..34809dbb8 100644
--- a/src/android/app/src/main/res/values-uk/strings.xml
+++ b/src/android/app/src/main/res/values-uk/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">Це програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ” запуÑкати ігри Ð´Ð»Ñ Ñ–Ð³Ñ€Ð¾Ð²Ð¾Ñ— конÑолі Nintendo Switch. Ми не надаємо Ñамі ігри або ключі.&lt;br /&gt;&lt;br /&gt;Перед початком роботи знайдіть ваш файл <![CDATA[<b> prod.keys </b>]]> у Ñховищі приÑтрою.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ</a>]]></string> 4 <string name="app_disclaimer">Це програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ” запуÑкати ігри Ð´Ð»Ñ Ñ–Ð³Ñ€Ð¾Ð²Ð¾Ñ— конÑолі Nintendo Switch. Ми не надаємо Ñамі ігри або ключі.&lt;br /&gt;&lt;br /&gt;Перед початком роботи знайдіть ваш файл <![CDATA[<b> prod.keys </b>]]> у Ñховищі приÑтрою.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ</a>]]></string>
5 <string name="emulation_notification_channel_name">ЕмулÑÑ†Ñ–Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°</string> 5 <string name="emulation_notification_channel_name">ЕмулÑÑ†Ñ–Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°</string>
@@ -25,7 +25,6 @@
25 <string name="back">Ðазад</string> 25 <string name="back">Ðазад</string>
26 <string name="add_games">Додати ігри</string> 26 <string name="add_games">Додати ігри</string>
27 <string name="add_games_description">Виберіть папку з іграми</string> 27 <string name="add_games_description">Виберіть папку з іграми</string>
28
29 <!-- Home strings --> 28 <!-- Home strings -->
30 <string name="home_games">Ігри</string> 29 <string name="home_games">Ігри</string>
31 <string name="home_search">Пошук</string> 30 <string name="home_search">Пошук</string>
@@ -61,6 +60,7 @@
61 <string name="invalid_keys_file">Вибрано неправильний файл ключів</string> 60 <string name="invalid_keys_file">Вибрано неправильний файл ключів</string>
62 <string name="install_keys_success">Ключі уÑпішно вÑтановлено</string> 61 <string name="install_keys_success">Ключі уÑпішно вÑтановлено</string>
63 <string name="reading_keys_failure">Помилка під Ñ‡Ð°Ñ Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² шифруваннÑ</string> 62 <string name="reading_keys_failure">Помилка під Ñ‡Ð°Ñ Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² шифруваннÑ</string>
63 <string name="install_prod_keys_failure_extension_description">ПереконайтеÑÑ, що файл ключів має Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .keys, Ñ– повторіть Ñпробу.</string>
64 <string name="invalid_keys_error">Ðевірні ключі шифруваннÑ</string> 64 <string name="invalid_keys_error">Ðевірні ключі шифруваннÑ</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">Обраний файл невірний або пошкоджений. Будь лаÑка, пере-дампіть ваші ключі.</string> 66 <string name="install_keys_failure_description">Обраний файл невірний або пошкоджений. Будь лаÑка, пере-дампіть ваші ключі.</string>
@@ -68,8 +68,6 @@
68 <string name="install_gpu_driver_description">Ð’Ñтановіть альтернативні драйвери Ð´Ð»Ñ Ð¿Ð¾Ñ‚ÐµÐ½Ñ†Ñ–Ð¹Ð½Ð¾ кращої продуктивноÑті та/або точноÑті</string> 68 <string name="install_gpu_driver_description">Ð’Ñтановіть альтернативні драйвери Ð´Ð»Ñ Ð¿Ð¾Ñ‚ÐµÐ½Ñ†Ñ–Ð¹Ð½Ð¾ кращої продуктивноÑті та/або точноÑті</string>
69 <string name="advanced_settings">Розширені налаштуваннÑ</string> 69 <string name="advanced_settings">Розширені налаштуваннÑ</string>
70 <string name="settings_description">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² емулÑтора</string> 70 <string name="settings_description">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² емулÑтора</string>
71 <string name="search_recently_played">Ðещодавно зіграно</string>
72 <string name="search_recently_added">Ðещодавно додано</string>
73 <string name="search_retail">Роздрібні</string> 71 <string name="search_retail">Роздрібні</string>
74 <string name="search_homebrew">Homebrew</string> 72 <string name="search_homebrew">Homebrew</string>
75 <string name="open_user_folder">Відкрити папку yuzu</string> 73 <string name="open_user_folder">Відкрити папку yuzu</string>
@@ -86,7 +84,6 @@
86 <string name="save_file_invalid_zip_structure_description">Ðазва першої вкладеної папки має бути ідентифікатором гри.</string> 84 <string name="save_file_invalid_zip_structure_description">Ðазва першої вкладеної папки має бути ідентифікатором гри.</string>
87 <string name="import_saves">Імпорт</string> 85 <string name="import_saves">Імпорт</string>
88 <string name="export_saves">ЕкÑпорт</string> 86 <string name="export_saves">ЕкÑпорт</string>
89
90 <!-- About screen strings --> 87 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia не Ñ–Ñнує</string> 88 <string name="gaia_is_not_real">Gaia не Ñ–Ñнує</string>
92 <string name="copied_to_clipboard">Скопійовано в буфер обміну</string> 89 <string name="copied_to_clipboard">Скопійовано в буфер обміну</string>
@@ -113,42 +110,20 @@
113 <string name="our_eternal_gratitude">Ðаша неÑкінченна вдÑчніÑть</string> 110 <string name="our_eternal_gratitude">Ðаша неÑкінченна вдÑчніÑть</string>
114 <string name="are_you_interested">Ви зацікавлені?</string> 111 <string name="are_you_interested">Ви зацікавлені?</string>
115 112
116 <!-- General settings strings -->
117 <string name="frame_limit_enable">Увімкнути Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ñті</string>
118 <string name="frame_limit_enable_description">Якщо цю функцію ввімкнено, швидкіÑть емулÑції буде обмежена зазначеним відÑотком від нормальної швидкоÑті.</string>
119 <string name="frame_limit_slider">ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ñотка швидкоÑті</string> 113 <string name="frame_limit_slider">ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ñотка швидкоÑті</string>
120 <string name="frame_limit_slider_description">Вказує відÑоток Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ñті емулÑції. При значенні за замовчуваннÑм 100% емулÑÑ†Ñ–Ñ Ð±ÑƒÐ´Ðµ обмежена нормальною швидкіÑтю. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¸Ñ‰Ðµ або нижче збільшуватимуть або зменшуватимуть Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ñті.</string>
121 <string name="cpu_accuracy">ТочніÑть ЦП</string> 114 <string name="cpu_accuracy">ТочніÑть ЦП</string>
122
123 <!-- System settings strings -->
124 <string name="use_docked_mode">Режим док-Ñтанції</string>
125 <string name="use_docked_mode_description">ЕмулÑÑ†Ñ–Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ док-Ñтанції, що збільшує роздільну здатніÑть за рахунок Ð·Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¸Ð²Ð½Ð¾Ñті.</string>
126 <string name="emulated_region">Емульований регіон</string> 115 <string name="emulated_region">Емульований регіон</string>
127 <string name="emulated_language">Емульована мова</string> 116 <string name="emulated_language">Емульована мова</string>
128 <string name="select_rtc_date">Оберіть дату RTC</string> 117 <string name="use_custom_rtc">КориÑтувацький RTC</string>
129 <string name="select_rtc_time">Оберіть Ñ‡Ð°Ñ RTC</string>
130 <string name="use_custom_rtc">Увімкнути кориÑтувацький RTC</string>
131 <string name="use_custom_rtc_description">Цей параметр дає змогу вÑтановити кориÑтувацький годинник реального чаÑу окремо від поточного ÑиÑтемного чаÑу</string>
132 <string name="set_custom_rtc">Ð’Ñтановити кориÑтувацький RTC</string>
133
134 <!-- Graphics settings strings --> 118 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">Рівень точноÑті</string> 119 <string name="renderer_accuracy">Рівень точноÑті</string>
137 <string name="renderer_resolution">Роздільна здатніÑть</string>
138 <string name="renderer_vsync">Режим верт. Ñинхронізації</string> 120 <string name="renderer_vsync">Режим верт. Ñинхронізації</string>
139 <string name="renderer_aspect_ratio">Ð¡Ð¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ñторін</string>
140 <string name="renderer_scaling_filter">Фільтр адаптації вікна</string>
141 <string name="renderer_anti_aliasing">Метод згладжуваннÑ</string>
142 <string name="renderer_force_max_clock">ПримуÑово змуÑити макÑимальну тактову чаÑтоту (тільки Ð´Ð»Ñ Adreno)</string> 121 <string name="renderer_force_max_clock">ПримуÑово змуÑити макÑимальну тактову чаÑтоту (тільки Ð´Ð»Ñ Adreno)</string>
143 <string name="renderer_force_max_clock_description">Змушує ГП працювати на макÑимально можливих тактових чаÑтотах (теплові Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ñе одно будуть заÑтоÑовуватиÑÑ).</string> 122 <string name="renderer_force_max_clock_description">Змушує ГП працювати на макÑимально можливих тактових чаÑтотах (теплові Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ñе одно будуть заÑтоÑовуватиÑÑ).</string>
144 <string name="renderer_asynchronous_shaders">ВикориÑтовувати аÑинхронні шейдери</string> 123 <string name="renderer_asynchronous_shaders">ВикориÑтовувати аÑинхронні шейдери</string>
145 <string name="renderer_asynchronous_shaders_description">Компілює шейдери аÑинхронно, що зменшує завиÑаннÑ, але може натоміÑть надати візуальні баги.</string> 124 <!-- Debug settings strings -->
146 <string name="renderer_debug">Увімкнути Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð³Ñ€Ð°Ñ„Ñ–ÐºÐ¸</string> 125 <string name="cpu">ЦП</string>
147 <string name="renderer_debug_description">Якщо увімкнено, графічний API переходить у повільніший режим налагодженнÑ</string> 126 <string name="renderer_api">API</string>
148 <string name="use_disk_shader_cache">ВикориÑтовувати кеш шейдерів на диÑку</string>
149 <string name="use_disk_shader_cache_description">Ð—Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð¸Ñань завдÑки зберіганню та завантаженню згенерованих шейдерів на Ñховище.</string>
150
151 <!-- Audio settings strings -->
152 <string name="audio_volume">ГучніÑть</string> 127 <string name="audio_volume">ГучніÑть</string>
153 <string name="audio_volume_description">Вказує гучніÑть аудіовиходу.</string> 128 <string name="audio_volume_description">Вказує гучніÑть аудіовиходу.</string>
154 129
@@ -161,17 +136,20 @@
161 <string name="reset_setting_confirmation">Чи хочете ви повернути цей параметр до Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм?</string> 136 <string name="reset_setting_confirmation">Чи хочете ви повернути цей параметр до Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм?</string>
162 <string name="reset_to_default">Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð´Ð¾ налаштувань за замовчуваннÑм</string> 137 <string name="reset_to_default">Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð´Ð¾ налаштувань за замовчуваннÑм</string>
163 <string name="reset_all_settings">Скинути вÑÑ– налаштуваннÑ</string> 138 <string name="reset_all_settings">Скинути вÑÑ– налаштуваннÑ</string>
164 <string name="reset_all_settings_description">УÑÑ– додаткові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ Ñкинуто до Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° замовчуваннÑм. Це неможливо ÑкаÑувати.</string>
165 <string name="settings_reset">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñкинуто</string> 139 <string name="settings_reset">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñкинуто</string>
166 <string name="close">Закрити</string> 140 <string name="close">Закрити</string>
167 <string name="learn_more">ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ</string> 141 <string name="learn_more">ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ</string>
168 142 <string name="auto">Ðвто</string>
143 <string name="string_null">Null</string>
144 <string name="string_import">Імпорт</string>
145 <string name="export">ЕкÑпорт</string>
169 <!-- GPU driver installation --> 146 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">Вибрати драйвер ГП</string> 147 <string name="select_gpu_driver">Вибрати драйвер ГП</string>
171 <string name="select_gpu_driver_title">Хочете замінити поточний драйвер ГП?</string> 148 <string name="select_gpu_driver_title">Хочете замінити поточний драйвер ГП?</string>
172 <string name="select_gpu_driver_install">Ð’Ñтановити</string> 149 <string name="select_gpu_driver_install">Ð’Ñтановити</string>
173 <string name="select_gpu_driver_default">За замовчуваннÑм</string> 150 <string name="select_gpu_driver_default">За замовчуваннÑм</string>
174 <string name="select_gpu_driver_use_default">ВикориÑтовуєтьÑÑ Ñтандартний драйвер ГП</string> 151 <string name="select_gpu_driver_use_default">ВикориÑтовуєтьÑÑ Ñтандартний драйвер ГП</string>
152 <string name="select_gpu_driver_error">Обрано неправильний драйвер, викориÑтовуєтьÑÑ Ñтандартний ÑиÑтемний!</string>
175 <string name="system_gpu_driver">СиÑтемний драйвер ГП</string> 153 <string name="system_gpu_driver">СиÑтемний драйвер ГП</string>
176 <string name="installing_driver">Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð°...</string> 154 <string name="installing_driver">Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð°...</string>
177 155
@@ -182,40 +160,19 @@
182 <string name="preferences_graphics">Графіка</string> 160 <string name="preferences_graphics">Графіка</string>
183 <string name="preferences_audio">Ðудіо</string> 161 <string name="preferences_audio">Ðудіо</string>
184 <string name="preferences_theme">Тема і колір</string> 162 <string name="preferences_theme">Тема і колір</string>
163 <string name="preferences_debug">ÐалагодженнÑ</string>
185 164
186 <!-- ROM loading errors --> 165 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">Ваш ROM зашифрований</string> 166 <string name="loader_error_encrypted">Ваш ROM зашифрований</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[Будь лаÑка, дотримуйтеÑÑŒ інÑтрукцій, щоб пере-дампити ваші <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">ігрові картриджі</a> або <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">вÑтановлені ігри</a>.]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[Будь лаÑка, переконайтеÑÑ, що ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> вÑтановлено, щоб ігри можна було розшифрувати.]]></string> 167 <string name="loader_error_encrypted_keys_description"><![CDATA[Будь лаÑка, переконайтеÑÑ, що ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> вÑтановлено, щоб ігри можна було розшифрувати.]]></string>
190 <string name="loader_error_video_core">СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ— відеоÑдра.</string> 168 <string name="loader_error_video_core">СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ— відеоÑдра.</string>
191 <string name="loader_error_video_core_description">Зазвичай це Ñпричинено неÑуміÑним драйвером ГП. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувацького драйвера ГП може вирішити цю проблему.</string> 169 <string name="loader_error_video_core_description">Зазвичай це Ñпричинено неÑуміÑним драйвером ГП. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувацького драйвера ГП може вирішити цю проблему.</string>
192 <string name="loader_error_invalid_format">Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити ROM</string> 170 <string name="loader_error_invalid_format">Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити ROM</string>
193 <string name="loader_error_file_not_found">Файл ROM не Ñ–Ñнує</string> 171 <string name="loader_error_file_not_found">Файл ROM не Ñ–Ñнує</string>
194 172
195 <!-- Emulation Menu -->
196 <string name="emulation_exit">Вихід з емулÑції</string>
197 <string name="emulation_done">Готово</string> 173 <string name="emulation_done">Готово</string>
198 <string name="emulation_fps_counter">Лічильник FPS</string>
199 <string name="emulation_toggle_controls">ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ</string>
200 <string name="emulation_rel_stick_center">ВідноÑний центр Ñтіка</string>
201 <string name="emulation_dpad_slide">Слайд хреÑтовиною</string>
202 <string name="emulation_haptics">Тактильний зворотний зв\'Ñзок</string>
203 <string name="emulation_show_overlay">Показати оверлей</string>
204 <string name="emulation_toggle_all">Перемкнути вÑе</string>
205 <string name="emulation_control_adjust">Ðалаштувати оверлей</string>
206 <string name="emulation_control_scale">МаÑштаб</string> 174 <string name="emulation_control_scale">МаÑштаб</string>
207 <string name="emulation_control_opacity">ÐепрозоріÑть</string> 175 <string name="emulation_control_opacity">ÐепрозоріÑть</string>
208 <string name="emulation_touch_overlay_reset">Скинути оверлей</string>
209 <string name="emulation_touch_overlay_edit">Змінити оверлей</string>
210 <string name="emulation_pause">Пауза емулÑції</string>
211 <string name="emulation_unpause">Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÐµÐ¼ÑƒÐ»Ñції</string>
212 <string name="emulation_input_overlay">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð²ÐµÑ€Ð»ÐµÑ</string>
213
214 <string name="load_settings">Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ...</string>
215
216 <!-- Software keyboard -->
217 <string name="software_keyboard">Віртуальна клавіатура</string>
218
219 <!-- Errors and warnings --> 176 <!-- Errors and warnings -->
220 <string name="abort_button">Перервати</string> 177 <string name="abort_button">Перервати</string>
221 <string name="continue_button">Продовжити</string> 178 <string name="continue_button">Продовжити</string>
@@ -226,7 +183,6 @@
226 <string name="fatal_error">Фатальна помилка</string> 183 <string name="fatal_error">Фатальна помилка</string>
227 <string name="fatal_error_message">СталаÑÑ Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð° помилка. Перевірте журнал Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÐ»Ð°Ð´Ð½Ð¾Ñ— інформації.\nÐŸÑ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ ÐµÐ¼ÑƒÐ»Ñції може призвеÑти до збоїв Ñ– помилок.</string> 184 <string name="fatal_error_message">СталаÑÑ Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð° помилка. Перевірте журнал Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÐ»Ð°Ð´Ð½Ð¾Ñ— інформації.\nÐŸÑ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ ÐµÐ¼ÑƒÐ»Ñції може призвеÑти до збоїв Ñ– помилок.</string>
228 <string name="performance_warning">Ð’Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡Ð½Ð¾ знизить продуктивніÑть емулÑції! Ð”Ð»Ñ Ð´Ð¾ÑÑÐ³Ð½ÐµÐ½Ð½Ñ Ð½Ð°Ð¹ÐºÑ€Ð°Ñ‰Ð¸Ñ… результатів рекомендуєтьÑÑ Ð·Ð°Ð»Ð¸ÑˆÐ¸Ñ‚Ð¸ це Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¼.</string> 185 <string name="performance_warning">Ð’Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡Ð½Ð¾ знизить продуктивніÑть емулÑції! Ð”Ð»Ñ Ð´Ð¾ÑÑÐ³Ð½ÐµÐ½Ð½Ñ Ð½Ð°Ð¹ÐºÑ€Ð°Ñ‰Ð¸Ñ… результатів рекомендуєтьÑÑ Ð·Ð°Ð»Ð¸ÑˆÐ¸Ñ‚Ð¸ це Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¼.</string>
229
230 <!-- Region Names --> 186 <!-- Region Names -->
231 <string name="region_japan">ЯпоніÑ</string> 187 <string name="region_japan">ЯпоніÑ</string>
232 <string name="region_usa">СШÐ</string> 188 <string name="region_usa">СШÐ</string>
@@ -236,8 +192,7 @@
236 <string name="region_korea">КореÑ</string> 192 <string name="region_korea">КореÑ</string>
237 <string name="region_taiwan">Тайвань</string> 193 <string name="region_taiwan">Тайвань</string>
238 194
239 <!-- Language Names --> 195 <string name="memory_gigabyte">GB</string>
240
241 <!-- Renderer APIs --> 196 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 197 <string name="renderer_vulkan">Vulkan</string>
243 <string name="renderer_none">Вимкнено</string> 198 <string name="renderer_none">Вимкнено</string>
@@ -274,22 +229,18 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 229 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 230 <string name="anti_aliasing_smaa">SMAA</string>
276 231
232 <string name="screen_layout_auto">Ðвто</string>
233
277 <!-- Aspect Ratios --> 234 <!-- Aspect Ratios -->
278 <string name="ratio_default">За замовчуваннÑм (16:9)</string> 235 <string name="ratio_default">За замовчуваннÑм (16:9)</string>
279 <string name="ratio_force_four_three">ЗмуÑити 4:3</string> 236 <string name="ratio_force_four_three">ЗмуÑити 4:3</string>
280 <string name="ratio_force_twenty_one_nine">ЗмуÑити 21:9</string> 237 <string name="ratio_force_twenty_one_nine">ЗмуÑити 21:9</string>
281 <string name="ratio_force_sixteen_ten">ЗмуÑити 16:10</string> 238 <string name="ratio_force_sixteen_ten">ЗмуÑити 16:10</string>
282 <string name="ratio_stretch">РозтÑгнути до вікна</string>
283
284 <!-- CPU Accuracy --> 239 <!-- CPU Accuracy -->
285 <string name="cpu_accuracy_accurate">Точно</string> 240 <string name="cpu_accuracy_accurate">Точно</string>
286 <string name="cpu_accuracy_unsafe">Ðебезпечно</string> 241 <string name="cpu_accuracy_unsafe">Ðебезпечно</string>
287 <string name="cpu_accuracy_paranoid">Параноїк (повільно)</string> 242 <string name="cpu_accuracy_paranoid">Параноїк (повільно)</string>
288 243
289 <!-- Gamepad Buttons -->
290 <string name="gamepad_d_pad">Кнопки напрÑмків</string>
291 <string name="gamepad_left_stick">Лівий міні-джойÑтик</string>
292 <string name="gamepad_right_stick">Правий міні-джойÑтик</string>
293 <string name="gamepad_home">Home</string> 244 <string name="gamepad_home">Home</string>
294 <string name="gamepad_screenshot">Знімок екрану</string> 245 <string name="gamepad_screenshot">Знімок екрану</string>
295 246
@@ -297,19 +248,16 @@
297 <string name="preparing_shaders">Підготовка шейдерів</string> 248 <string name="preparing_shaders">Підготовка шейдерів</string>
298 <string name="building_shaders">Побудова шейдерів</string> 249 <string name="building_shaders">Побудова шейдерів</string>
299 250
300 <!-- Theme options -->
301 <string name="change_app_theme">Змінити тему заÑтоÑунку</string>
302 <string name="theme_default">За замовчуваннÑм</string> 251 <string name="theme_default">За замовчуваннÑм</string>
303 <string name="theme_material_you">Material You</string> 252 <string name="theme_material_you">Material You</string>
304 253
305 <!-- Theme Modes -->
306 <string name="change_theme_mode">Змінити режим теми</string>
307 <string name="theme_mode_follow_system">СиÑтемна</string> 254 <string name="theme_mode_follow_system">СиÑтемна</string>
308 <string name="theme_mode_light">Світла</string> 255 <string name="theme_mode_light">Світла</string>
309 <string name="theme_mode_dark">Темна</string> 256 <string name="theme_mode_dark">Темна</string>
310 257
311 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">ВикориÑтовувати чорне тло</string>
313 <string name="use_black_backgrounds_description">У разі викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‚ÐµÐ¼Ð½Ð¾Ñ— теми заÑтоÑовуйте чорне тло.</string> 258 <string name="use_black_backgrounds_description">У разі викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‚ÐµÐ¼Ð½Ð¾Ñ— теми заÑтоÑовуйте чорне тло.</string>
314 259
315</resources> 260 <string name="mute">Вимкнути звук</string>
261 <string name="unmute">Увімкнути звук</string>
262
263 </resources>
diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml
new file mode 100644
index 000000000..f977db3a2
--- /dev/null
+++ b/src/android/app/src/main/res/values-vi/strings.xml
@@ -0,0 +1,340 @@
1<?xml version="1.0" encoding="utf-8"?>
2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3
4 <string name="app_disclaimer">Phần má»m này sẽ chạy các game cho máy chÆ¡i game Nintendo Switch. Không có title games hoặc keys được bao gồm.&lt;br /&gt;&lt;br /&gt;Trước khi bạn bắt đầu, hãy tìm tập tin <![CDATA[<b> prod.keys </b>]]> trên bá»™ nhá»› thiết bị cá»§a bạn.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Tìm hiểu thêm</a>]]></string>
5 <string name="emulation_notification_channel_name">Giả lập đang chạy</string>
6 <string name="emulation_notification_channel_description">Hiển thị thông báo liên tục khi giả lập đang chạy.</string>
7 <string name="emulation_notification_running">yuzu đang chạy</string>
8 <string name="notice_notification_channel_name">Thông báo và lỗi</string>
9 <string name="notice_notification_channel_description">Hiển thị thông báo khi có sự cố xảy ra.</string>
10 <string name="notification_permission_not_granted">Ứng dụng không được cấp quyá»n thông báo!</string>
11
12 <!-- Setup strings -->
13 <string name="welcome">Chào mừng!</string>
14 <string name="welcome_description">Tìm hiểu cách cài đặt &lt;b>yuzu&lt;/b> và bắt đầu giả lập.</string>
15 <string name="get_started">Bắt đầu</string>
16 <string name="keys">Keys</string>
17 <string name="keys_description">Chá»n tệp &lt;b>prod.keys&lt;/b> cá»§a bạn bằng nút bên dưới.</string>
18 <string name="select_keys">Chá»n Keys</string>
19 <string name="games">Game</string>
20 <string name="games_description">Chá»n thư mục &lt;b>Game&lt;/b> cá»§a bạn bằng nút bên dưới.</string>
21 <string name="done">Hoàn thành</string>
22 <string name="done_description">Tất cả đã hoàn tất.\nHãy tận hưởng các game của bạn!</string>
23 <string name="text_continue">Tiếp tục</string>
24 <string name="next">Tiếp theo</string>
25 <string name="back">Trở lại</string>
26 <string name="add_games">Thêm Game</string>
27 <string name="add_games_description">Chá»n thư mục game cá»§a bạn</string>
28 <!-- Home strings -->
29 <string name="home_games">Game</string>
30 <string name="home_search">Tìm kiếm</string>
31 <string name="home_settings">Cài đặt</string>
32 <string name="empty_gamelist">Không tìm thấy tập tin hoặc chưa có thư mục game nào được chá»n.</string>
33 <string name="search_and_filter_games">Tìm và lá»c game</string>
34 <string name="select_games_folder">Chá»n thư mục game</string>
35 <string name="select_games_folder_description">Cho phép yuzu thêm vào danh sách game</string>
36 <string name="add_games_warning">Bá» qua việc lá»±a chá»n thư mục game?</string>
37 <string name="add_games_warning_description">Game sẽ không hiển thị trong danh sách nếu má»™t thư mục không được chá»n.</string>
38 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
39 <string name="home_search_games">Tìm kiếm game</string>
40 <string name="games_dir_selected">Thư mục game đã được chá»n</string>
41 <string name="install_prod_keys">Cài đặt prod.keys</string>
42 <string name="install_prod_keys_description">Yêu cầu để giải mã các game bán lẻ</string>
43 <string name="install_prod_keys_warning">BỠqua việc thêm keys?</string>
44 <string name="install_prod_keys_warning_description">Cần có keys hợp lệ để giả lập các game bán lẻ. Chỉ có các ứng dụng homebrew có thể vận hành nếu bạn tiếp tục.</string>
45 <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
46 <string name="notifications">Thông báo</string>
47 <string name="notifications_description">Cấp quyá»n thông báo bằng nút bên dưới.</string>
48 <string name="give_permission">Cấp quyá»n</string>
49 <string name="notification_warning">Bá» qua việc cấp quyá»n thông báo?</string>
50 <string name="notification_warning_description">yuzu sẽ không thể gá»­i những thông báo quan trá»ng đến bạn.</string>
51 <string name="permission_denied">Äã từ chối cấp quyá»n</string>
52 <string name="permission_denied_description">Bạn từ chối cấp quyá»n này quá nhiá»u lần và giá» bạn phải cấp quyá»n thá»§ công trong cài đặt máy.</string>
53 <string name="about">Thông tin</string>
54 <string name="about_description">Phiên bản, đóng góp và những thứ khác</string>
55 <string name="warning_help">Trợ giúp</string>
56 <string name="warning_skip">Bá» qua</string>
57 <string name="warning_cancel">Há»§y bá»</string>
58 <string name="install_amiibo_keys">Cài đặt keys Amiibo</string>
59 <string name="install_amiibo_keys_description">Cần thiết để dùng Amiibo trong game</string>
60 <string name="invalid_keys_file">Tệp keys không hợp lệ đã được chá»n</string>
61 <string name="install_keys_success">Cài đặt keys thành công</string>
62 <string name="reading_keys_failure">Lá»—i Ä‘á»c keys mã hóa</string>
63 <string name="install_prod_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .keys và thử lại.</string>
64 <string name="install_amiibo_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .bin và thử lại.</string>
65 <string name="invalid_keys_error">Keys mã hoá không hợp lệ</string>
66 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
67 <string name="install_keys_failure_description">Tệp đã chá»n sai hoặc há»ng. Vui lòng trích xuất lại keys cá»§a bạn.</string>
68 <string name="install_gpu_driver">Cài đặt driver GPU</string>
69 <string name="install_gpu_driver_description">Cài đặt driver thay thế để có thể có hiệu suất tốt và chính xác hơn</string>
70 <string name="advanced_settings">Cài đặt nâng cao</string>
71 <string name="settings_description">Cấu hình cài đặt giả lập</string>
72 <string name="search_recently_played">Äã chÆ¡i gần đây</string>
73 <string name="search_recently_added">Äã thêm gần đây</string>
74 <string name="search_retail">Bán lẻ</string>
75 <string name="search_homebrew">Homebrew</string>
76 <string name="open_user_folder">Mở thư mục yuzu</string>
77 <string name="open_user_folder_description">Quản lý tệp nội bộ của yuzu</string>
78 <string name="theme_and_color_description">Thay đổi giao diện ứng dụng</string>
79 <string name="no_file_manager">Không tìm thấy trình quản lý tập tin</string>
80 <string name="notification_no_directory_link">Không thể mở thư mục yuzu</string>
81 <string name="notification_no_directory_link_description">Vui lòng xác định thư mục ngưá»i dùng vá»›i bảng Ä‘iá»u khiển bên cá»§a trình quản lý tệp thá»§ công.</string>
82 <string name="manage_save_data">Quản lý dữ liệu save</string>
83 <string name="manage_save_data_description">Äã tìm thấy dữ liệu save. Vui lòng chá»n má»™t tuỳ chá»n bên dưới.</string>
84 <string name="import_export_saves_description">Nhập hoặc xuất tệp save</string>
85 <string name="save_file_imported_success">Nhập thành công</string>
86 <string name="save_file_invalid_zip_structure">Cấu trúc thư mục save không hợp lệ</string>
87 <string name="save_file_invalid_zip_structure_description">Tên thư mục con đầu tiên phải là ID title của game.</string>
88 <string name="import_saves">Nhập</string>
89 <string name="export_saves">Xuất</string>
90 <string name="install_firmware">Cài đặt firmware</string>
91 <string name="install_firmware_description">Firmware phải được đặt trong một tập tin nén ZIP và cần thiết để khởi chạy một số game</string>
92 <string name="firmware_installing">Äang cài đặt firmware</string>
93 <string name="firmware_installed_success">Cài đặt firmware thành công</string>
94 <string name="firmware_installed_failure">Cài đặt firmware thất bại</string>
95 <string name="share_log">Chia sẻ nhật ký gỡ lỗi</string>
96 <string name="share_log_description">Chia sẻ tập tin nhật ký cá»§a yuzu để gỡ lá»—i vấn Ä‘á»</string>
97 <string name="share_log_missing">Không tìm thấy tập tin nhật ký</string>
98 <string name="install_game_content">Cài đặt nội dung game</string>
99 <string name="install_game_content_description">Cài đặt cập nhật game hoặc DLC</string>
100 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
101 <!-- About screen strings -->
102 <string name="gaia_is_not_real">Gaia không có thật</string>
103 <string name="copied_to_clipboard">Äã sao chép vào bá»™ nhá»› tạm</string>
104 <string name="about_app_description">Một giả lập Switch mã nguồn mở</string>
105 <string name="contributors">Ngưá»i đóng góp</string>
106 <string name="contributors_description">ÄÆ°á»£c làm vá»›i \u2764 từ nhóm yuzu</string>
107 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
108 <string name="licenses_description">Các dá»± án làm cho yuzu trên Android trở thành Ä‘iá»u có thể</string>
109 <string name="build">Dá»±ng</string>
110 <string name="support_link">https://discord.gg/u77vRWY</string>
111 <string name="website_link">https://yuzu-emu.org/</string>
112 <string name="github_link">https://github.com/yuzu-emu</string>
113
114 <!-- Early access upgrade strings -->
115 <string name="early_access">Early Access</string>
116 <string name="get_early_access">Tải Early Access</string>
117 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
118 <string name="get_early_access_description">Các tính năng tiên tiến, truy cập sá»›m các bản cập nhật và nhiá»u hÆ¡n nữa</string>
119 <string name="early_access_benefits">Lợi ích của Early Access</string>
120 <string name="cutting_edge_features">Tính năng tiên tiến</string>
121 <string name="early_access_updates">Truy cập sớm các bản cập nhật</string>
122 <string name="no_manual_installation">Không có cài đặt thủ công</string>
123 <string name="prioritized_support">Ưu tiên hỗ trợ</string>
124 <string name="helping_game_preservation">Hỗ trợ bảo tồn game</string>
125 <string name="our_eternal_gratitude">Sự biết ơn vô hạn của chúng tôi</string>
126 <string name="are_you_interested">Bạn có thấy hứng thú không?</string>
127
128 <!-- General settings strings -->
129 <string name="frame_limit_enable">Giới hạn tốc độ</string>
130 <string name="frame_limit_enable_description">Giá»›i hạn tốc độ giả lập ở má»™t phần trăm cụ thể cá»§a tốc độ bình thưá»ng.</string>
131 <string name="frame_limit_slider">Giới hạn phần trăm tốc độ</string>
132 <string name="frame_limit_slider_description">Xác định phần trăm để giá»›i hạn tốc độ giả lập. 100% là tốc độ bình thưá»ng. Giá trị cao hÆ¡n hoặc thấp hÆ¡n sẽ tăng hoặc giảm giá»›i hạn tốc độ.</string>
133 <string name="cpu_accuracy">Äá»™ chính xác CPU</string>
134 <!-- System settings strings -->
135 <string name="use_docked_mode">Chế độ docked</string>
136 <string name="use_docked_mode_description">Tăng độ phân giải, giảm hiệu suất. Chế độ handheld được sử dụng khi tắt, giảm độ phân giải và tăng hiệu suất.</string>
137 <string name="emulated_region">Khu vực giả lập</string>
138 <string name="emulated_language">Ngôn ngữ giả lập</string>
139 <string name="select_rtc_date">Chá»n ngày RTC</string>
140 <string name="select_rtc_time">Chá»n giá» RTC</string>
141 <string name="use_custom_rtc">RTC tuỳ chỉnh</string>
142 <string name="use_custom_rtc_description">Cho phép bạn thiết lập má»™t đồng hồ thá»i gian thá»±c tùy chỉnh riêng biệt so vá»›i thá»i gian hệ thống hiện tại.</string>
143 <string name="set_custom_rtc">Thiết lập RTC tùy chỉnh</string>
144
145 <!-- Graphics settings strings -->
146 <string name="renderer_accuracy">Mức độ chính xác</string>
147 <string name="renderer_resolution">Äá»™ phân giải (Handheld/Docked)</string>
148 <string name="renderer_vsync">Chế độ VSync</string>
149 <string name="renderer_aspect_ratio">Tỉ lệ khung hình</string>
150 <string name="renderer_scaling_filter">Bá»™ lá»c Ä‘iá»u chỉnh cá»­a sổ</string>
151 <string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
152 <string name="renderer_force_max_clock">Buộc chạy ở xung nhịp tối đa (chỉ cho Adreno)</string>
153 <string name="renderer_force_max_clock_description">Buộc GPU hoạt động ở xung nhịp tối đa có thể (ràng buộc nhiệt độ vẫn sẽ được áp dụng).</string>
154 <string name="renderer_asynchronous_shaders">Dùng các shader bất đồng bộ</string>
155 <string name="renderer_asynchronous_shaders_description">Biên dịch các shader bất đồng bộ, giảm tình trạng giật lag nhưng có thể gây ra các lỗi.</string>
156 <string name="renderer_reactive_flushing">Dùng xả tương ứng</string>
157 <string name="renderer_reactive_flushing_description">Cải thiện độ chính xác kết xuất trong má»™t số game nhưng đồng thá»i giảm hiệu suất.</string>
158 <string name="use_disk_shader_cache">Lưu bộ nhớ đệm shader trên ổ cứng</string>
159 <string name="use_disk_shader_cache_description">Giảm tình trạng giật lag bằng cách lưu trữ và tải các shader được tạo ra nội bộ.</string>
160
161 <!-- Debug settings strings -->
162 <string name="cpu">CPU</string>
163 <string name="renderer_api">API</string>
164 <string name="renderer_debug">Gỡ lỗi đồ hoạ</string>
165 <string name="renderer_debug_description">Äặt API đồ há»a vào chế độ gỡ lá»—i chậm.</string>
166 <string name="audio_volume">Âm lượng</string>
167 <string name="audio_volume_description">Xác định âm lượng của đầu ra âm thanh.</string>
168
169 <!-- Miscellaneous -->
170 <string name="slider_default">Mặc định</string>
171 <string name="ini_saved">Cài đặt đã lưu</string>
172 <string name="gameid_saved">Cài đặt đã lưu cho %1$s</string>
173 <string name="error_saving">Lỗi khi lưu %1$s.ini: %2$s</string>
174 <string name="loading">Äang tải...</string>
175 <string name="reset_setting_confirmation">Bạn có muốn đặt lại cài đặt này vỠgiá trị mặc định không?</string>
176 <string name="reset_to_default">Äặt lại vá» mặc định</string>
177 <string name="reset_all_settings">Bạn có muốn đặt lại tất cả các cài đặt vỠgiá trị mặc định không?</string>
178 <string name="reset_all_settings_description">Tất cả các cài đặt nâng cao sẽ được đặt lại vá» cấu hình mặc định. Äiá»u này không thể hoàn tác.</string>
179 <string name="settings_reset">Cài đặt đã được đặt lại</string>
180 <string name="close">Äóng</string>
181 <string name="learn_more">Tìm hiểu thêm</string>
182 <string name="auto">Tự động</string>
183 <string name="submit">Gá»­i</string>
184 <string name="string_null">Null</string>
185 <string name="string_import">Nhập</string>
186 <string name="export">Xuất</string>
187 <!-- GPU driver installation -->
188 <string name="select_gpu_driver">Chá»n driver GPU</string>
189 <string name="select_gpu_driver_title">Bạn có muốn thay thế driver GPU hiện tại không?</string>
190 <string name="select_gpu_driver_install">Cài đặt</string>
191 <string name="select_gpu_driver_default">Mặc định</string>
192 <string name="select_gpu_driver_use_default">Dùng driver GPU mặc định</string>
193 <string name="select_gpu_driver_error">Driver không hợp lệ đã được chá»n, dùng mặc định hệ thống!</string>
194 <string name="system_gpu_driver">Driver GPU hệ thống</string>
195 <string name="installing_driver">Äang cài đặt driver...</string>
196
197 <!-- Preferences Screen -->
198 <string name="preferences_settings">Cài đặt</string>
199 <string name="preferences_general">Chung</string>
200 <string name="preferences_system">Hệ thống</string>
201 <string name="preferences_graphics">Äồ hoạ</string>
202 <string name="preferences_audio">Âm thanh</string>
203 <string name="preferences_theme">Chủ đỠvà màu sắc</string>
204 <string name="preferences_debug">Gỡ lỗi</string>
205
206 <!-- ROM loading errors -->
207 <string name="loader_error_encrypted">ROM của bạn đã bị mã hoá</string>
208 <string name="loader_error_encrypted_keys_description"><![CDATA[Vui lòng đảm bảo tệp <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> đã được cài đặt để các game có thể được giải mã.]]></string>
209 <string name="loader_error_video_core">Äã xảy ra lá»—i khi khởi tạo lõi video</string>
210 <string name="loader_error_video_core_description">Việc này thưá»ng do driver GPU không tương thích. Cài đặt má»™t driver GPU tùy chỉnh có thể giải quyết vấn đỠnày.</string>
211 <string name="loader_error_invalid_format">Không thể nạp ROM</string>
212 <string name="loader_error_file_not_found">Tệp ROM không tồn tại</string>
213
214 <!-- Emulation Menu -->
215 <string name="emulation_exit">Thoát giả lập</string>
216 <string name="emulation_done">Hoàn thành</string>
217 <string name="emulation_fps_counter">Bộ đếm FPS</string>
218 <string name="emulation_toggle_controls">Chuyển đổi Ä‘iá»u khiển</string>
219 <string name="emulation_rel_stick_center">Trung tâm nút cần xoay tương đối</string>
220 <string name="emulation_dpad_slide">Trượt D-pad</string>
221 <string name="emulation_haptics">Chạm haptics</string>
222 <string name="emulation_show_overlay">Hiện lớp phủ</string>
223 <string name="emulation_toggle_all">Chuyển đổi tất cả</string>
224 <string name="emulation_control_adjust">Äiá»u chỉnh lá»›p phá»§</string>
225 <string name="emulation_control_scale">Tỉ lệ thu phóng</string>
226 <string name="emulation_control_opacity">Äá»™ má»</string>
227 <string name="emulation_touch_overlay_reset">Äặt lại lá»›p phá»§</string>
228 <string name="emulation_touch_overlay_edit">Chỉnh sửa lớp phủ</string>
229 <string name="emulation_pause">Tạm đừng giả lập</string>
230 <string name="emulation_unpause">Tiếp tục giả lập</string>
231 <string name="emulation_input_overlay">Tuỳ chá»n lá»›p phá»§</string>
232
233 <string name="load_settings">Äang tải cài đặt...</string>
234
235 <!-- Software keyboard -->
236 <string name="software_keyboard">Bàn phím má»m</string>
237
238 <!-- Errors and warnings -->
239 <string name="abort_button">Há»§y bá»</string>
240 <string name="continue_button">Tiếp tục</string>
241 <string name="system_archive_not_found">Không tìm thấy bản lưu trữ của hệ thống</string>
242 <string name="system_archive_not_found_message">%s bị thiếu. Vui lòng trích xuất các bản lưu trữ hệ thống của bạn.\nNếu chạy tiếp giả lập có thể bị crash và lỗi.</string>
243 <string name="system_archive_general">Một bản lưu trữ của hệ thống</string>
244 <string name="save_load_error">Lỗi Lưu/Tải</string>
245 <string name="fatal_error">Lá»—i nghiêm trá»ng</string>
246 <string name="fatal_error_message">Äã xảy ra lá»—i nghiêm trá»ng. Kiểm tra nhật ký để biết thêm chi tiết.\nNếu chạy tiếp giả lập có thể bị crash và lá»—i.</string>
247 <string name="performance_warning">Tắt cài đặt này sẽ làm giảm đáng kể hiệu suất giả lập! Äể có trải nghiệm tốt nhất, bạn nên bật cài đặt này.</string>
248 <!-- Region Names -->
249 <string name="region_japan">Nhật Bản</string>
250 <string name="region_usa">Hoa Kỳ</string>
251 <string name="region_europe">Châu Âu</string>
252 <string name="region_australia">Úc</string>
253 <string name="region_china">Trung Quốc</string>
254 <string name="region_korea">Hàn Quốc</string>
255 <string name="region_taiwan">Äài Loan</string>
256
257 <string name="memory_gigabyte">GB</string>
258 <!-- Renderer APIs -->
259 <string name="renderer_vulkan">Vulkan</string>
260 <string name="renderer_none">Không có</string>
261
262 <!-- Renderer Accuracy -->
263 <string name="renderer_accuracy_normal">Bình thưá»ng</string>
264 <string name="renderer_accuracy_high">Cao</string>
265 <string name="renderer_accuracy_extreme">Cực đại (Chậm)</string>
266
267 <!-- Resolutions -->
268 <string name="resolution_half">0.5X (360p/540p)</string>
269 <string name="resolution_three_quarter">0.75X (540p/810p)</string>
270 <string name="resolution_one">1X (720p/1080p)</string>
271 <string name="resolution_two">2X (1440p/2160p) (Chậm)</string>
272 <string name="resolution_three">3X (2160p/3240p) (Chậm)</string>
273 <string name="resolution_four">4X (2880p/4320p) (Chậm)</string>
274
275 <!-- Renderer VSync -->
276 <string name="renderer_vsync_immediate">Immediate (Tắt)</string>
277 <string name="renderer_vsync_mailbox">Mailbox</string>
278 <string name="renderer_vsync_fifo">FIFO (Bật)</string>
279 <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
280
281 <!-- Scaling Filters -->
282 <string name="scaling_filter_nearest_neighbor">Nearest Neighbor</string>
283 <string name="scaling_filter_bilinear">Bilinear</string>
284 <string name="scaling_filter_bicubic">Bicubic</string>
285 <string name="scaling_filter_gaussian">Gaussian</string>
286 <string name="scaling_filter_scale_force">ScaleForce</string>
287 <string name="scaling_filter_fsr">AMD FidelityFXâ„¢ Super Resolution</string>
288
289 <!-- Anti-Aliasing -->
290 <string name="anti_aliasing_none">Không có</string>
291 <string name="anti_aliasing_fxaa">FXAA</string>
292 <string name="anti_aliasing_smaa">SMAA</string>
293
294 <string name="screen_layout_auto">Tự động</string>
295
296 <!-- Aspect Ratios -->
297 <string name="ratio_default">Mặc định (16:9)</string>
298 <string name="ratio_force_four_three">Dùng 4:3</string>
299 <string name="ratio_force_twenty_one_nine">Dùng 21:9</string>
300 <string name="ratio_force_sixteen_ten">Dùng 16:10</string>
301 <string name="ratio_stretch">Mở rộng đến cửa sổ</string>
302
303 <!-- CPU Accuracy -->
304 <string name="cpu_accuracy_accurate">Chính xác</string>
305 <string name="cpu_accuracy_unsafe">Không an toàn</string>
306 <string name="cpu_accuracy_paranoid">Paranoid (Chậm)</string>
307
308 <!-- Gamepad Buttons -->
309 <string name="gamepad_d_pad">D-pad</string>
310 <string name="gamepad_left_stick">Cần trái</string>
311 <string name="gamepad_right_stick">Cần phải</string>
312 <string name="gamepad_home">Home</string>
313 <string name="gamepad_screenshot">Ảnh chụp màn hình</string>
314
315 <!-- Disk shader cache -->
316 <string name="preparing_shaders">Äang chuẩn bị shader</string>
317 <string name="building_shaders">Äang đựng shader</string>
318
319 <!-- Theme options -->
320 <string name="change_app_theme">Thay đổi chủ đỠứng dụng</string>
321 <string name="theme_default">Mặc định</string>
322 <string name="theme_material_you">Material You</string>
323
324 <!-- Theme Modes -->
325 <string name="change_theme_mode">Thay đổi chá»§ Ä‘á»</string>
326 <string name="theme_mode_follow_system">Theo hệ thống</string>
327 <string name="theme_mode_light">Sáng</string>
328 <string name="theme_mode_dark">Tối</string>
329
330 <!-- Black backgrounds theme -->
331 <string name="use_black_backgrounds">Ná»n Ä‘en</string>
332 <string name="use_black_backgrounds_description">Khi sá»­ dụng chá»§ đỠtối, hãy áp dụng ná»n Ä‘en.</string>
333
334 <string name="mute">Tắt tiếng</string>
335 <string name="unmute">Bật tiếng</string>
336
337 <!-- Licenses screen strings -->
338 <string name="licenses">Giấy phép</string>
339 <string name="license_fidelityfx_fsr_description">Upscaling chất lượng cao từ AMD</string>
340 </resources>
diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml
index c0e885751..13455564f 100644
--- a/src/android/app/src/main/res/values-zh-rCN/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">此软件å¯ä»¥è¿è¡Œ Nintendo Switch 游æˆï¼Œä½†ä¸åŒ…å«ä»»ä½•游æˆå’Œå¯†é’¥æ–‡ä»¶ã€‚&lt;br /&gt;&lt;br /&gt;在开始å‰ï¼Œè¯·æ‰¾åˆ°æ”¾ç½®äºŽè®¾å¤‡å­˜å‚¨ä¸­çš„ <![CDATA[<b> prod.keys </b>]]> 文件。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">了解更多</a>]]></string> 4 <string name="app_disclaimer">此软件å¯ä»¥è¿è¡Œ Nintendo Switch 游æˆï¼Œä½†ä¸åŒ…å«ä»»ä½•游æˆå’Œå¯†é’¥æ–‡ä»¶ã€‚&lt;br /&gt;&lt;br /&gt;在开始å‰ï¼Œè¯·æ‰¾åˆ°æ”¾ç½®äºŽè®¾å¤‡å­˜å‚¨ä¸­çš„ <![CDATA[<b> prod.keys </b>]]> 文件。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">了解更多</a>]]></string>
5 <string name="emulation_notification_channel_name">正在进行模拟</string> 5 <string name="emulation_notification_channel_name">正在进行模拟</string>
@@ -17,7 +17,7 @@
17 <string name="keys_description">使用下方的按钮æ¥é€‰æ‹©ä½ çš„ &lt;b>prod.keys&lt;/b> 文件。</string> 17 <string name="keys_description">使用下方的按钮æ¥é€‰æ‹©ä½ çš„ &lt;b>prod.keys&lt;/b> 文件。</string>
18 <string name="select_keys">选择密钥文件</string> 18 <string name="select_keys">选择密钥文件</string>
19 <string name="games">游æˆ</string> 19 <string name="games">游æˆ</string>
20 <string name="games_description">使用下方的按钮选择你的 &lt;b>游æˆ&lt;/b> 文件夹。</string> 20 <string name="games_description">使用下方的按钮选择你的&lt;b>游æˆ&lt;/b>文件夹。</string>
21 <string name="done">完æˆ</string> 21 <string name="done">完æˆ</string>
22 <string name="done_description">你完æˆäº†å…¨éƒ¨è®¾ç½®ã€‚\n玩的开心ï¼</string> 22 <string name="done_description">你完æˆäº†å…¨éƒ¨è®¾ç½®ã€‚\n玩的开心ï¼</string>
23 <string name="text_continue">ç»§ç»­</string> 23 <string name="text_continue">ç»§ç»­</string>
@@ -25,6 +25,7 @@
25 <string name="back">上一步</string> 25 <string name="back">上一步</string>
26 <string name="add_games">添加游æˆ</string> 26 <string name="add_games">添加游æˆ</string>
27 <string name="add_games_description">é€‰æ‹©ä½ çš„æ¸¸æˆæ–‡ä»¶å¤¹</string> 27 <string name="add_games_description">é€‰æ‹©ä½ çš„æ¸¸æˆæ–‡ä»¶å¤¹</string>
28 <string name="step_complete">完æˆï¼</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">游æˆ</string> 31 <string name="home_games">游æˆ</string>
@@ -38,6 +39,7 @@
38 <string name="add_games_warning_description">å¦‚æžœæœªé€‰æ‹©æ¸¸æˆæ–‡ä»¶å¤¹ï¼Œæ¸¸æˆå°†ä¸ä¼šæ˜¾ç¤ºåœ¨æ¸¸æˆåˆ—表中。</string> 39 <string name="add_games_warning_description">å¦‚æžœæœªé€‰æ‹©æ¸¸æˆæ–‡ä»¶å¤¹ï¼Œæ¸¸æˆå°†ä¸ä¼šæ˜¾ç¤ºåœ¨æ¸¸æˆåˆ—表中。</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">æœç´¢æ¸¸æˆ</string> 41 <string name="home_search_games">æœç´¢æ¸¸æˆ</string>
42 <string name="search_settings">æœç´¢è®¾ç½®</string>
41 <string name="games_dir_selected">å·²é€‰æ‹©æ¸¸æˆæ–‡ä»¶å¤¹</string> 43 <string name="games_dir_selected">å·²é€‰æ‹©æ¸¸æˆæ–‡ä»¶å¤¹</string>
42 <string name="install_prod_keys">安装 prod.keys 文件</string> 44 <string name="install_prod_keys">安装 prod.keys 文件</string>
43 <string name="install_prod_keys_description">需è¦å¯†é’¥æ–‡ä»¶æ¥è§£å¯†æ¸¸æˆ</string> 45 <string name="install_prod_keys_description">需è¦å¯†é’¥æ–‡ä»¶æ¥è§£å¯†æ¸¸æˆ</string>
@@ -61,12 +63,15 @@
61 <string name="invalid_keys_file">选择的密钥文件无效</string> 63 <string name="invalid_keys_file">选择的密钥文件无效</string>
62 <string name="install_keys_success">密钥文件已æˆåŠŸå®‰è£…</string> 64 <string name="install_keys_success">密钥文件已æˆåŠŸå®‰è£…</string>
63 <string name="reading_keys_failure">读å–加密密钥时出错</string> 65 <string name="reading_keys_failure">读å–加密密钥时出错</string>
66 <string name="install_prod_keys_failure_extension_description">è¯·ç¡®ä¿æ‚¨çš„密钥文件扩展å为 .keys å¹¶é‡è¯•。</string>
67 <string name="install_amiibo_keys_failure_extension_description">è¯·ç¡®ä¿æ‚¨çš„密钥文件扩展å为 .bin å¹¶é‡è¯•。</string>
64 <string name="invalid_keys_error">无效的加密密钥</string> 68 <string name="invalid_keys_error">无效的加密密钥</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">é€‰æ‹©çš„å¯†é’¥æ–‡ä»¶ä¸æ­£ç¡®æˆ–å·²æŸåã€‚è¯·é‡æ–°è½¬å‚¨å¯†é’¥æ–‡ä»¶ã€‚</string> 70 <string name="install_keys_failure_description">é€‰æ‹©çš„å¯†é’¥æ–‡ä»¶ä¸æ­£ç¡®æˆ–å·²æŸåã€‚è¯·é‡æ–°è½¬å‚¨å¯†é’¥æ–‡ä»¶ã€‚</string>
67 <string name="install_gpu_driver">安装 GPU 驱动</string> 71 <string name="install_gpu_driver">安装 GPU 驱动</string>
68 <string name="install_gpu_driver_description">安装替代的驱动程åºä»¥èŽ·å¾—æ›´å¥½çš„æ€§èƒ½å’Œç²¾åº¦</string> 72 <string name="install_gpu_driver_description">安装替代的驱动程åºä»¥èŽ·å¾—æ›´å¥½çš„æ€§èƒ½å’Œç²¾åº¦</string>
69 <string name="advanced_settings">高级选项</string> 73 <string name="advanced_settings">高级选项</string>
74 <string name="advanced_settings_game">高级选项: %1$s</string>
70 <string name="settings_description">更改模拟器设置</string> 75 <string name="settings_description">更改模拟器设置</string>
71 <string name="search_recently_played">最近游玩</string> 76 <string name="search_recently_played">最近游玩</string>
72 <string name="search_recently_added">最近添加</string> 77 <string name="search_recently_added">最近添加</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">ç¬¬ä¸€ä¸ªå­æ–‡ä»¶å¤¹åç§°å¿…é¡»ä¸ºå½“å‰æ¸¸æˆçš„ ID。</string> 91 <string name="save_file_invalid_zip_structure_description">ç¬¬ä¸€ä¸ªå­æ–‡ä»¶å¤¹åç§°å¿…é¡»ä¸ºå½“å‰æ¸¸æˆçš„ ID。</string>
87 <string name="import_saves">导入</string> 92 <string name="import_saves">导入</string>
88 <string name="export_saves">导出</string> 93 <string name="export_saves">导出</string>
94 <string name="install_firmware">安装固件</string>
95 <string name="install_firmware_description">固件文件必须为 zip æ ¼å¼ï¼Œå¯åЍæŸäº›æ¸¸æˆæ—¶å¿…需</string>
96 <string name="firmware_installing">正在安装固件</string>
97 <string name="firmware_installed_success">固件已æˆåŠŸå®‰è£…</string>
98 <string name="firmware_installed_failure">固件安装失败</string>
99 <string name="firmware_installed_failure_description">请确ä¿å›ºä»¶ nca 文件ä½äºŽ zip 压缩包的根目录,然åŽé‡è¯•。</string>
100 <string name="share_log">分享调试日志</string>
101 <string name="share_log_description">分享 yuzu 日志文件以便调试</string>
102 <string name="share_log_missing">未找到日志文件</string>
103 <string name="install_game_content">安装游æˆé™„加内容</string>
104 <string name="install_game_content_description">å®‰è£…æ¸¸æˆæ›´æ–°åŠ DLC</string>
105 <string name="installing_game_content">安装中...</string>
106 <string name="install_game_content_failure">å‘ NAND 安装文件时失败</string>
107 <string name="install_game_content_failure_description">请确ä¿é™„加内容的有效性,并且 prod.keys 密钥文件已安装。</string>
108 <string name="install_game_content_failure_base">为é¿å…产生冲çªï¼Œæ­¤åŠŸèƒ½ä¸èƒ½ç”¨äºŽå®‰è£…æ¸¸æˆæœ¬ä½“。</string>
109 <string name="install_game_content_failure_file_extension">åªæœ‰ NSP 或 XCI æ ¼å¼çš„附加内容å¯ä»¥å®‰è£…ã€‚è¯·ç¡®ä¿æ‚¨çš„æ¸¸æˆé™„加内容是有效的。</string>
110 <string name="install_game_content_failed_count">%1$d 安装出错</string>
111 <string name="install_game_content_success">游æˆé™„加内容已æˆåŠŸå®‰è£…</string>
112 <string name="install_game_content_success_install">%1$d 安装æˆåŠŸ</string>
113 <string name="install_game_content_success_overwrite">%1$d 覆盖安装æˆåŠŸ</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">䏿”¯æŒè‡ªå®šä¹‰é©±åЍ</string>
116 <string name="custom_driver_not_supported_description">æ­¤è®¾å¤‡ä¸æ”¯æŒè‡ªå®šä¹‰é©±åŠ¨ã€‚\n请之åŽå†è®¿é—®æ­¤é¡¹ï¼ŒæŸ¥çœ‹æ˜¯å¦å·²ä¸ºæ­¤è®¾å¤‡æ·»åŠ æ”¯æŒã€‚</string>
117 <string name="manage_yuzu_data">ç®¡ç† yuzu æ•°æ®</string>
118 <string name="manage_yuzu_data_description">导入/导出固件ã€å¯†é’¥ã€ç”¨æˆ·æ•°æ®åŠå…¶ä»–。</string>
119 <string name="share_save_file">分享存档文件</string>
120 <string name="export_save_failed">导出存档文件失败</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia ä¸çœŸå®ž</string> 123 <string name="gaia_is_not_real">Gaia ä¸çœŸå®ž</string>
@@ -94,14 +126,25 @@
94 <string name="contributors">贡献者</string> 126 <string name="contributors">贡献者</string>
95 <string name="contributors_description">使用æ¥è‡ª yuzu 团队的 \u2764 制作</string> 127 <string name="contributors_description">使用æ¥è‡ª yuzu 团队的 \u2764 制作</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">Android 版 yuzu 离ä¸å¼€è¿™äº›é¡¹ç›®çš„æ”¯æŒ</string>
97 <string name="build">构建版本</string> 130 <string name="build">构建版本</string>
131 <string name="user_data">用户数æ®</string>
132 <string name="user_data_description">导入/å¯¼å‡ºåº”ç”¨ç¨‹åºæ‰€æœ‰æ•°æ®ã€‚\n\nå¯¼å…¥ç”¨æˆ·æ•°æ®æ—¶ï¼Œå°†åˆ é™¤å½“剿‰€æœ‰çš„用户数æ®ï¼</string>
133 <string name="exporting_user_data">正在导出用户数æ®...</string>
134 <string name="importing_user_data">正在导入用户数æ®...</string>
135 <string name="import_user_data">导入用户数æ®</string>
136 <string name="invalid_yuzu_backup">无效的 yuzu 备份</string>
137 <string name="user_data_export_success">å¯¼å‡ºç”¨æˆ·æ•°æ®æˆåŠŸ</string>
138 <string name="user_data_import_success">å¯¼å…¥ç”¨æˆ·æ•°æ®æˆåŠŸ</string>
139 <string name="user_data_export_cancelled">已喿¶ˆå¯¼å‡ºæ•°æ®</string>
140 <string name="user_data_import_failed_description">请确ä¿ç”¨æˆ·æ•°æ®æ–‡ä»¶å¤¹ä½äºŽ zip 压缩包的根目录,并在 config/config.ini 路径中包å«é…置文件,然åŽé‡è¯•。</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
101 144
102 <!-- Early access upgrade strings --> 145 <!-- Early access upgrade strings -->
103 <string name="early_access">抢先体验</string> 146 <string name="early_access">抢先体验</string>
104 <string name="get_early_access">å–得抢先体验</string> 147 <string name="get_early_access">èŽ·å–æŠ¢å…ˆä½“éªŒï¼</string>
105 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string> 148 <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
106 <string name="get_early_access_description">æœ€æ–°çš„åŠŸèƒ½ã€æŠ¢å…ˆæ›´æ–°ã€ä»¥åŠæ›´å¤š</string> 149 <string name="get_early_access_description">æœ€æ–°çš„åŠŸèƒ½ã€æŠ¢å…ˆæ›´æ–°ã€ä»¥åŠæ›´å¤š</string>
107 <string name="early_access_benefits">抢先体验的æƒç›Š</string> 150 <string name="early_access_benefits">抢先体验的æƒç›Š</string>
@@ -109,33 +152,34 @@
109 <string name="early_access_updates">抢先更新</string> 152 <string name="early_access_updates">抢先更新</string>
110 <string name="no_manual_installation">无需手动安装</string> 153 <string name="no_manual_installation">无需手动安装</string>
111 <string name="prioritized_support">优先支æŒ</string> 154 <string name="prioritized_support">优先支æŒ</string>
112 <string name="helping_game_preservation">帮助ä¿ç•™æ¸¸æˆ</string> 155 <string name="helping_game_preservation">帮助ä¿ç•™æ¸¸çŽ©åŽ†å²</string>
113 <string name="our_eternal_gratitude">我们真诚的感激</string> 156 <string name="our_eternal_gratitude">我们真诚的感激</string>
114 <string name="are_you_interested">您对此感兴趣å—?</string> 157 <string name="are_you_interested">您对此感兴趣å—?</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">å¯ç”¨è¿è¡Œé€Ÿåº¦é™åˆ¶</string> 160 <string name="frame_limit_enable">è¿è¡Œé€Ÿåº¦é™åˆ¶</string>
118 <string name="frame_limit_enable_description">å¯ç”¨åŽï¼Œæ¨¡æ‹Ÿé€Ÿåº¦å°†é™åˆ¶åœ¨æ­£å¸¸è¿è¡Œé€Ÿåº¦çš„æŒ‡å®šç™¾åˆ†æ¯”。</string> 161 <string name="frame_limit_enable_description">å°†è¿è¡Œé€Ÿåº¦é™åˆ¶ä¸ºæ­£å¸¸é€Ÿåº¦çš„æŒ‡å®šç™¾åˆ†æ¯”。</string>
119 <string name="frame_limit_slider">é™åˆ¶é€Ÿåº¦ç™¾åˆ†æ¯”</string> 162 <string name="frame_limit_slider">é™åˆ¶é€Ÿåº¦ç™¾åˆ†æ¯”</string>
120 <string name="frame_limit_slider_description">指定é™åˆ¶æ¨¡æ‹Ÿé€Ÿåº¦çš„百分比。预设为 100%,此时模拟速度将被é™åˆ¶ä¸ºæ ‡å‡†é€Ÿåº¦ã€‚更高或更低的值将增加或é™ä½Žé€Ÿåº¦é™åˆ¶ä¸Šé™ã€‚</string> 163 <string name="frame_limit_slider_description">指定é™åˆ¶è¿è¡Œé€Ÿåº¦çš„百分比。100% 为正常速度。更高或更低的值将增加或é™ä½Žé€Ÿåº¦é™åˆ¶ä¸Šé™ã€‚</string>
121 <string name="cpu_accuracy">CPU 精度</string> 164 <string name="cpu_accuracy">CPU 精度</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">主机模å¼</string> 168 <string name="use_docked_mode">主机模å¼</string>
125 <string name="use_docked_mode_description">以主机模å¼è¿›è¡Œæ¨¡æ‹Ÿï¼Œç‰ºç‰²æ€§èƒ½å¹¶æé«˜ç”»é¢åˆ†è¾¨çŽ‡ã€‚</string> 169 <string name="use_docked_mode_description">æé«˜åˆ†è¾¨çŽ‡ï¼Œä½†é™ä½Žæ€§èƒ½ã€‚ç¦ç”¨æ­¤é¡¹æ—¶ä½¿ç”¨æŽŒæœºæ¨¡å¼ï¼Œé™ä½Žåˆ†è¾¨çއ并æé«˜æ€§èƒ½ã€‚</string>
126 <string name="emulated_region">模拟区域</string> 170 <string name="emulated_region">模拟区域</string>
127 <string name="emulated_language">模拟语言</string> 171 <string name="emulated_language">模拟语言</string>
128 <string name="select_rtc_date">选择日期</string> 172 <string name="select_rtc_date">选择日期</string>
129 <string name="select_rtc_time">选择时间</string> 173 <string name="select_rtc_time">选择时间</string>
130 <string name="use_custom_rtc">å¯ç”¨è‡ªå®šä¹‰ç³»ç»Ÿæ—¶é’Ÿ</string> 174 <string name="use_custom_rtc">自定义系统时间</string>
131 <string name="use_custom_rtc_description">此选项å…许您设置与目å‰ç³»ç»Ÿæ—¶é—´ç›¸ç‹¬ç«‹çš„自定义系统时钟</string> 175 <string name="use_custom_rtc_description">此选项å…许您设置与目å‰ç³»ç»Ÿæ—¶é—´ç›¸ç‹¬ç«‹çš„自定义系统时钟。</string>
132 <string name="set_custom_rtc">设置自定义系统时钟</string> 176 <string name="set_custom_rtc">设置自定义系统时间</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">精度等级</string> 179 <string name="renderer_accuracy">精度等级</string>
137 <string name="renderer_resolution">分辨率</string> 180 <string name="renderer_resolution">分辨率 (掌机模å¼/主机模å¼)</string>
138 <string name="renderer_vsync">åž‚ç›´åŒæ­¥æ¨¡å¼</string> 181 <string name="renderer_vsync">åž‚ç›´åŒæ­¥æ¨¡å¼</string>
182 <string name="renderer_screen_layout">å±å¹•æ–¹å‘</string>
139 <string name="renderer_aspect_ratio">å±å¹•纵横比</string> 183 <string name="renderer_aspect_ratio">å±å¹•纵横比</string>
140 <string name="renderer_scaling_filter">çª—å£æ»¤é•œ</string> 184 <string name="renderer_scaling_filter">çª—å£æ»¤é•œ</string>
141 <string name="renderer_anti_aliasing">抗锯齿方å¼</string> 185 <string name="renderer_anti_aliasing">抗锯齿方å¼</string>
@@ -143,12 +187,23 @@
143 <string name="renderer_force_max_clock_description">强制 GPU 以最大时钟è¿è¡Œ (ä»è¢«æ¸©æŽ§é™åˆ¶)。</string> 187 <string name="renderer_force_max_clock_description">强制 GPU 以最大时钟è¿è¡Œ (ä»è¢«æ¸©æŽ§é™åˆ¶)。</string>
144 <string name="renderer_asynchronous_shaders">使用异步ç€è‰²å™¨</string> 188 <string name="renderer_asynchronous_shaders">使用异步ç€è‰²å™¨</string>
145 <string name="renderer_asynchronous_shaders_description">异步编译ç€è‰²å™¨ï¼Œå‡å°‘å¡é¡¿ï¼Œä½†å¯èƒ½å¼•入故障。</string> 189 <string name="renderer_asynchronous_shaders_description">异步编译ç€è‰²å™¨ï¼Œå‡å°‘å¡é¡¿ï¼Œä½†å¯èƒ½å¼•入故障。</string>
146 <string name="renderer_debug">å¯ç”¨å›¾å½¢è°ƒè¯•</string> 190 <string name="renderer_reactive_flushing">å¯ç”¨å应性刷新</string>
147 <string name="renderer_debug_description">å¯ç”¨æ—¶ï¼Œå›¾å½¢ API 将进入较慢的调试模å¼ã€‚</string> 191 <string name="renderer_reactive_flushing_description">牺牲性能,æé«˜æŸäº›æ¸¸æˆçš„æ¸²æŸ“精度。</string>
148 <string name="use_disk_shader_cache">使用ç£ç›˜ç€è‰²å™¨ç¼“å­˜</string> 192 <string name="use_disk_shader_cache">ç£ç›˜ç€è‰²å™¨ç¼“å­˜</string>
149 <string name="use_disk_shader_cache_description">将生æˆçš„ç€è‰²å™¨ç¼“存于ç£ç›˜ä¸­å¹¶è¿›è¡Œè¯»å–以å‡å°‘å¡é¡¿ã€‚</string> 193 <string name="use_disk_shader_cache_description">将生æˆçš„ç€è‰²å™¨ç¼“存于ç£ç›˜ä¸­å¹¶è¿›è¡Œè¯»å–,以å‡å°‘å¡é¡¿ã€‚</string>
194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">CPU 调试</string>
198 <string name="cpu_debug_mode_description">å°† CPU 设置为较慢的调试模å¼ã€‚</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
201 <string name="renderer_debug">图形调试</string>
202 <string name="renderer_debug_description">将图形 API 设置为较慢的调试模å¼ã€‚</string>
203 <string name="fastmem">Fastmem</string>
150 204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">输出引擎</string>
152 <string name="audio_volume">音é‡</string> 207 <string name="audio_volume">音é‡</string>
153 <string name="audio_volume_description">指定输出的音é‡ã€‚</string> 208 <string name="audio_volume_description">指定输出的音é‡ã€‚</string>
154 209
@@ -157,7 +212,9 @@
157 <string name="ini_saved">å·²ä¿å­˜è®¾ç½®</string> 212 <string name="ini_saved">å·²ä¿å­˜è®¾ç½®</string>
158 <string name="gameid_saved">å·²ä¿å­˜ %1$s 的设置</string> 213 <string name="gameid_saved">å·²ä¿å­˜ %1$s 的设置</string>
159 <string name="error_saving">ä¿å­˜ %1$s.ini 时出错: %2$s</string> 214 <string name="error_saving">ä¿å­˜ %1$s.ini 时出错: %2$s</string>
215 <string name="unimplemented_menu">未生效èœå•</string>
160 <string name="loading">加载中…</string> 216 <string name="loading">加载中…</string>
217 <string name="shutting_down">正在关闭…</string>
161 <string name="reset_setting_confirmation">您è¦å°†æ­¤è®¾å®šé‡è®¾ä¸ºé»˜è®¤å€¼å—?</string> 218 <string name="reset_setting_confirmation">您è¦å°†æ­¤è®¾å®šé‡è®¾ä¸ºé»˜è®¤å€¼å—?</string>
162 <string name="reset_to_default">æ¢å¤é»˜è®¤</string> 219 <string name="reset_to_default">æ¢å¤é»˜è®¤</string>
163 <string name="reset_all_settings">é‡ç½®æ‰€æœ‰è®¾ç½®é¡¹ï¼Ÿ</string> 220 <string name="reset_all_settings">é‡ç½®æ‰€æœ‰è®¾ç½®é¡¹ï¼Ÿ</string>
@@ -165,6 +222,14 @@
165 <string name="settings_reset">é‡è®¾è®¾ç½®é¡¹</string> 222 <string name="settings_reset">é‡è®¾è®¾ç½®é¡¹</string>
166 <string name="close">关闭</string> 223 <string name="close">关闭</string>
167 <string name="learn_more">了解更多</string> 224 <string name="learn_more">了解更多</string>
225 <string name="auto">自动</string>
226 <string name="submit">æäº¤</string>
227 <string name="string_null">æ— </string>
228 <string name="string_import">导入</string>
229 <string name="export">导出</string>
230 <string name="export_failed">导出失败</string>
231 <string name="import_failed">导入失败</string>
232 <string name="cancelling">å–æ¶ˆä¸­</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">选择 GPU 驱动程åº</string> 235 <string name="select_gpu_driver">选择 GPU 驱动程åº</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">安装</string> 237 <string name="select_gpu_driver_install">安装</string>
173 <string name="select_gpu_driver_default">系统默认</string> 238 <string name="select_gpu_driver_default">系统默认</string>
174 <string name="select_gpu_driver_use_default">使用默认 GPU 驱动程åº</string> 239 <string name="select_gpu_driver_use_default">使用默认 GPU 驱动程åº</string>
240 <string name="select_gpu_driver_error">é€‰æ‹©çš„é©±åŠ¨ç¨‹åºæ— æ•ˆï¼Œå°†ä½¿ç”¨ç³»ç»Ÿé»˜è®¤çš„驱动程åºï¼</string>
175 <string name="system_gpu_driver">系统 GPU 驱动程åº</string> 241 <string name="system_gpu_driver">系统 GPU 驱动程åº</string>
176 <string name="installing_driver">正在安装驱动程åºâ€¦</string> 242 <string name="installing_driver">正在安装驱动程åºâ€¦</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">图形</string> 248 <string name="preferences_graphics">图形</string>
183 <string name="preferences_audio">声音</string> 249 <string name="preferences_audio">声音</string>
184 <string name="preferences_theme">主题和色彩</string> 250 <string name="preferences_theme">主题和色彩</string>
251 <string name="preferences_debug">调试</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">您的 ROM 已加密</string> 254 <string name="loader_error_encrypted">您的 ROM 已加密</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[请å‚考指å—釿–°è½¬å‚¨ä½ çš„<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">游æˆå¡å¸¦</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">已安装的游æˆ</a>。]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[请按照指å—釿–°è½¬å‚¨æ‚¨çš„<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">游æˆå¡å¸¦</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">已安装的游æˆ</a>。]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[è¯·ç¡®ä¿ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 文件已安装,使得游æˆå¯ä»¥è¢«è§£å¯†ã€‚]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[è¯·ç¡®ä¿ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 文件已安装,使得游æˆå¯ä»¥è¢«è§£å¯†ã€‚]]></string>
190 <string name="loader_error_video_core">åˆå§‹åŒ–视频核心时å‘生错误</string> 257 <string name="loader_error_video_core">åˆå§‹åŒ–视频核心时å‘生错误</string>
191 <string name="loader_error_video_core_description">这通常由ä¸å…¼å®¹çš„ GPU 驱动程åºé€ æˆï¼Œå®‰è£…自定义 GPU 驱动程åºå¯èƒ½è§£å†³æ­¤é—®é¢˜ã€‚</string> 258 <string name="loader_error_video_core_description">这通常由ä¸å…¼å®¹çš„ GPU 驱动程åºé€ æˆï¼Œå®‰è£…自定义 GPU 驱动程åºå¯èƒ½è§£å†³æ­¤é—®é¢˜ã€‚</string>
@@ -226,6 +293,9 @@
226 <string name="fatal_error">致命错误</string> 293 <string name="fatal_error">致命错误</string>
227 <string name="fatal_error_message">å‘生致命错误,请查阅日志获å–详细信æ¯ã€‚\n继续模拟å¯èƒ½ä¼šé€ æˆå´©æºƒå’Œé”™è¯¯ã€‚</string> 294 <string name="fatal_error_message">å‘生致命错误,请查阅日志获å–详细信æ¯ã€‚\n继续模拟å¯èƒ½ä¼šé€ æˆå´©æºƒå’Œé”™è¯¯ã€‚</string>
228 <string name="performance_warning">关闭此项会显著é™ä½Žæ¨¡æ‹Ÿæ€§èƒ½ï¼å»ºè®®æ‚¨å°†æ­¤é¡¹ä¿æŒä¸ºå¯ç”¨çжæ€ã€‚</string> 295 <string name="performance_warning">关闭此项会显著é™ä½Žæ¨¡æ‹Ÿæ€§èƒ½ï¼å»ºè®®æ‚¨å°†æ­¤é¡¹ä¿æŒä¸ºå¯ç”¨çжæ€ã€‚</string>
296 <string name="device_memory_inadequate">设备 RAM: %1$s\n推è RAM: %2$s</string>
297 <string name="memory_formatted">%1$s%2$s</string>
298 <string name="no_game_present">当剿²¡æœ‰å¯å¯åŠ¨çš„æ¸¸æˆï¼</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">日本</string> 301 <string name="region_japan">日本</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">韩国</string> 306 <string name="region_korea">韩国</string>
237 <string name="region_taiwan">䏭国尿¹¾</string> 307 <string name="region_taiwan">䏭国尿¹¾</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">KB</string>
312 <string name="memory_megabyte">MB</string>
313 <string name="memory_gigabyte">GB</string>
314 <string name="memory_terabyte">TB</string>
315 <string name="memory_petabyte">PB</string>
316 <string name="memory_exabyte">EB</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 319 <string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
274 <string name="anti_aliasing_fxaa">快速近似抗锯齿</string> 351 <string name="anti_aliasing_fxaa">快速近似抗锯齿</string>
275 <string name="anti_aliasing_smaa">å­åƒç´ å½¢æ€å­¦æŠ—锯齿</string> 352 <string name="anti_aliasing_smaa">å­åƒç´ å½¢æ€å­¦æŠ—锯齿</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">横å‘大å±</string>
356 <string name="screen_layout_portrait">纵å‘å±å¹•</string>
357 <string name="screen_layout_auto">自动</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">默认 (16:9)</string> 360 <string name="ratio_default">默认 (16:9)</string>
279 <string name="ratio_force_four_three">强制 4:3</string> 361 <string name="ratio_force_four_three">强制 4:3</string>
@@ -303,13 +385,27 @@
303 <string name="theme_material_you">Material You</string> 385 <string name="theme_material_you">Material You</string>
304 386
305 <!-- Theme Modes --> 387 <!-- Theme Modes -->
306 <string name="change_theme_mode">主题模å¼</string> 388 <string name="change_theme_mode">更改主题模å¼</string>
307 <string name="theme_mode_follow_system">è·Ÿéšç³»ç»Ÿ</string> 389 <string name="theme_mode_follow_system">è·Ÿéšç³»ç»Ÿ</string>
308 <string name="theme_mode_light">浅色</string> 390 <string name="theme_mode_light">浅色</string>
309 <string name="theme_mode_dark">深色</string> 391 <string name="theme_mode_dark">深色</string>
310 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
311 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
312 <string name="use_black_backgrounds">使用黑色背景</string> 397 <string name="use_black_backgrounds">使用黑色背景</string>
313 <string name="use_black_backgrounds_description">使用深色主题时,套用黑色背景。</string> 398 <string name="use_black_backgrounds_description">使用深色主题时,套用黑色背景。</string>
314 399
315</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">画中画</string>
402 <string name="picture_in_picture_description">模拟器ä½äºŽåŽå°æ—¶æœ€å°åŒ–窗å£</string>
403 <string name="pause">æš‚åœ</string>
404 <string name="play">开始</string>
405 <string name="mute">é™éŸ³</string>
406 <string name="unmute">å–æ¶ˆé™éŸ³</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">许å¯è¯</string>
410 <string name="license_fidelityfx_fsr_description">æ¥è‡ª AMD 的高å“质画质å‡çº§</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml
index 4a21bf893..b8f468c68 100644
--- a/src/android/app/src/main/res/values-zh-rTW/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<resources> 2<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
3 3
4 <string name="app_disclaimer">此軟體å¯ä»¥åŸ·è¡Œ Nintendo Switch ä¸»æ©ŸéŠæˆ²ï¼Œä½†ä¸åŒ…å«ä»»ä½•éŠæˆ²å’Œé‡‘鑰。&lt;br /&gt;&lt;br /&gt;在您開始å‰ï¼Œè«‹æ‰¾åˆ°æ”¾ç½®æ–¼æ‚¨çš„è£ç½®å„²å­˜ç©ºé–“çš„ <![CDATA[<b> prod.keys </b>]]> 檔案。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">深入瞭解</a>]]></string> 4 <string name="app_disclaimer">此軟體å¯ä»¥åŸ·è¡Œ Nintendo Switch ä¸»æ©ŸéŠæˆ²ï¼Œä½†ä¸åŒ…å«ä»»ä½•éŠæˆ²å’Œé‡‘鑰。&lt;br /&gt;&lt;br /&gt;在您開始å‰ï¼Œè«‹æ‰¾åˆ°æ”¾ç½®æ–¼æ‚¨çš„è£ç½®å„²å­˜ç©ºé–“çš„ <![CDATA[<b> prod.keys </b>]]> 檔案。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">深入瞭解</a>]]></string>
5 <string name="emulation_notification_channel_name">模擬進行中</string> 5 <string name="emulation_notification_channel_name">模擬進行中</string>
@@ -25,6 +25,7 @@
25 <string name="back">上一步</string> 25 <string name="back">上一步</string>
26 <string name="add_games">æ–°å¢žéŠæˆ²</string> 26 <string name="add_games">æ–°å¢žéŠæˆ²</string>
27 <string name="add_games_description">é¸å–æ‚¨çš„éŠæˆ²è³‡æ–™å¤¾</string> 27 <string name="add_games_description">é¸å–æ‚¨çš„éŠæˆ²è³‡æ–™å¤¾</string>
28 <string name="step_complete">完æˆï¼</string>
28 29
29 <!-- Home strings --> 30 <!-- Home strings -->
30 <string name="home_games">éŠæˆ²</string> 31 <string name="home_games">éŠæˆ²</string>
@@ -33,11 +34,12 @@
33 <string name="empty_gamelist">找ä¸åˆ°æª”案,或者尚未é¸å–éŠæˆ²ç›®éŒ„。</string> 34 <string name="empty_gamelist">找ä¸åˆ°æª”案,或者尚未é¸å–éŠæˆ²ç›®éŒ„。</string>
34 <string name="search_and_filter_games">æœå°‹ä¸¦ç¯©é¸éŠæˆ²</string> 35 <string name="search_and_filter_games">æœå°‹ä¸¦ç¯©é¸éŠæˆ²</string>
35 <string name="select_games_folder">é¸å–éŠæˆ²è³‡æ–™å¤¾</string> 36 <string name="select_games_folder">é¸å–éŠæˆ²è³‡æ–™å¤¾</string>
36 <string name="select_games_folder_description">一律å…許 yuzu å¡«å…¥éŠæˆ²æ¸…å–®</string> 37 <string name="select_games_folder_description">å…許 yuzu å¡«å…¥éŠæˆ²æ¸…å–®</string>
37 <string name="add_games_warning">è·³éŽé¸å–éŠæˆ²è³‡æ–™å¤¾ï¼Ÿ</string> 38 <string name="add_games_warning">è·³éŽé¸å–éŠæˆ²è³‡æ–™å¤¾ï¼Ÿ</string>
38 <string name="add_games_warning_description">如果資料夾未é¸å–ï¼ŒéŠæˆ²å°‡ä¸æœƒé¡¯ç¤ºåœ¨éŠæˆ²æ¸…單。</string> 39 <string name="add_games_warning_description">如果資料夾未é¸å–ï¼ŒéŠæˆ²å°‡ä¸æœƒé¡¯ç¤ºåœ¨éŠæˆ²æ¸…單。</string>
39 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 40 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
40 <string name="home_search_games">æœå°‹éŠæˆ²</string> 41 <string name="home_search_games">æœå°‹éŠæˆ²</string>
42 <string name="search_settings">æœç´¢è®¾ç½®</string>
41 <string name="games_dir_selected">éŠæˆ²ç›®éŒ„å·²é¸å–</string> 43 <string name="games_dir_selected">éŠæˆ²ç›®éŒ„å·²é¸å–</string>
42 <string name="install_prod_keys">å®‰è£ prod.keys</string> 44 <string name="install_prod_keys">å®‰è£ prod.keys</string>
43 <string name="install_prod_keys_description">需è¦è§£å¯†é›¶å”®éŠæˆ²</string> 45 <string name="install_prod_keys_description">需è¦è§£å¯†é›¶å”®éŠæˆ²</string>
@@ -60,13 +62,16 @@
60 <string name="install_amiibo_keys_description">需è¦åœ¨éŠæˆ²ä¸­ä½¿ç”¨ Amiibo</string> 62 <string name="install_amiibo_keys_description">需è¦åœ¨éŠæˆ²ä¸­ä½¿ç”¨ Amiibo</string>
61 <string name="invalid_keys_file">無效的金鑰檔案已é¸å–</string> 63 <string name="invalid_keys_file">無效的金鑰檔案已é¸å–</string>
62 <string name="install_keys_success">金鑰已æˆåŠŸå®‰è£</string> 64 <string name="install_keys_success">金鑰已æˆåŠŸå®‰è£</string>
63 <string name="reading_keys_failure">讀å–加密金鑰時出ç¾éŒ¯èª¤</string> 65 <string name="reading_keys_failure">讀å–加密金鑰時發生錯誤</string>
66 <string name="install_prod_keys_failure_extension_description">驗證您的金鑰檔案是å¦å…·æœ‰ .keys 副檔å並å†è©¦ä¸€æ¬¡ã€‚</string>
67 <string name="install_amiibo_keys_failure_extension_description">驗證您的金鑰檔案是å¦å…·æœ‰ .bin 副檔å並å†è©¦ä¸€æ¬¡ã€‚</string>
64 <string name="invalid_keys_error">無效的加密金鑰</string> 68 <string name="invalid_keys_error">無效的加密金鑰</string>
65 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 69 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
66 <string name="install_keys_failure_description">é¸å–çš„æª”æ¡ˆä¸æ­£ç¢ºæˆ–å·²ææ¯€ï¼Œè«‹é‡æ–°å‚¾å°æ‚¨çš„金鑰。</string> 70 <string name="install_keys_failure_description">é¸å–çš„æª”æ¡ˆä¸æ­£ç¢ºæˆ–å·²ææ¯€ï¼Œè«‹é‡æ–°å‚¾å°æ‚¨çš„金鑰。</string>
67 <string name="install_gpu_driver">å®‰è£ GPU 驅動程å¼</string> 71 <string name="install_gpu_driver">å®‰è£ GPU 驅動程å¼</string>
68 <string name="install_gpu_driver_description">å®‰è£æ›¿ä»£é©…動程å¼ä»¥å–得潛在的更佳效能或準確度</string> 72 <string name="install_gpu_driver_description">å®‰è£æ›¿ä»£é©…動程å¼ä»¥å–得潛在的更佳效能或準確度</string>
69 <string name="advanced_settings">進階設定</string> 73 <string name="advanced_settings">進階設定</string>
74 <string name="advanced_settings_game">高级选项: %1$s</string>
70 <string name="settings_description">進行模擬器設定</string> 75 <string name="settings_description">進行模擬器設定</string>
71 <string name="search_recently_played">最近éŠçŽ©</string> 76 <string name="search_recently_played">最近éŠçŽ©</string>
72 <string name="search_recently_added">最近新增</string> 77 <string name="search_recently_added">最近新增</string>
@@ -86,6 +91,33 @@
86 <string name="save_file_invalid_zip_structure_description">首個å­è³‡æ–™å¤¾åç¨±å¿…é ˆç‚ºéŠæˆ²æ¨™é¡Œ ID。</string> 91 <string name="save_file_invalid_zip_structure_description">首個å­è³‡æ–™å¤¾åç¨±å¿…é ˆç‚ºéŠæˆ²æ¨™é¡Œ ID。</string>
87 <string name="import_saves">匯入</string> 92 <string name="import_saves">匯入</string>
88 <string name="export_saves">匯出</string> 93 <string name="export_saves">匯出</string>
94 <string name="install_firmware">安è£éŸŒé«”</string>
95 <string name="install_firmware_description">韌體必須為 ZIP å°å­˜æª”ï¼Œå°‡æœƒç”¨æ–¼éƒ¨åˆ†éŠæˆ²çš„啟動</string>
96 <string name="firmware_installing">正在安è£éŸŒé«”</string>
97 <string name="firmware_installed_success">韌體已æˆåŠŸå®‰è£</string>
98 <string name="firmware_installed_failure">韌體安è£å¤±æ•—</string>
99 <string name="firmware_installed_failure_description">请确ä¿å›ºä»¶ nca 文件ä½äºŽ zip 压缩包的根目录,然åŽé‡è¯•。</string>
100 <string name="share_log">分享åµéŒ¯è¨˜éŒ„</string>
101 <string name="share_log_description">分享 yuzu 的記錄檔以便å°ç›¸é—œå•題進行åµéŒ¯</string>
102 <string name="share_log_missing">找ä¸åˆ°è¨˜éŒ„檔</string>
103 <string name="install_game_content">安è£éŠæˆ²å…§å®¹</string>
104 <string name="install_game_content_description">安è£éŠæˆ²æ›´æ–°æˆ– DLC</string>
105 <string name="installing_game_content">安装中...</string>
106 <string name="install_game_content_failure">å‘ NAND 安装文件时失败</string>
107 <string name="install_game_content_failure_description">请确ä¿é™„加内容的有效性,并且 prod.keys 密钥文件已安装。</string>
108 <string name="install_game_content_failure_base">为é¿å…产生冲çªï¼Œæ­¤åŠŸèƒ½ä¸èƒ½ç”¨äºŽå®‰è£…æ¸¸æˆæœ¬ä½“。</string>
109 <string name="install_game_content_failure_file_extension">åªæœ‰ NSP 或 XCI æ ¼å¼çš„附加内容å¯ä»¥å®‰è£…ã€‚è¯·ç¡®ä¿æ‚¨çš„æ¸¸æˆé™„加内容是有效的。</string>
110 <string name="install_game_content_failed_count">%1$d 安装出错</string>
111 <string name="install_game_content_success">游æˆé™„加内容已æˆåŠŸå®‰è£…</string>
112 <string name="install_game_content_success_install">%1$d 安装æˆåŠŸ</string>
113 <string name="install_game_content_success_overwrite">%1$d 覆盖安装æˆåŠŸ</string>
114 <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
115 <string name="custom_driver_not_supported">䏿”¯æŒè‡ªå®šä¹‰é©±åЍ</string>
116 <string name="custom_driver_not_supported_description">æ­¤è®¾å¤‡ä¸æ”¯æŒè‡ªå®šä¹‰é©±åŠ¨ã€‚\n请之åŽå†è®¿é—®æ­¤é¡¹ï¼ŒæŸ¥çœ‹æ˜¯å¦å·²ä¸ºæ­¤è®¾å¤‡æ·»åŠ æ”¯æŒã€‚</string>
117 <string name="manage_yuzu_data">ç®¡ç† yuzu æ•°æ®</string>
118 <string name="manage_yuzu_data_description">导入/导出固件ã€å¯†é’¥ã€ç”¨æˆ·æ•°æ®åŠå…¶ä»–。</string>
119 <string name="share_save_file">分享存档文件</string>
120 <string name="export_save_failed">导出存档文件失败</string>
89 121
90 <!-- About screen strings --> 122 <!-- About screen strings -->
91 <string name="gaia_is_not_real">Gaia ä¸çœŸå¯¦</string> 123 <string name="gaia_is_not_real">Gaia ä¸çœŸå¯¦</string>
@@ -94,7 +126,18 @@
94 <string name="contributors">åƒèˆ‡è€…</string> 126 <string name="contributors">åƒèˆ‡è€…</string>
95 <string name="contributors_description">使用來自 yuzu 團隊的 \u2764 製作</string> 127 <string name="contributors_description">使用來自 yuzu 團隊的 \u2764 製作</string>
96 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 128 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
129 <string name="licenses_description">這些專案使 yuzu Android 版æˆç‚ºå¯èƒ½</string>
97 <string name="build">組建</string> 130 <string name="build">組建</string>
131 <string name="user_data">用户数æ®</string>
132 <string name="user_data_description">导入/å¯¼å‡ºåº”ç”¨ç¨‹åºæ‰€æœ‰æ•°æ®ã€‚\n\nå¯¼å…¥ç”¨æˆ·æ•°æ®æ—¶ï¼Œå°†åˆ é™¤å½“剿‰€æœ‰çš„用户数æ®ï¼</string>
133 <string name="exporting_user_data">正在导出用户数æ®...</string>
134 <string name="importing_user_data">正在导入用户数æ®...</string>
135 <string name="import_user_data">导入用户数æ®</string>
136 <string name="invalid_yuzu_backup">无效的 yuzu 备份</string>
137 <string name="user_data_export_success">å¯¼å‡ºç”¨æˆ·æ•°æ®æˆåŠŸ</string>
138 <string name="user_data_import_success">å¯¼å…¥ç”¨æˆ·æ•°æ®æˆåŠŸ</string>
139 <string name="user_data_export_cancelled">已喿¶ˆå¯¼å‡ºæ•°æ®</string>
140 <string name="user_data_import_failed_description">请确ä¿ç”¨æˆ·æ•°æ®æ–‡ä»¶å¤¹ä½äºŽ zip 压缩包的根目录,并在 config/config.ini 路径中包å«é…置文件,然åŽé‡è¯•。</string>
98 <string name="support_link">https://discord.gg/u77vRWY</string> 141 <string name="support_link">https://discord.gg/u77vRWY</string>
99 <string name="website_link">https://yuzu-emu.org/</string> 142 <string name="website_link">https://yuzu-emu.org/</string>
100 <string name="github_link">https://github.com/yuzu-emu</string> 143 <string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,28 +157,29 @@
114 <string name="are_you_interested">æ‚¨ä»æ„Ÿèˆˆè¶£å—Žï¼Ÿ</string> 157 <string name="are_you_interested">æ‚¨ä»æ„Ÿèˆˆè¶£å—Žï¼Ÿ</string>
115 158
116 <!-- General settings strings --> 159 <!-- General settings strings -->
117 <string name="frame_limit_enable">啟用é™åˆ¶é€Ÿåº¦</string> 160 <string name="frame_limit_enable">é™åˆ¶é€Ÿåº¦</string>
118 <string name="frame_limit_enable_description">若啟用,模擬速度將會é™åˆ¶åœ¨æ¨™æº–速度的指定百分比。</string> 161 <string name="frame_limit_enable_description">將模擬速度é™åˆ¶åœ¨æ¨™æº–速度的指定百分比。</string>
119 <string name="frame_limit_slider">é™åˆ¶é€Ÿåº¦ç™¾åˆ†æ¯”</string> 162 <string name="frame_limit_slider">é™åˆ¶é€Ÿåº¦ç™¾åˆ†æ¯”</string>
120 <string name="frame_limit_slider_description">指定é™åˆ¶æ¨¡æ“¬é€Ÿåº¦çš„百分比。é è¨­ç‚º 100%,模擬速度將被é™åˆ¶ç‚ºæ¨™æº–速度。更高或更低的值將會增加或減少速度é™åˆ¶ã€‚</string> 163 <string name="frame_limit_slider_description">指定é™åˆ¶æ¨¡æ“¬é€Ÿåº¦çš„百分比。100% 為標準速度,更高或更低的值將會增加或減少速度é™åˆ¶ã€‚</string>
121 <string name="cpu_accuracy">CPU 準確度</string> 164 <string name="cpu_accuracy">CPU 準確度</string>
165 <string name="value_with_units">%1$s%2$s</string>
122 166
123 <!-- System settings strings --> 167 <!-- System settings strings -->
124 <string name="use_docked_mode">底座模å¼</string> 168 <string name="use_docked_mode">底座模å¼</string>
125 <string name="use_docked_mode_description">ä»¥åº•åº§æ¨¡å¼æ¨¡æ“¬ï¼Œä»¥çŠ§ç‰²æ•ˆèƒ½çš„ä»£åƒ¹æé«˜è§£æžåº¦ã€‚</string> 169 <string name="use_docked_mode_description">æé«˜è§£æžåº¦ï¼Œé™ä½Žæ•ˆèƒ½ã€‚åœç”¨å¾Œå°‡æœƒä½¿ç”¨æ‰‹ææ¨¡å¼ï¼Œæœƒé™ä½Žè§£æžåº¦ä¸¦æé«˜æ•ˆèƒ½ã€‚</string>
126 <string name="emulated_region">模擬å€åŸŸ</string> 170 <string name="emulated_region">模擬å€åŸŸ</string>
127 <string name="emulated_language">模擬語言</string> 171 <string name="emulated_language">模擬語言</string>
128 <string name="select_rtc_date">é¸å– RTC 日期</string> 172 <string name="select_rtc_date">é¸å– RTC 日期</string>
129 <string name="select_rtc_time">é¸å– RTC 時間</string> 173 <string name="select_rtc_time">é¸å– RTC 時間</string>
130 <string name="use_custom_rtc">啟用自訂 RTC</string> 174 <string name="use_custom_rtc">自訂 RTC</string>
131 <string name="use_custom_rtc_description">此設定å…許您設定與您的目å‰ç³»çµ±æ™‚間相互ç¨ç«‹çš„è‡ªè¨‚å³æ™‚時é˜</string> 175 <string name="use_custom_rtc_description">å…許您設定與您的目å‰ç³»çµ±æ™‚間相互ç¨ç«‹çš„è‡ªè¨‚å³æ™‚時é˜ã€‚</string>
132 <string name="set_custom_rtc">設定自訂 RTC</string> 176 <string name="set_custom_rtc">設定自訂 RTC</string>
133 177
134 <!-- Graphics settings strings --> 178 <!-- Graphics settings strings -->
135 <string name="renderer_api">API</string>
136 <string name="renderer_accuracy">準確度層級</string> 179 <string name="renderer_accuracy">準確度層級</string>
137 <string name="renderer_resolution">è§£æžåº¦</string> 180 <string name="renderer_resolution">è§£æžåº¦ (手æ/底座)</string>
138 <string name="renderer_vsync">VSync 模å¼</string> 181 <string name="renderer_vsync">VSync 模å¼</string>
182 <string name="renderer_screen_layout">å±å¹•æ–¹å‘</string>
139 <string name="renderer_aspect_ratio">長寬比</string> 183 <string name="renderer_aspect_ratio">長寬比</string>
140 <string name="renderer_scaling_filter">è¦–çª—é©æ‡‰éŽæ¿¾å™¨</string> 184 <string name="renderer_scaling_filter">è¦–çª—é©æ‡‰éŽæ¿¾å™¨</string>
141 <string name="renderer_anti_aliasing">消除鋸齒方法</string> 185 <string name="renderer_anti_aliasing">消除鋸齒方法</string>
@@ -143,12 +187,23 @@
143 <string name="renderer_force_max_clock_description">強制 GPU 以最大å¯èƒ½æ™‚脈執行 (熱溫é™åˆ¶ä»è¢«å¥—用)。</string> 187 <string name="renderer_force_max_clock_description">強制 GPU 以最大å¯èƒ½æ™‚脈執行 (熱溫é™åˆ¶ä»è¢«å¥—用)。</string>
144 <string name="renderer_asynchronous_shaders">使用éžåŒæ­¥è‘—色器</string> 188 <string name="renderer_asynchronous_shaders">使用éžåŒæ­¥è‘—色器</string>
145 <string name="renderer_asynchronous_shaders_description">éžåŒæ­¥ç·¨è­¯è‘—色器,將會減少間斷,但å¯èƒ½æœƒå¼•入故障。</string> 189 <string name="renderer_asynchronous_shaders_description">éžåŒæ­¥ç·¨è­¯è‘—色器,將會減少間斷,但å¯èƒ½æœƒå¼•入故障。</string>
146 <string name="renderer_debug">啟用圖形åµéŒ¯</string> 190 <string name="renderer_reactive_flushing">ä½¿ç”¨é‡æ–°å•Ÿç”¨æŽ’清</string>
147 <string name="renderer_debug_description">æ ¸å–æ™‚,åœå½¢ API 將會進入慢速åµéŒ¯æ¨¡å¼ã€‚</string> 191 <string name="renderer_reactive_flushing_description">犧牲效能,以改å–éƒ¨åˆ†éŠæˆ²çš„轉譯準確度。</string>
148 <string name="use_disk_shader_cache">使用ç£ç¢Ÿè‘—色器快å–</string> 192 <string name="use_disk_shader_cache">ç£ç¢Ÿè‘—色器快å–</string>
149 <string name="use_disk_shader_cache_description">é€éŽå°‡ç”¢ç”Ÿçš„著色器儲存並載入至ç£ç¢Ÿï¼Œæ¸›å°‘中斷。</string> 193 <string name="use_disk_shader_cache_description">é€éŽå°‡ç”¢ç”Ÿçš„著色器儲存並載入至ç£ç¢Ÿï¼Œæ¸›å°‘中斷。</string>
150 194
195 <!-- Debug settings strings -->
196 <string name="cpu">CPU</string>
197 <string name="cpu_debug_mode">CPU 调试</string>
198 <string name="cpu_debug_mode_description">å°† CPU 设置为较慢的调试模å¼ã€‚</string>
199 <string name="gpu">GPU</string>
200 <string name="renderer_api">API</string>
201 <string name="renderer_debug">圖形åµéŒ¯</string>
202 <string name="renderer_debug_description">將圖形 API 設為慢速åµéŒ¯æ¨¡å¼ã€‚</string>
203 <string name="fastmem">Fastmem</string>
204
151 <!-- Audio settings strings --> 205 <!-- Audio settings strings -->
206 <string name="audio_output_engine">输出引擎</string>
152 <string name="audio_volume">音é‡</string> 207 <string name="audio_volume">音é‡</string>
153 <string name="audio_volume_description">指定音訊輸出音é‡ã€‚</string> 208 <string name="audio_volume_description">指定音訊輸出音é‡ã€‚</string>
154 209
@@ -157,7 +212,9 @@
157 <string name="ini_saved">已儲存設定</string> 212 <string name="ini_saved">已儲存設定</string>
158 <string name="gameid_saved">已儲存 %1$s 設定</string> 213 <string name="gameid_saved">已儲存 %1$s 設定</string>
159 <string name="error_saving">儲存 %1$s 時發生錯誤 ini: %2$s</string> 214 <string name="error_saving">儲存 %1$s 時發生錯誤 ini: %2$s</string>
215 <string name="unimplemented_menu">未生效èœå•</string>
160 <string name="loading">正在載入…</string> 216 <string name="loading">正在載入…</string>
217 <string name="shutting_down">正在关闭…</string>
161 <string name="reset_setting_confirmation">è¦å°‡æ­¤è¨­å®šé‡è¨­å›žé è¨­å€¼å—Žï¼Ÿ</string> 218 <string name="reset_setting_confirmation">è¦å°‡æ­¤è¨­å®šé‡è¨­å›žé è¨­å€¼å—Žï¼Ÿ</string>
162 <string name="reset_to_default">é‡è¨­ç‚ºé è¨­å€¼</string> 219 <string name="reset_to_default">é‡è¨­ç‚ºé è¨­å€¼</string>
163 <string name="reset_all_settings">é‡è¨­æ‰€æœ‰è¨­å®šï¼Ÿ</string> 220 <string name="reset_all_settings">é‡è¨­æ‰€æœ‰è¨­å®šï¼Ÿ</string>
@@ -165,6 +222,14 @@
165 <string name="settings_reset">設定已é‡è¨­</string> 222 <string name="settings_reset">設定已é‡è¨­</string>
166 <string name="close">關閉</string> 223 <string name="close">關閉</string>
167 <string name="learn_more">深入瞭解</string> 224 <string name="learn_more">深入瞭解</string>
225 <string name="auto">自動</string>
226 <string name="submit">æäº¤</string>
227 <string name="string_null">ç„¡</string>
228 <string name="string_import">匯入</string>
229 <string name="export">匯出</string>
230 <string name="export_failed">导出失败</string>
231 <string name="import_failed">导入失败</string>
232 <string name="cancelling">å–æ¶ˆä¸­</string>
168 233
169 <!-- GPU driver installation --> 234 <!-- GPU driver installation -->
170 <string name="select_gpu_driver">é¸å– GPU 驅動程å¼</string> 235 <string name="select_gpu_driver">é¸å– GPU 驅動程å¼</string>
@@ -172,6 +237,7 @@
172 <string name="select_gpu_driver_install">安è£</string> 237 <string name="select_gpu_driver_install">安è£</string>
173 <string name="select_gpu_driver_default">é è¨­</string> 238 <string name="select_gpu_driver_default">é è¨­</string>
174 <string name="select_gpu_driver_use_default">使用é è¨­ GPU 驅動程å¼</string> 239 <string name="select_gpu_driver_use_default">使用é è¨­ GPU 驅動程å¼</string>
240 <string name="select_gpu_driver_error">é¸å–的驅動程å¼ç„¡æ•ˆï¼Œå°‡ä½¿ç”¨ç³»çµ±é è¨­é©…動程å¼ï¼</string>
175 <string name="system_gpu_driver">系統 GPU 驅動程å¼</string> 241 <string name="system_gpu_driver">系統 GPU 驅動程å¼</string>
176 <string name="installing_driver">正在安è£é©…動程å¼â€¦</string> 242 <string name="installing_driver">正在安è£é©…動程å¼â€¦</string>
177 243
@@ -182,10 +248,11 @@
182 <string name="preferences_graphics">圖形</string> 248 <string name="preferences_graphics">圖形</string>
183 <string name="preferences_audio">音訊</string> 249 <string name="preferences_audio">音訊</string>
184 <string name="preferences_theme">主題和色彩</string> 250 <string name="preferences_theme">主題和色彩</string>
251 <string name="preferences_debug">åµéŒ¯</string>
185 252
186 <!-- ROM loading errors --> 253 <!-- ROM loading errors -->
187 <string name="loader_error_encrypted">您的 ROM 已加密</string> 254 <string name="loader_error_encrypted">您的 ROM 已加密</string>
188 <string name="loader_error_encrypted_roms_description"><![CDATA[è«‹ä¾å¾ªæŒ‡å—釿–°å‚¾å°æ‚¨çš„<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">éŠæˆ²å¡åŒ£</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">å®‰è£æ¨™é¡Œ</a>。]]></string> 255 <string name="loader_error_encrypted_roms_description"><![CDATA[请按照指å—釿–°è½¬å‚¨æ‚¨çš„<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">游æˆå¡å¸¦</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">已安装的游æˆ</a>。]]></string>
189 <string name="loader_error_encrypted_keys_description"><![CDATA[è«‹ç¢ºä¿æ‚¨çš„ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 檔案已安è£ï¼Œè®“éŠæˆ²å¯ä»¥è§£å¯†ã€‚]]></string> 256 <string name="loader_error_encrypted_keys_description"><![CDATA[è«‹ç¢ºä¿æ‚¨çš„ <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 檔案已安è£ï¼Œè®“éŠæˆ²å¯ä»¥è§£å¯†ã€‚]]></string>
190 <string name="loader_error_video_core">åˆå§‹åŒ–視訊核心時發生錯誤</string> 257 <string name="loader_error_video_core">åˆå§‹åŒ–視訊核心時發生錯誤</string>
191 <string name="loader_error_video_core_description">這經常由ä¸ç›¸å®¹çš„ GPU 驅動程å¼é€ æˆï¼Œå®‰è£è‡ªè¨‚ GPU 驅動程å¼å¯èƒ½æœƒè§£æ±ºæ­¤å•題。</string> 258 <string name="loader_error_video_core_description">這經常由ä¸ç›¸å®¹çš„ GPU 驅動程å¼é€ æˆï¼Œå®‰è£è‡ªè¨‚ GPU 驅動程å¼å¯èƒ½æœƒè§£æ±ºæ­¤å•題。</string>
@@ -219,13 +286,16 @@
219 <!-- Errors and warnings --> 286 <!-- Errors and warnings -->
220 <string name="abort_button">中止</string> 287 <string name="abort_button">中止</string>
221 <string name="continue_button">繼續</string> 288 <string name="continue_button">繼續</string>
222 <string name="system_archive_not_found">找ä¸åˆ°ç³»çµ±æª”案</string> 289 <string name="system_archive_not_found">找ä¸åˆ°ç³»çµ±å°å­˜</string>
223 <string name="system_archive_not_found_message">%s éºå¤±ï¼Œè«‹å‚¾å°æ‚¨çš„系統å°å­˜ã€‚\n繼續模擬å¯èƒ½æœƒé€ æˆç•¶æ©Ÿå’ŒéŒ¯èª¤ã€‚</string> 290 <string name="system_archive_not_found_message">%s éºå¤±ï¼Œè«‹å‚¾å°æ‚¨çš„系統å°å­˜ã€‚\n繼續模擬å¯èƒ½æœƒé€ æˆç•¶æ©Ÿå’ŒéŒ¯èª¤ã€‚</string>
224 <string name="system_archive_general">系統å°å­˜</string> 291 <string name="system_archive_general">系統å°å­˜</string>
225 <string name="save_load_error">儲存/載入發生錯誤</string> 292 <string name="save_load_error">儲存/載入發生錯誤</string>
226 <string name="fatal_error">åš´é‡éŒ¯èª¤</string> 293 <string name="fatal_error">åš´é‡éŒ¯èª¤</string>
227 <string name="fatal_error_message">發生嚴é‡éŒ¯èª¤ï¼Œæª¢æŸ¥è¨˜éŒ„以å–得詳細資訊。\n繼續模擬å¯èƒ½æœƒé€ æˆç•¶æ©Ÿå’ŒéŒ¯èª¤ã€‚</string> 294 <string name="fatal_error_message">發生嚴é‡éŒ¯èª¤ï¼Œæª¢æŸ¥è¨˜éŒ„以å–得詳細資訊。\n繼續模擬å¯èƒ½æœƒé€ æˆç•¶æ©Ÿå’ŒéŒ¯èª¤ã€‚</string>
228 <string name="performance_warning">關閉此設定會顯著é™ä½Žæ¨¡æ“¬æ•ˆèƒ½ï¼å¦‚éœ€æœ€ä½³é«”é©—ï¼Œå»ºè­°æ‚¨å°‡æ­¤è¨­å®šä¿æŒç‚ºå•Ÿç”¨ç‹€æ…‹ã€‚</string> 295 <string name="performance_warning">關閉此設定會顯著é™ä½Žæ¨¡æ“¬æ•ˆèƒ½ï¼å¦‚éœ€æœ€ä½³é«”é©—ï¼Œå»ºè­°æ‚¨å°‡æ­¤è¨­å®šä¿æŒç‚ºå•Ÿç”¨ç‹€æ…‹ã€‚</string>
296 <string name="device_memory_inadequate">设备 RAM: %1$s\n推è RAM: %2$s</string>
297 <string name="memory_formatted">%1$s%2$s</string>
298 <string name="no_game_present">当剿²¡æœ‰å¯å¯åŠ¨çš„æ¸¸æˆï¼</string>
229 299
230 <!-- Region Names --> 300 <!-- Region Names -->
231 <string name="region_japan">日本</string> 301 <string name="region_japan">日本</string>
@@ -236,7 +306,14 @@
236 <string name="region_korea">å—韓</string> 306 <string name="region_korea">å—韓</string>
237 <string name="region_taiwan">å°ç£</string> 307 <string name="region_taiwan">å°ç£</string>
238 308
239 <!-- Language Names --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string>
311 <string name="memory_kilobyte">KB</string>
312 <string name="memory_megabyte">MB</string>
313 <string name="memory_gigabyte">英國</string>
314 <string name="memory_terabyte">TB</string>
315 <string name="memory_petabyte">PB</string>
316 <string name="memory_exabyte">EB</string>
240 317
241 <!-- Renderer APIs --> 318 <!-- Renderer APIs -->
242 <string name="renderer_vulkan">Vulkan</string> 319 <string name="renderer_vulkan">Vulkan</string>
@@ -274,14 +351,20 @@
274 <string name="anti_aliasing_fxaa">FXAA</string> 351 <string name="anti_aliasing_fxaa">FXAA</string>
275 <string name="anti_aliasing_smaa">SMAA</string> 352 <string name="anti_aliasing_smaa">SMAA</string>
276 353
354 <!-- Screen Layouts -->
355 <string name="screen_layout_landscape">横å‘大å±</string>
356 <string name="screen_layout_portrait">纵å‘å±å¹•</string>
357 <string name="screen_layout_auto">自動</string>
358
277 <!-- Aspect Ratios --> 359 <!-- Aspect Ratios -->
278 <string name="ratio_default">é è¨­ (16:9)</string> 360 <string name="ratio_default">é è¨­ (16:9)</string>
279 <string name="ratio_force_four_three">強制 4:3</string> 361 <string name="ratio_force_four_three">強制 4:3</string>
280 <string name="ratio_force_twenty_one_nine">強制 21:9</string> 362 <string name="ratio_force_twenty_one_nine">強制 21:9</string>
281 <string name="ratio_force_sixteen_ten">強制 16:10</string> 363 <string name="ratio_force_sixteen_ten">強制 16:10</string>
282 <string name="ratio_stretch">延伸視窗</string> 364 <string name="ratio_stretch">延展視窗</string>
283 365
284 <!-- CPU Accuracy --> 366 <!-- CPU Accuracy -->
367 <string name="cpu_accuracy_accurate">高精度</string>
285 <string name="cpu_accuracy_unsafe">低精度</string> 368 <string name="cpu_accuracy_unsafe">低精度</string>
286 <string name="cpu_accuracy_paranoid">ä¸åˆç† (æ…¢)</string> 369 <string name="cpu_accuracy_paranoid">ä¸åˆç† (æ…¢)</string>
287 370
@@ -307,8 +390,22 @@
307 <string name="theme_mode_light">淺色</string> 390 <string name="theme_mode_light">淺色</string>
308 <string name="theme_mode_dark">深色</string> 391 <string name="theme_mode_dark">深色</string>
309 392
393 <!-- Audio output engines -->
394 <string name="cubeb">cubeb</string>
395
310 <!-- Black backgrounds theme --> 396 <!-- Black backgrounds theme -->
311 <string name="use_black_backgrounds">使用黑色背景</string> 397 <string name="use_black_backgrounds">黑色背景</string>
312 <string name="use_black_backgrounds_description">使用深色主題時,套用黑色背景。</string> 398 <string name="use_black_backgrounds_description">使用深色主題時,套用黑色背景。</string>
313 399
314</resources> 400 <!-- Picture-In-Picture -->
401 <string name="picture_in_picture">画中画</string>
402 <string name="picture_in_picture_description">模拟器ä½äºŽåŽå°æ—¶æœ€å°åŒ–窗å£</string>
403 <string name="pause">æš‚åœ</string>
404 <string name="play">开始</string>
405 <string name="mute">éœéŸ³</string>
406 <string name="unmute">å–æ¶ˆéœéŸ³</string>
407
408 <!-- Licenses screen strings -->
409 <string name="licenses">授權</string>
410 <string name="license_fidelityfx_fsr_description">來自 AMD çš„å‡ç´šåœ–åƒå“質</string>
411 </resources>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 9e4854221..c551a6106 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -72,7 +72,7 @@
72 <string name="invalid_keys_error">Invalid encryption keys</string> 72 <string name="invalid_keys_error">Invalid encryption keys</string>
73 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> 73 <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
74 <string name="install_keys_failure_description">The selected file is incorrect or corrupt. Please redump your keys.</string> 74 <string name="install_keys_failure_description">The selected file is incorrect or corrupt. Please redump your keys.</string>
75 <string name="gpu_driver_manager">GPU Driver Manager</string> 75 <string name="gpu_driver_manager">GPU driver manager</string>
76 <string name="install_gpu_driver">Install GPU driver</string> 76 <string name="install_gpu_driver">Install GPU driver</string>
77 <string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string> 77 <string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
78 <string name="advanced_settings">Advanced settings</string> 78 <string name="advanced_settings">Advanced settings</string>
@@ -124,6 +124,24 @@
124 <string name="share_save_file">Share save file</string> 124 <string name="share_save_file">Share save file</string>
125 <string name="export_save_failed">Failed to export save</string> 125 <string name="export_save_failed">Failed to export save</string>
126 126
127 <!-- Applet launcher strings -->
128 <string name="applets">Applet launcher</string>
129 <string name="applets_description">Launch system applets using installed firmware</string>
130 <string name="applets_error_firmware">Firmware not installed</string>
131 <string name="applets_error_applet">Applet not available</string>
132 <string name="applets_error_description"><![CDATA[Please ensure your <a href="https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys">prod.keys</a> file and <a href="https://yuzu-emu.org/help/quickstart/#dumping-system-firmware">firmware</a> are installed and try again.]]></string>
133 <string name="album_applet">Album</string>
134 <string name="album_applet_description">See images stored in the user screenshots folder with the system photo viewer</string>
135 <string name="mii_edit_applet">Mii edit</string>
136 <string name="mii_edit_applet_description">View and edit Miis with the system editor</string>
137 <string name="cabinet_applet">Cabinet</string>
138 <string name="cabinet_applet_description">Edit and delete data stored on amiibo</string>
139 <string name="cabinet_launcher">Cabinet launcher</string>
140 <string name="cabinet_nickname_and_owner">Nickname and owner settings</string>
141 <string name="cabinet_game_data_eraser">Game data eraser</string>
142 <string name="cabinet_restorer">Restorer</string>
143 <string name="cabinet_formatter">Formatter</string>
144
127 <!-- About screen strings --> 145 <!-- About screen strings -->
128 <string name="gaia_is_not_real">Gaia isn\'t real</string> 146 <string name="gaia_is_not_real">Gaia isn\'t real</string>
129 <string name="copied_to_clipboard">Copied to clipboard</string> 147 <string name="copied_to_clipboard">Copied to clipboard</string>
diff --git a/src/android/app/src/main/res/xml/locales_config.xml b/src/android/app/src/main/res/xml/locales_config.xml
deleted file mode 100644
index 51b88d9dc..000000000
--- a/src/android/app/src/main/res/xml/locales_config.xml
+++ /dev/null
@@ -1,17 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
3 <locale android:name="en" /> <!-- English (default) -->
4 <locale android:name="de" /> <!-- German -->
5 <locale android:name="es" /> <!-- Spanish -->
6 <locale android:name="fr" /> <!-- French -->
7 <locale android:name="it" /> <!-- Italian -->
8 <locale android:name="ja" /> <!-- Japanese -->
9 <locale android:name="nb" /> <!-- Norwegian Bokmal -->
10 <locale android:name="pl" /> <!-- Polish -->
11 <locale android:name="pt-rBR" /> <!-- Portuguese (Brazil) -->
12 <locale android:name="pt-RPT" /> <!-- Portuguese (Portugal) -->
13 <locale android:name="ru" /> <!-- Russian -->
14 <locale android:name="uk" /> <!-- Ukranian -->
15 <locale android:name="zh-rCN" /> <!-- Chinese (China) -->
16 <locale android:name="zh-rTW" /> <!-- Chinese (Taiwan) -->
17</locale-config>
diff --git a/src/audio_core/adsp/apps/opus/opus_decoder.cpp b/src/audio_core/adsp/apps/opus/opus_decoder.cpp
index 2084de128..75f0fb9ad 100644
--- a/src/audio_core/adsp/apps/opus/opus_decoder.cpp
+++ b/src/audio_core/adsp/apps/opus/opus_decoder.cpp
@@ -30,9 +30,9 @@ bool IsValidMultiStreamChannelCount(u32 channel_count) {
30 return channel_count <= OpusStreamCountMax; 30 return channel_count <= OpusStreamCountMax;
31} 31}
32 32
33bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 sterero_stream_count) { 33bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 stereo_stream_count) {
34 return IsValidMultiStreamChannelCount(total_stream_count) && total_stream_count > 0 && 34 return IsValidMultiStreamChannelCount(total_stream_count) && total_stream_count > 0 &&
35 sterero_stream_count > 0 && sterero_stream_count <= total_stream_count; 35 stereo_stream_count >= 0 && stereo_stream_count <= total_stream_count;
36} 36}
37} // namespace 37} // namespace
38 38
diff --git a/src/audio_core/opus/decoder_manager.cpp b/src/audio_core/opus/decoder_manager.cpp
index 4a5382973..fdeccdf50 100644
--- a/src/audio_core/opus/decoder_manager.cpp
+++ b/src/audio_core/opus/decoder_manager.cpp
@@ -24,7 +24,7 @@ bool IsValidSampleRate(u32 sample_rate) {
24} 24}
25 25
26bool IsValidStreamCount(u32 channel_count, u32 total_stream_count, u32 stereo_stream_count) { 26bool IsValidStreamCount(u32 channel_count, u32 total_stream_count, u32 stereo_stream_count) {
27 return total_stream_count > 0 && stereo_stream_count > 0 && 27 return total_stream_count > 0 && static_cast<s32>(stereo_stream_count) >= 0 &&
28 stereo_stream_count <= total_stream_count && 28 stereo_stream_count <= total_stream_count &&
29 total_stream_count + stereo_stream_count <= channel_count; 29 total_stream_count + stereo_stream_count <= channel_count;
30} 30}
diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp
index 88fdba527..f437d7187 100644
--- a/src/common/arm64/native_clock.cpp
+++ b/src/common/arm64/native_clock.cpp
@@ -1,6 +1,9 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#ifdef ANDROID
5#include <sys/system_properties.h>
6#endif
4#include "common/arm64/native_clock.h" 7#include "common/arm64/native_clock.h"
5 8
6namespace Common::Arm64 { 9namespace Common::Arm64 {
@@ -65,7 +68,23 @@ bool NativeClock::IsNative() const {
65 68
66u64 NativeClock::GetHostCNTFRQ() { 69u64 NativeClock::GetHostCNTFRQ() {
67 u64 cntfrq_el0 = 0; 70 u64 cntfrq_el0 = 0;
68 asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); 71 std::string_view board{""};
72#ifdef ANDROID
73 char buffer[PROP_VALUE_MAX];
74 int len{__system_property_get("ro.product.board", buffer)};
75 board = std::string_view(buffer, static_cast<size_t>(len));
76#endif
77 if (board == "s5e9925") { // Exynos 2200
78 cntfrq_el0 = 25600000;
79 } else if (board == "exynos2100") { // Exynos 2100
80 cntfrq_el0 = 26000000;
81 } else if (board == "exynos9810") { // Exynos 9810
82 cntfrq_el0 = 26000000;
83 } else if (board == "s5e8825") { // Exynos 1280
84 cntfrq_el0 = 26000000;
85 } else {
86 asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
87 }
69 return cntfrq_el0; 88 return cntfrq_el0;
70} 89}
71 90
diff --git a/src/common/fs/fs_android.cpp b/src/common/fs/fs_android.cpp
index 298a79bac..1dd826a4a 100644
--- a/src/common/fs/fs_android.cpp
+++ b/src/common/fs/fs_android.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/fs/fs_android.h" 4#include "common/fs/fs_android.h"
5#include "common/string_util.h"
5 6
6namespace Common::FS::Android { 7namespace Common::FS::Android {
7 8
@@ -28,28 +29,35 @@ void RegisterCallbacks(JNIEnv* env, jclass clazz) {
28 env->GetJavaVM(&g_jvm); 29 env->GetJavaVM(&g_jvm);
29 native_library = clazz; 30 native_library = clazz;
30 31
32#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \
33 F(JMethodID, JMethodName, Signature)
31#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \ 34#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
32 F(JMethodID, JMethodName, Signature) 35 F(JMethodID, JMethodName, Signature)
33#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \ 36#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \
34 F(JMethodID, JMethodName, Signature) 37 F(JMethodID, JMethodName, Signature)
35#define F(JMethodID, JMethodName, Signature) \ 38#define F(JMethodID, JMethodName, Signature) \
36 JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature); 39 JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature);
40 ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
37 ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) 41 ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
38 ANDROID_STORAGE_FUNCTIONS(FS) 42 ANDROID_STORAGE_FUNCTIONS(FS)
39#undef F 43#undef F
40#undef FS 44#undef FS
41#undef FR 45#undef FR
46#undef FH
42} 47}
43 48
44void UnRegisterCallbacks() { 49void UnRegisterCallbacks() {
50#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
45#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID) 51#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
46#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) 52#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
47#define F(JMethodID) JMethodID = nullptr; 53#define F(JMethodID) JMethodID = nullptr;
54 ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
48 ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) 55 ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
49 ANDROID_STORAGE_FUNCTIONS(FS) 56 ANDROID_STORAGE_FUNCTIONS(FS)
50#undef F 57#undef F
51#undef FS 58#undef FS
52#undef FR 59#undef FR
60#undef FH
53} 61}
54 62
55bool IsContentUri(const std::string& path) { 63bool IsContentUri(const std::string& path) {
@@ -95,4 +103,29 @@ ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
95#undef F 103#undef F
96#undef FR 104#undef FR
97 105
106#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \
107 F(FunctionName, JMethodID, Caller)
108#define F(FunctionName, JMethodID, Caller) \
109 std::string FunctionName(const std::string& filepath) { \
110 if (JMethodID == nullptr) { \
111 return 0; \
112 } \
113 auto env = GetEnvForThread(); \
114 jstring j_filepath = env->NewStringUTF(filepath.c_str()); \
115 jstring j_return = \
116 static_cast<jstring>(env->Caller(native_library, JMethodID, j_filepath)); \
117 if (!j_return) { \
118 return {}; \
119 } \
120 const jchar* jchars = env->GetStringChars(j_return, nullptr); \
121 const jsize length = env->GetStringLength(j_return); \
122 const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length); \
123 const std::string converted_string = Common::UTF16ToUTF8(string_view); \
124 env->ReleaseStringChars(j_return, jchars); \
125 return converted_string; \
126 }
127ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
128#undef F
129#undef FH
130
98} // namespace Common::FS::Android 131} // namespace Common::FS::Android
diff --git a/src/common/fs/fs_android.h b/src/common/fs/fs_android.h
index b441c2a12..2c9234313 100644
--- a/src/common/fs/fs_android.h
+++ b/src/common/fs/fs_android.h
@@ -17,19 +17,28 @@
17 "(Ljava/lang/String;)Z") \ 17 "(Ljava/lang/String;)Z") \
18 V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z") 18 V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z")
19 19
20#define ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(V) \
21 V(GetParentDirectory, get_parent_directory, CallStaticObjectMethod, "getParentDirectory", \
22 "(Ljava/lang/String;)Ljava/lang/String;") \
23 V(GetFilename, get_filename, CallStaticObjectMethod, "getFilename", \
24 "(Ljava/lang/String;)Ljava/lang/String;")
25
20namespace Common::FS::Android { 26namespace Common::FS::Android {
21 27
22static JavaVM* g_jvm = nullptr; 28static JavaVM* g_jvm = nullptr;
23static jclass native_library = nullptr; 29static jclass native_library = nullptr;
24 30
31#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
25#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID) 32#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
26#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) 33#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
27#define F(JMethodID) static jmethodID JMethodID = nullptr; 34#define F(JMethodID) static jmethodID JMethodID = nullptr;
35ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
28ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) 36ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
29ANDROID_STORAGE_FUNCTIONS(FS) 37ANDROID_STORAGE_FUNCTIONS(FS)
30#undef F 38#undef F
31#undef FS 39#undef FS
32#undef FR 40#undef FR
41#undef FH
33 42
34enum class OpenMode { 43enum class OpenMode {
35 Read, 44 Read,
@@ -62,4 +71,10 @@ ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
62#undef F 71#undef F
63#undef FR 72#undef FR
64 73
74#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(FunctionName)
75#define F(FunctionName) std::string FunctionName(const std::string& filepath);
76ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
77#undef F
78#undef FH
79
65} // namespace Common::FS::Android 80} // namespace Common::FS::Android
diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h
index 441c8af97..bcf447089 100644
--- a/src/common/fs/fs_paths.h
+++ b/src/common/fs/fs_paths.h
@@ -13,6 +13,7 @@
13#define AMIIBO_DIR "amiibo" 13#define AMIIBO_DIR "amiibo"
14#define CACHE_DIR "cache" 14#define CACHE_DIR "cache"
15#define CONFIG_DIR "config" 15#define CONFIG_DIR "config"
16#define CRASH_DUMPS_DIR "crash_dumps"
16#define DUMP_DIR "dump" 17#define DUMP_DIR "dump"
17#define KEYS_DIR "keys" 18#define KEYS_DIR "keys"
18#define LOAD_DIR "load" 19#define LOAD_DIR "load"
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index 0abd81a45..c3a81f9a9 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -119,6 +119,7 @@ public:
119 GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR); 119 GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR);
120 GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache); 120 GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache);
121 GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config); 121 GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config);
122 GenerateYuzuPath(YuzuPath::CrashDumpsDir, yuzu_path / CRASH_DUMPS_DIR);
122 GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR); 123 GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR);
123 GenerateYuzuPath(YuzuPath::KeysDir, yuzu_path / KEYS_DIR); 124 GenerateYuzuPath(YuzuPath::KeysDir, yuzu_path / KEYS_DIR);
124 GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR); 125 GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR);
@@ -400,6 +401,16 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se
400} 401}
401 402
402std::string_view GetParentPath(std::string_view path) { 403std::string_view GetParentPath(std::string_view path) {
404 if (path.empty()) {
405 return path;
406 }
407
408#ifdef ANDROID
409 if (path[0] != '/') {
410 std::string path_string{path};
411 return FS::Android::GetParentDirectory(path_string);
412 }
413#endif
403 const auto name_bck_index = path.rfind('\\'); 414 const auto name_bck_index = path.rfind('\\');
404 const auto name_fwd_index = path.rfind('/'); 415 const auto name_fwd_index = path.rfind('/');
405 std::size_t name_index; 416 std::size_t name_index;
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index 63801c924..2874ea738 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -15,6 +15,7 @@ enum class YuzuPath {
15 AmiiboDir, // Where Amiibo backups are stored. 15 AmiiboDir, // Where Amiibo backups are stored.
16 CacheDir, // Where cached filesystem data is stored. 16 CacheDir, // Where cached filesystem data is stored.
17 ConfigDir, // Where config files are stored. 17 ConfigDir, // Where config files are stored.
18 CrashDumpsDir, // Where crash dumps are stored.
18 DumpDir, // Where dumped data is stored. 19 DumpDir, // Where dumped data is stored.
19 KeysDir, // Where key files are stored. 20 KeysDir, // Where key files are stored.
20 LoadDir, // Where cheat/mod files are stored. 21 LoadDir, // Where cheat/mod files are stored.
diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp
index 7ed7690ee..fa3747782 100644
--- a/src/common/nvidia_flags.cpp
+++ b/src/common/nvidia_flags.cpp
@@ -25,6 +25,7 @@ void ConfigureNvidiaEnvironmentFlags() {
25 25
26 void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path_string).c_str())); 26 void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path_string).c_str()));
27 void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1")); 27 void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1"));
28 void(_putenv("__GL_THREADED_OPTIMIZATIONS=1"));
28#endif 29#endif
29} 30}
30 31
diff --git a/src/common/settings.h b/src/common/settings.h
index 236e33bee..9317075f7 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -505,7 +505,6 @@ struct Values {
505 linkage, false, "use_auto_stub", Category::Debugging, Specialization::Default, false}; 505 linkage, false, "use_auto_stub", Category::Debugging, Specialization::Default, false};
506 Setting<bool> enable_all_controllers{linkage, false, "enable_all_controllers", 506 Setting<bool> enable_all_controllers{linkage, false, "enable_all_controllers",
507 Category::Debugging}; 507 Category::Debugging};
508 Setting<bool> create_crash_dumps{linkage, false, "create_crash_dumps", Category::Debugging};
509 Setting<bool> perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging}; 508 Setting<bool> perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging};
510 509
511 // Miscellaneous 510 // Miscellaneous
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 4c7aba3f5..72c481798 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -14,6 +14,10 @@
14#include <windows.h> 14#include <windows.h>
15#endif 15#endif
16 16
17#ifdef ANDROID
18#include <common/fs/fs_android.h>
19#endif
20
17namespace Common { 21namespace Common {
18 22
19/// Make a string lowercase 23/// Make a string lowercase
@@ -63,6 +67,14 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
63 if (full_path.empty()) 67 if (full_path.empty())
64 return false; 68 return false;
65 69
70#ifdef ANDROID
71 if (full_path[0] != '/') {
72 *_pPath = Common::FS::Android::GetParentDirectory(full_path);
73 *_pFilename = Common::FS::Android::GetFilename(full_path);
74 return true;
75 }
76#endif
77
66 std::size_t dir_end = full_path.find_last_of("/" 78 std::size_t dir_end = full_path.find_last_of("/"
67// windows needs the : included for something like just "C:" to be considered a directory 79// windows needs the : included for something like just "C:" to be considered a directory
68#ifdef _WIN32 80#ifdef _WIN32
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 0c012f094..5e27dde58 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -86,9 +86,9 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
86 86
87 std::map<std::string, Symbols::Symbols> symbols; 87 std::map<std::string, Symbols::Symbols> symbols;
88 for (const auto& module : modules) { 88 for (const auto& module : modules) {
89 symbols.insert_or_assign( 89 symbols.insert_or_assign(module.second,
90 module.second, Symbols::GetSymbols(module.first, system.ApplicationMemory(), 90 Symbols::GetSymbols(module.first, system.ApplicationMemory(),
91 system.ApplicationProcess()->Is64BitProcess())); 91 system.ApplicationProcess()->Is64Bit()));
92 } 92 }
93 93
94 for (auto& entry : out) { 94 for (auto& entry : out) {
diff --git a/src/core/core.cpp b/src/core/core.cpp
index d7e2efbd7..14d6c8c27 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -309,17 +309,10 @@ struct System::Impl {
309 309
310 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); 310 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
311 311
312 // Create a resource limit for the process.
313 const auto physical_memory_size =
314 kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application);
315 auto* resource_limit = Kernel::CreateResourceLimitForProcess(system, physical_memory_size);
316
317 // Create the process. 312 // Create the process.
318 auto main_process = Kernel::KProcess::Create(system.Kernel()); 313 auto main_process = Kernel::KProcess::Create(system.Kernel());
319 ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
320 Kernel::KProcess::ProcessType::Userland, resource_limit)
321 .IsSuccess());
322 Kernel::KProcess::Register(system.Kernel(), main_process); 314 Kernel::KProcess::Register(system.Kernel(), main_process);
315 kernel.AppendNewProcess(main_process);
323 kernel.MakeApplicationProcess(main_process); 316 kernel.MakeApplicationProcess(main_process);
324 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); 317 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
325 if (load_result != Loader::ResultStatus::Success) { 318 if (load_result != Loader::ResultStatus::Success) {
@@ -418,6 +411,7 @@ struct System::Impl {
418 services->KillNVNFlinger(); 411 services->KillNVNFlinger();
419 } 412 }
420 kernel.CloseServices(); 413 kernel.CloseServices();
414 kernel.ShutdownCores();
421 services.reset(); 415 services.reset();
422 service_manager.reset(); 416 service_manager.reset();
423 cheat_engine.reset(); 417 cheat_engine.reset();
@@ -429,7 +423,6 @@ struct System::Impl {
429 gpu_core.reset(); 423 gpu_core.reset();
430 host1x_core.reset(); 424 host1x_core.reset();
431 perf_stats.reset(); 425 perf_stats.reset();
432 kernel.ShutdownCores();
433 cpu_manager.Shutdown(); 426 cpu_manager.Shutdown();
434 debugger.reset(); 427 debugger.reset();
435 kernel.Shutdown(); 428 kernel.Shutdown();
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index a1589fecb..0e270eb50 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -258,20 +258,20 @@ private:
258 Kernel::KScopedSchedulerLock sl{system.Kernel()}; 258 Kernel::KScopedSchedulerLock sl{system.Kernel()};
259 259
260 // Put all threads to sleep on next scheduler round. 260 // Put all threads to sleep on next scheduler round.
261 for (auto* thread : ThreadList()) { 261 for (auto& thread : ThreadList()) {
262 thread->RequestSuspend(Kernel::SuspendType::Debug); 262 thread.RequestSuspend(Kernel::SuspendType::Debug);
263 } 263 }
264 } 264 }
265 265
266 void ResumeEmulation(Kernel::KThread* except = nullptr) { 266 void ResumeEmulation(Kernel::KThread* except = nullptr) {
267 // Wake up all threads. 267 // Wake up all threads.
268 for (auto* thread : ThreadList()) { 268 for (auto& thread : ThreadList()) {
269 if (thread == except) { 269 if (std::addressof(thread) == except) {
270 continue; 270 continue;
271 } 271 }
272 272
273 thread->SetStepState(Kernel::StepState::NotStepping); 273 thread.SetStepState(Kernel::StepState::NotStepping);
274 thread->Resume(Kernel::SuspendType::Debug); 274 thread.Resume(Kernel::SuspendType::Debug);
275 } 275 }
276 } 276 }
277 277
@@ -283,13 +283,17 @@ private:
283 } 283 }
284 284
285 void UpdateActiveThread() { 285 void UpdateActiveThread() {
286 const auto& threads{ThreadList()}; 286 auto& threads{ThreadList()};
287 if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) { 287 for (auto& thread : threads) {
288 state->active_thread = threads.front(); 288 if (std::addressof(thread) == state->active_thread) {
289 // Thread is still alive, no need to update.
290 return;
291 }
289 } 292 }
293 state->active_thread = std::addressof(threads.front());
290 } 294 }
291 295
292 const std::list<Kernel::KThread*>& ThreadList() { 296 Kernel::KProcess::ThreadList& ThreadList() {
293 return system.ApplicationProcess()->GetThreadList(); 297 return system.ApplicationProcess()->GetThreadList();
294 } 298 }
295 299
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 2076aa8a2..6f5f5156b 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -109,7 +109,7 @@ static std::string EscapeXML(std::string_view data) {
109 109
110GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_) 110GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_)
111 : DebuggerFrontend(backend_), system{system_} { 111 : DebuggerFrontend(backend_), system{system_} {
112 if (system.ApplicationProcess()->Is64BitProcess()) { 112 if (system.ApplicationProcess()->Is64Bit()) {
113 arch = std::make_unique<GDBStubA64>(); 113 arch = std::make_unique<GDBStubA64>();
114 } else { 114 } else {
115 arch = std::make_unique<GDBStubA32>(); 115 arch = std::make_unique<GDBStubA32>();
@@ -446,10 +446,10 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
446// See osdbg_thread_local_region.os.horizon.hpp and osdbg_thread_type.os.horizon.hpp 446// See osdbg_thread_local_region.os.horizon.hpp and osdbg_thread_type.os.horizon.hpp
447 447
448static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory, 448static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory,
449 const Kernel::KThread* thread) { 449 const Kernel::KThread& thread) {
450 // Read thread type from TLS 450 // Read thread type from TLS
451 const VAddr tls_thread_type{memory.Read32(thread->GetTlsAddress() + 0x1fc)}; 451 const VAddr tls_thread_type{memory.Read32(thread.GetTlsAddress() + 0x1fc)};
452 const VAddr argument_thread_type{thread->GetArgument()}; 452 const VAddr argument_thread_type{thread.GetArgument()};
453 453
454 if (argument_thread_type && tls_thread_type != argument_thread_type) { 454 if (argument_thread_type && tls_thread_type != argument_thread_type) {
455 // Probably not created by nnsdk, no name available. 455 // Probably not created by nnsdk, no name available.
@@ -477,10 +477,10 @@ static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory&
477} 477}
478 478
479static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory, 479static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory,
480 const Kernel::KThread* thread) { 480 const Kernel::KThread& thread) {
481 // Read thread type from TLS 481 // Read thread type from TLS
482 const VAddr tls_thread_type{memory.Read64(thread->GetTlsAddress() + 0x1f8)}; 482 const VAddr tls_thread_type{memory.Read64(thread.GetTlsAddress() + 0x1f8)};
483 const VAddr argument_thread_type{thread->GetArgument()}; 483 const VAddr argument_thread_type{thread.GetArgument()};
484 484
485 if (argument_thread_type && tls_thread_type != argument_thread_type) { 485 if (argument_thread_type && tls_thread_type != argument_thread_type) {
486 // Probably not created by nnsdk, no name available. 486 // Probably not created by nnsdk, no name available.
@@ -508,16 +508,16 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
508} 508}
509 509
510static std::optional<std::string> GetThreadName(Core::System& system, 510static std::optional<std::string> GetThreadName(Core::System& system,
511 const Kernel::KThread* thread) { 511 const Kernel::KThread& thread) {
512 if (system.ApplicationProcess()->Is64BitProcess()) { 512 if (system.ApplicationProcess()->Is64Bit()) {
513 return GetNameFromThreadType64(system.ApplicationMemory(), thread); 513 return GetNameFromThreadType64(system.ApplicationMemory(), thread);
514 } else { 514 } else {
515 return GetNameFromThreadType32(system.ApplicationMemory(), thread); 515 return GetNameFromThreadType32(system.ApplicationMemory(), thread);
516 } 516 }
517} 517}
518 518
519static std::string_view GetThreadWaitReason(const Kernel::KThread* thread) { 519static std::string_view GetThreadWaitReason(const Kernel::KThread& thread) {
520 switch (thread->GetWaitReasonForDebugging()) { 520 switch (thread.GetWaitReasonForDebugging()) {
521 case Kernel::ThreadWaitReasonForDebugging::Sleep: 521 case Kernel::ThreadWaitReasonForDebugging::Sleep:
522 return "Sleep"; 522 return "Sleep";
523 case Kernel::ThreadWaitReasonForDebugging::IPC: 523 case Kernel::ThreadWaitReasonForDebugging::IPC:
@@ -535,8 +535,8 @@ static std::string_view GetThreadWaitReason(const Kernel::KThread* thread) {
535 } 535 }
536} 536}
537 537
538static std::string GetThreadState(const Kernel::KThread* thread) { 538static std::string GetThreadState(const Kernel::KThread& thread) {
539 switch (thread->GetState()) { 539 switch (thread.GetState()) {
540 case Kernel::ThreadState::Initialized: 540 case Kernel::ThreadState::Initialized:
541 return "Initialized"; 541 return "Initialized";
542 case Kernel::ThreadState::Waiting: 542 case Kernel::ThreadState::Waiting:
@@ -604,7 +604,7 @@ void GDBStub::HandleQuery(std::string_view command) {
604 const auto& threads = system.ApplicationProcess()->GetThreadList(); 604 const auto& threads = system.ApplicationProcess()->GetThreadList();
605 std::vector<std::string> thread_ids; 605 std::vector<std::string> thread_ids;
606 for (const auto& thread : threads) { 606 for (const auto& thread : threads) {
607 thread_ids.push_back(fmt::format("{:x}", thread->GetThreadId())); 607 thread_ids.push_back(fmt::format("{:x}", thread.GetThreadId()));
608 } 608 }
609 SendReply(fmt::format("m{}", fmt::join(thread_ids, ","))); 609 SendReply(fmt::format("m{}", fmt::join(thread_ids, ",")));
610 } else if (command.starts_with("sThreadInfo")) { 610 } else if (command.starts_with("sThreadInfo")) {
@@ -616,14 +616,14 @@ void GDBStub::HandleQuery(std::string_view command) {
616 buffer += "<threads>"; 616 buffer += "<threads>";
617 617
618 const auto& threads = system.ApplicationProcess()->GetThreadList(); 618 const auto& threads = system.ApplicationProcess()->GetThreadList();
619 for (const auto* thread : threads) { 619 for (const auto& thread : threads) {
620 auto thread_name{GetThreadName(system, thread)}; 620 auto thread_name{GetThreadName(system, thread)};
621 if (!thread_name) { 621 if (!thread_name) {
622 thread_name = fmt::format("Thread {:d}", thread->GetThreadId()); 622 thread_name = fmt::format("Thread {:d}", thread.GetThreadId());
623 } 623 }
624 624
625 buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="{}">{}</thread>)", 625 buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="{}">{}</thread>)",
626 thread->GetThreadId(), thread->GetActiveCore(), 626 thread.GetThreadId(), thread.GetActiveCore(),
627 EscapeXML(*thread_name), GetThreadState(thread)); 627 EscapeXML(*thread_name), GetThreadState(thread));
628 } 628 }
629 629
@@ -850,10 +850,10 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
850} 850}
851 851
852Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) { 852Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) {
853 const auto& threads{system.ApplicationProcess()->GetThreadList()}; 853 auto& threads{system.ApplicationProcess()->GetThreadList()};
854 for (auto* thread : threads) { 854 for (auto& thread : threads) {
855 if (thread->GetThreadId() == thread_id) { 855 if (thread.GetThreadId() == thread_id) {
856 return thread; 856 return std::addressof(thread);
857 } 857 }
858 } 858 }
859 859
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 8e291ff67..763a44fee 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -104,16 +104,16 @@ Loader::ResultStatus ProgramMetadata::Reload(VirtualFile file) {
104} 104}
105 105
106/*static*/ ProgramMetadata ProgramMetadata::GetDefault() { 106/*static*/ ProgramMetadata ProgramMetadata::GetDefault() {
107 // Allow use of cores 0~3 and thread priorities 1~63. 107 // Allow use of cores 0~3 and thread priorities 16~63.
108 constexpr u32 default_thread_info_capability = 0x30007F7; 108 constexpr u32 default_thread_info_capability = 0x30043F7;
109 109
110 ProgramMetadata result; 110 ProgramMetadata result;
111 111
112 result.LoadManual( 112 result.LoadManual(
113 true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/, 113 true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/,
114 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x00100000 /*main_thread_stack_size*/, 114 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x100000 /*main_thread_stack_size*/,
115 0 /*title_id*/, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, 115 0 /*title_id*/, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, 0 /*system_resource_size*/,
116 0x1FE00000 /*system_resource_size*/, {default_thread_info_capability} /*capabilities*/); 116 {default_thread_info_capability} /*capabilities*/);
117 117
118 return result; 118 return result;
119} 119}
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h
index 9f8e74b13..76ee97d78 100644
--- a/src/core/file_sys/program_metadata.h
+++ b/src/core/file_sys/program_metadata.h
@@ -73,6 +73,9 @@ public:
73 u64 GetFilesystemPermissions() const; 73 u64 GetFilesystemPermissions() const;
74 u32 GetSystemResourceSize() const; 74 u32 GetSystemResourceSize() const;
75 const KernelCapabilityDescriptors& GetKernelCapabilities() const; 75 const KernelCapabilityDescriptors& GetKernelCapabilities() const;
76 const std::array<u8, 0x10>& GetName() const {
77 return npdm_header.application_name;
78 }
76 79
77 void Print() const; 80 void Print() const;
78 81
@@ -164,14 +167,14 @@ private:
164 u32_le unk_size_2; 167 u32_le unk_size_2;
165 }; 168 };
166 169
167 Header npdm_header; 170 Header npdm_header{};
168 AciHeader aci_header; 171 AciHeader aci_header{};
169 AcidHeader acid_header; 172 AcidHeader acid_header{};
170 173
171 FileAccessControl acid_file_access; 174 FileAccessControl acid_file_access{};
172 FileAccessHeader aci_file_access; 175 FileAccessHeader aci_file_access{};
173 176
174 KernelCapabilityDescriptors aci_kernel_capabilities; 177 KernelCapabilityDescriptors aci_kernel_capabilities{};
175}; 178};
176 179
177} // namespace FileSys 180} // namespace FileSys
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 1c580de57..1eb1f439a 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -35,13 +35,14 @@ struct RomFSHeader {
35static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size."); 35static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size.");
36 36
37struct DirectoryEntry { 37struct DirectoryEntry {
38 u32_le parent;
38 u32_le sibling; 39 u32_le sibling;
39 u32_le child_dir; 40 u32_le child_dir;
40 u32_le child_file; 41 u32_le child_file;
41 u32_le hash; 42 u32_le hash;
42 u32_le name_length; 43 u32_le name_length;
43}; 44};
44static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size."); 45static_assert(sizeof(DirectoryEntry) == 0x18, "DirectoryEntry has incorrect size.");
45 46
46struct FileEntry { 47struct FileEntry {
47 u32_le parent; 48 u32_le parent;
@@ -64,25 +65,22 @@ std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offs
64 return {entry, string}; 65 return {entry, string};
65} 66}
66 67
67void ProcessFile(VirtualFile file, std::size_t file_offset, std::size_t data_offset, 68void ProcessFile(const VirtualFile& file, std::size_t file_offset, std::size_t data_offset,
68 u32 this_file_offset, std::shared_ptr<VectorVfsDirectory> parent) { 69 u32 this_file_offset, std::shared_ptr<VectorVfsDirectory>& parent) {
69 while (true) { 70 while (this_file_offset != ROMFS_ENTRY_EMPTY) {
70 auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset); 71 auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
71 72
72 parent->AddFile(std::make_shared<OffsetVfsFile>( 73 parent->AddFile(std::make_shared<OffsetVfsFile>(
73 file, entry.first.size, entry.first.offset + data_offset, entry.second)); 74 file, entry.first.size, entry.first.offset + data_offset, entry.second));
74 75
75 if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
76 break;
77
78 this_file_offset = entry.first.sibling; 76 this_file_offset = entry.first.sibling;
79 } 77 }
80} 78}
81 79
82void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file_offset, 80void ProcessDirectory(const VirtualFile& file, std::size_t dir_offset, std::size_t file_offset,
83 std::size_t data_offset, u32 this_dir_offset, 81 std::size_t data_offset, u32 this_dir_offset,
84 std::shared_ptr<VectorVfsDirectory> parent) { 82 std::shared_ptr<VectorVfsDirectory>& parent) {
85 while (true) { 83 while (this_dir_offset != ROMFS_ENTRY_EMPTY) {
86 auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset); 84 auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
87 auto current = std::make_shared<VectorVfsDirectory>( 85 auto current = std::make_shared<VectorVfsDirectory>(
88 std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, entry.second); 86 std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, entry.second);
@@ -97,14 +95,12 @@ void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file
97 } 95 }
98 96
99 parent->AddDirectory(current); 97 parent->AddDirectory(current);
100 if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
101 break;
102 this_dir_offset = entry.first.sibling; 98 this_dir_offset = entry.first.sibling;
103 } 99 }
104} 100}
105} // Anonymous namespace 101} // Anonymous namespace
106 102
107VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) { 103VirtualDir ExtractRomFS(VirtualFile file) {
108 RomFSHeader header{}; 104 RomFSHeader header{};
109 if (file->ReadObject(&header) != sizeof(RomFSHeader)) 105 if (file->ReadObject(&header) != sizeof(RomFSHeader))
110 return nullptr; 106 return nullptr;
@@ -113,27 +109,17 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
113 return nullptr; 109 return nullptr;
114 110
115 const u64 file_offset = header.file_meta.offset; 111 const u64 file_offset = header.file_meta.offset;
116 const u64 dir_offset = header.directory_meta.offset + 4; 112 const u64 dir_offset = header.directory_meta.offset;
117
118 auto root =
119 std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{},
120 file->GetName(), file->GetContainingDirectory());
121
122 ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root);
123 113
124 VirtualDir out = std::move(root); 114 auto root_container = std::make_shared<VectorVfsDirectory>();
125 115
126 if (type == RomFSExtractionType::SingleDiscard) 116 ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container);
127 return out->GetSubdirectories().front();
128 117
129 while (out->GetSubdirectories().size() == 1 && out->GetFiles().empty()) { 118 if (auto root = root_container->GetSubdirectory(""); root) {
130 if (Common::ToLower(out->GetSubdirectories().front()->GetName()) == "data" && 119 return std::make_shared<CachedVfsDirectory>(std::move(root));
131 type == RomFSExtractionType::Truncated)
132 break;
133 out = out->GetSubdirectories().front();
134 } 120 }
135 121
136 return std::make_shared<CachedVfsDirectory>(std::move(out)); 122 return nullptr;
137} 123}
138 124
139VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { 125VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) {
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h
index 5d7f0c2a8..b75ff1aad 100644
--- a/src/core/file_sys/romfs.h
+++ b/src/core/file_sys/romfs.h
@@ -7,16 +7,9 @@
7 7
8namespace FileSys { 8namespace FileSys {
9 9
10enum class RomFSExtractionType {
11 Full, // Includes data directory
12 Truncated, // Traverses into data directory
13 SingleDiscard, // Traverses into the first subdirectory of root
14};
15
16// Converts a RomFS binary blob to VFS Filesystem 10// Converts a RomFS binary blob to VFS Filesystem
17// Returns nullptr on failure 11// Returns nullptr on failure
18VirtualDir ExtractRomFS(VirtualFile file, 12VirtualDir ExtractRomFS(VirtualFile file);
19 RomFSExtractionType type = RomFSExtractionType::Truncated);
20 13
21// Converts a VFS filesystem into a RomFS binary 14// Converts a VFS filesystem into a RomFS binary
22// Returns nullptr on failure 15// Returns nullptr on failure
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 2af3f06fc..8e2894449 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -1091,30 +1091,30 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
1091 1091
1092 bool is_charging = false; 1092 bool is_charging = false;
1093 bool is_powered = false; 1093 bool is_powered = false;
1094 NpadBatteryLevel battery_level = 0; 1094 NpadBatteryLevel battery_level = NpadBatteryLevel::Empty;
1095 switch (controller.battery_values[index]) { 1095 switch (controller.battery_values[index]) {
1096 case Common::Input::BatteryLevel::Charging: 1096 case Common::Input::BatteryLevel::Charging:
1097 is_charging = true; 1097 is_charging = true;
1098 is_powered = true; 1098 is_powered = true;
1099 battery_level = 6; 1099 battery_level = NpadBatteryLevel::Full;
1100 break; 1100 break;
1101 case Common::Input::BatteryLevel::Medium: 1101 case Common::Input::BatteryLevel::Medium:
1102 battery_level = 6; 1102 battery_level = NpadBatteryLevel::High;
1103 break; 1103 break;
1104 case Common::Input::BatteryLevel::Low: 1104 case Common::Input::BatteryLevel::Low:
1105 battery_level = 4; 1105 battery_level = NpadBatteryLevel::Low;
1106 break; 1106 break;
1107 case Common::Input::BatteryLevel::Critical: 1107 case Common::Input::BatteryLevel::Critical:
1108 battery_level = 2; 1108 battery_level = NpadBatteryLevel::Critical;
1109 break; 1109 break;
1110 case Common::Input::BatteryLevel::Empty: 1110 case Common::Input::BatteryLevel::Empty:
1111 battery_level = 0; 1111 battery_level = NpadBatteryLevel::Empty;
1112 break; 1112 break;
1113 case Common::Input::BatteryLevel::None: 1113 case Common::Input::BatteryLevel::None:
1114 case Common::Input::BatteryLevel::Full: 1114 case Common::Input::BatteryLevel::Full:
1115 default: 1115 default:
1116 is_powered = true; 1116 is_powered = true;
1117 battery_level = 8; 1117 battery_level = NpadBatteryLevel::Full;
1118 break; 1118 break;
1119 } 1119 }
1120 1120
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 00beb40dd..7ba75a50c 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -302,6 +302,15 @@ enum class TouchScreenModeForNx : u8 {
302 Heat2, 302 Heat2,
303}; 303};
304 304
305// This is nn::hid::system::NpadBatteryLevel
306enum class NpadBatteryLevel : u32 {
307 Empty,
308 Critical,
309 Low,
310 High,
311 Full,
312};
313
305// This is nn::hid::NpadStyleTag 314// This is nn::hid::NpadStyleTag
306struct NpadStyleTag { 315struct NpadStyleTag {
307 union { 316 union {
@@ -385,16 +394,12 @@ struct NpadGcTriggerState {
385}; 394};
386static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); 395static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
387 396
388// This is nn::hid::system::NpadBatteryLevel
389using NpadBatteryLevel = u32;
390static_assert(sizeof(NpadBatteryLevel) == 0x4, "NpadBatteryLevel is an invalid size");
391
392// This is nn::hid::system::NpadPowerInfo 397// This is nn::hid::system::NpadPowerInfo
393struct NpadPowerInfo { 398struct NpadPowerInfo {
394 bool is_powered{}; 399 bool is_powered{};
395 bool is_charging{}; 400 bool is_charging{};
396 INSERT_PADDING_BYTES(0x6); 401 INSERT_PADDING_BYTES(0x6);
397 NpadBatteryLevel battery_level{8}; 402 NpadBatteryLevel battery_level{NpadBatteryLevel::Full};
398}; 403};
399static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); 404static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
400 405
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
index 4cfdf4558..59364efa1 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -8,7 +8,11 @@
8 8
9#include "core/hle/kernel/board/nintendo/nx/k_system_control.h" 9#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
10#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h" 10#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h"
11#include "core/hle/kernel/k_memory_manager.h"
12#include "core/hle/kernel/k_page_table.h"
11#include "core/hle/kernel/k_trace.h" 13#include "core/hle/kernel/k_trace.h"
14#include "core/hle/kernel/kernel.h"
15#include "core/hle/kernel/svc_results.h"
12 16
13namespace Kernel::Board::Nintendo::Nx { 17namespace Kernel::Board::Nintendo::Nx {
14 18
@@ -30,6 +34,8 @@ constexpr const std::size_t RequiredNonSecureSystemMemorySize =
30constexpr const std::size_t RequiredNonSecureSystemMemorySizeWithFatal = 34constexpr const std::size_t RequiredNonSecureSystemMemorySizeWithFatal =
31 RequiredNonSecureSystemMemorySize + impl::RequiredNonSecureSystemMemorySizeViFatal; 35 RequiredNonSecureSystemMemorySize + impl::RequiredNonSecureSystemMemorySizeViFatal;
32 36
37constexpr const std::size_t SecureAlignment = 128_KiB;
38
33namespace { 39namespace {
34 40
35using namespace Common::Literals; 41using namespace Common::Literals;
@@ -183,4 +189,57 @@ u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
183 return GenerateUniformRange(min, max, GenerateRandomU64); 189 return GenerateUniformRange(min, max, GenerateRandomU64);
184} 190}
185 191
192size_t KSystemControl::CalculateRequiredSecureMemorySize(size_t size, u32 pool) {
193 if (pool == static_cast<u32>(KMemoryManager::Pool::Applet)) {
194 return 0;
195 } else {
196 // return KSystemControlBase::CalculateRequiredSecureMemorySize(size, pool);
197 return size;
198 }
199}
200
201Result KSystemControl::AllocateSecureMemory(KernelCore& kernel, KVirtualAddress* out, size_t size,
202 u32 pool) {
203 // Applet secure memory is handled separately.
204 UNIMPLEMENTED_IF(pool == static_cast<u32>(KMemoryManager::Pool::Applet));
205
206 // Ensure the size is aligned.
207 const size_t alignment =
208 (pool == static_cast<u32>(KMemoryManager::Pool::System) ? PageSize : SecureAlignment);
209 R_UNLESS(Common::IsAligned(size, alignment), ResultInvalidSize);
210
211 // Allocate the memory.
212 const size_t num_pages = size / PageSize;
213 const KPhysicalAddress paddr = kernel.MemoryManager().AllocateAndOpenContinuous(
214 num_pages, alignment / PageSize,
215 KMemoryManager::EncodeOption(static_cast<KMemoryManager::Pool>(pool),
216 KMemoryManager::Direction::FromFront));
217 R_UNLESS(paddr != 0, ResultOutOfMemory);
218
219 // Ensure we don't leak references to the memory on error.
220 ON_RESULT_FAILURE {
221 kernel.MemoryManager().Close(paddr, num_pages);
222 };
223
224 // We succeeded.
225 *out = KPageTable::GetHeapVirtualAddress(kernel.MemoryLayout(), paddr);
226 R_SUCCEED();
227}
228
229void KSystemControl::FreeSecureMemory(KernelCore& kernel, KVirtualAddress address, size_t size,
230 u32 pool) {
231 // Applet secure memory is handled separately.
232 UNIMPLEMENTED_IF(pool == static_cast<u32>(KMemoryManager::Pool::Applet));
233
234 // Ensure the size is aligned.
235 const size_t alignment =
236 (pool == static_cast<u32>(KMemoryManager::Pool::System) ? PageSize : SecureAlignment);
237 ASSERT(Common::IsAligned(GetInteger(address), alignment));
238 ASSERT(Common::IsAligned(size, alignment));
239
240 // Close the secure region's pages.
241 kernel.MemoryManager().Close(KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), address),
242 size / PageSize);
243}
244
186} // namespace Kernel::Board::Nintendo::Nx 245} // namespace Kernel::Board::Nintendo::Nx
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
index b477e8193..ff1feec70 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
@@ -4,6 +4,11 @@
4#pragma once 4#pragma once
5 5
6#include "core/hle/kernel/k_typed_address.h" 6#include "core/hle/kernel/k_typed_address.h"
7#include "core/hle/result.h"
8
9namespace Kernel {
10class KernelCore;
11}
7 12
8namespace Kernel::Board::Nintendo::Nx { 13namespace Kernel::Board::Nintendo::Nx {
9 14
@@ -25,8 +30,16 @@ public:
25 static std::size_t GetMinimumNonSecureSystemPoolSize(); 30 static std::size_t GetMinimumNonSecureSystemPoolSize();
26 }; 31 };
27 32
33 // Randomness.
28 static u64 GenerateRandomRange(u64 min, u64 max); 34 static u64 GenerateRandomRange(u64 min, u64 max);
29 static u64 GenerateRandomU64(); 35 static u64 GenerateRandomU64();
36
37 // Secure Memory.
38 static size_t CalculateRequiredSecureMemorySize(size_t size, u32 pool);
39 static Result AllocateSecureMemory(KernelCore& kernel, KVirtualAddress* out, size_t size,
40 u32 pool);
41 static void FreeSecureMemory(KernelCore& kernel, KVirtualAddress address, size_t size,
42 u32 pool);
30}; 43};
31 44
32} // namespace Kernel::Board::Nintendo::Nx 45} // namespace Kernel::Board::Nintendo::Nx
diff --git a/src/core/hle/kernel/k_capabilities.h b/src/core/hle/kernel/k_capabilities.h
index de766c811..ebd4eedb1 100644
--- a/src/core/hle/kernel/k_capabilities.h
+++ b/src/core/hle/kernel/k_capabilities.h
@@ -200,8 +200,8 @@ private:
200 200
201 RawCapabilityValue raw; 201 RawCapabilityValue raw;
202 BitField<0, 15, CapabilityType> id; 202 BitField<0, 15, CapabilityType> id;
203 BitField<15, 4, u32> major_version; 203 BitField<15, 4, u32> minor_version;
204 BitField<19, 13, u32> minor_version; 204 BitField<19, 13, u32> major_version;
205 }; 205 };
206 206
207 union HandleTable { 207 union HandleTable {
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index efbac0e6a..7633a51fb 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -107,12 +107,12 @@ KConditionVariable::KConditionVariable(Core::System& system)
107 107
108KConditionVariable::~KConditionVariable() = default; 108KConditionVariable::~KConditionVariable() = default;
109 109
110Result KConditionVariable::SignalToAddress(KProcessAddress addr) { 110Result KConditionVariable::SignalToAddress(KernelCore& kernel, KProcessAddress addr) {
111 KThread* owner_thread = GetCurrentThreadPointer(m_kernel); 111 KThread* owner_thread = GetCurrentThreadPointer(kernel);
112 112
113 // Signal the address. 113 // Signal the address.
114 { 114 {
115 KScopedSchedulerLock sl(m_kernel); 115 KScopedSchedulerLock sl(kernel);
116 116
117 // Remove waiter thread. 117 // Remove waiter thread.
118 bool has_waiters{}; 118 bool has_waiters{};
@@ -133,7 +133,7 @@ Result KConditionVariable::SignalToAddress(KProcessAddress addr) {
133 133
134 // Write the value to userspace. 134 // Write the value to userspace.
135 Result result{ResultSuccess}; 135 Result result{ResultSuccess};
136 if (WriteToUser(m_kernel, addr, std::addressof(next_value))) [[likely]] { 136 if (WriteToUser(kernel, addr, std::addressof(next_value))) [[likely]] {
137 result = ResultSuccess; 137 result = ResultSuccess;
138 } else { 138 } else {
139 result = ResultInvalidCurrentMemory; 139 result = ResultInvalidCurrentMemory;
@@ -148,28 +148,28 @@ Result KConditionVariable::SignalToAddress(KProcessAddress addr) {
148 } 148 }
149} 149}
150 150
151Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u32 value) { 151Result KConditionVariable::WaitForAddress(KernelCore& kernel, Handle handle, KProcessAddress addr,
152 KThread* cur_thread = GetCurrentThreadPointer(m_kernel); 152 u32 value) {
153 ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(m_kernel); 153 KThread* cur_thread = GetCurrentThreadPointer(kernel);
154 ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel);
154 155
155 // Wait for the address. 156 // Wait for the address.
156 KThread* owner_thread{}; 157 KThread* owner_thread{};
157 { 158 {
158 KScopedSchedulerLock sl(m_kernel); 159 KScopedSchedulerLock sl(kernel);
159 160
160 // Check if the thread should terminate. 161 // Check if the thread should terminate.
161 R_UNLESS(!cur_thread->IsTerminationRequested(), ResultTerminationRequested); 162 R_UNLESS(!cur_thread->IsTerminationRequested(), ResultTerminationRequested);
162 163
163 // Read the tag from userspace. 164 // Read the tag from userspace.
164 u32 test_tag{}; 165 u32 test_tag{};
165 R_UNLESS(ReadFromUser(m_kernel, std::addressof(test_tag), addr), 166 R_UNLESS(ReadFromUser(kernel, std::addressof(test_tag), addr), ResultInvalidCurrentMemory);
166 ResultInvalidCurrentMemory);
167 167
168 // If the tag isn't the handle (with wait mask), we're done. 168 // If the tag isn't the handle (with wait mask), we're done.
169 R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask)); 169 R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask));
170 170
171 // Get the lock owner thread. 171 // Get the lock owner thread.
172 owner_thread = GetCurrentProcess(m_kernel) 172 owner_thread = GetCurrentProcess(kernel)
173 .GetHandleTable() 173 .GetHandleTable()
174 .GetObjectWithoutPseudoHandle<KThread>(handle) 174 .GetObjectWithoutPseudoHandle<KThread>(handle)
175 .ReleasePointerUnsafe(); 175 .ReleasePointerUnsafe();
diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h
index 8c2f3ae51..2620c8e39 100644
--- a/src/core/hle/kernel/k_condition_variable.h
+++ b/src/core/hle/kernel/k_condition_variable.h
@@ -24,11 +24,12 @@ public:
24 explicit KConditionVariable(Core::System& system); 24 explicit KConditionVariable(Core::System& system);
25 ~KConditionVariable(); 25 ~KConditionVariable();
26 26
27 // Arbitration 27 // Arbitration.
28 Result SignalToAddress(KProcessAddress addr); 28 static Result SignalToAddress(KernelCore& kernel, KProcessAddress addr);
29 Result WaitForAddress(Handle handle, KProcessAddress addr, u32 value); 29 static Result WaitForAddress(KernelCore& kernel, Handle handle, KProcessAddress addr,
30 u32 value);
30 31
31 // Condition variable 32 // Condition variable.
32 void Signal(u64 cv_key, s32 count); 33 void Signal(u64 cv_key, s32 count);
33 Result Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout); 34 Result Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout);
34 35
diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp
index fe6a20168..22d79569a 100644
--- a/src/core/hle/kernel/k_interrupt_manager.cpp
+++ b/src/core/hle/kernel/k_interrupt_manager.cpp
@@ -22,7 +22,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
22 KScopedSchedulerLock sl{kernel}; 22 KScopedSchedulerLock sl{kernel};
23 23
24 // Pin the current thread. 24 // Pin the current thread.
25 process->PinCurrentThread(core_id); 25 process->PinCurrentThread();
26 26
27 // Set the interrupt flag for the thread. 27 // Set the interrupt flag for the thread.
28 GetCurrentThread(kernel).SetInterruptFlag(); 28 GetCurrentThread(kernel).SetInterruptFlag();
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index 637558e10..cdc5572d8 100644
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -11,6 +11,7 @@
11#include "core/hle/kernel/initial_process.h" 11#include "core/hle/kernel/initial_process.h"
12#include "core/hle/kernel/k_memory_manager.h" 12#include "core/hle/kernel/k_memory_manager.h"
13#include "core/hle/kernel/k_page_group.h" 13#include "core/hle/kernel/k_page_group.h"
14#include "core/hle/kernel/k_page_table.h"
14#include "core/hle/kernel/kernel.h" 15#include "core/hle/kernel/kernel.h"
15#include "core/hle/kernel/svc_results.h" 16#include "core/hle/kernel/svc_results.h"
16 17
@@ -168,11 +169,37 @@ void KMemoryManager::Initialize(KVirtualAddress management_region, size_t manage
168} 169}
169 170
170Result KMemoryManager::InitializeOptimizedMemory(u64 process_id, Pool pool) { 171Result KMemoryManager::InitializeOptimizedMemory(u64 process_id, Pool pool) {
171 UNREACHABLE(); 172 const u32 pool_index = static_cast<u32>(pool);
173
174 // Lock the pool.
175 KScopedLightLock lk(m_pool_locks[pool_index]);
176
177 // Check that we don't already have an optimized process.
178 R_UNLESS(!m_has_optimized_process[pool_index], ResultBusy);
179
180 // Set the optimized process id.
181 m_optimized_process_ids[pool_index] = process_id;
182 m_has_optimized_process[pool_index] = true;
183
184 // Clear the management area for the optimized process.
185 for (auto* manager = this->GetFirstManager(pool, Direction::FromFront); manager != nullptr;
186 manager = this->GetNextManager(manager, Direction::FromFront)) {
187 manager->InitializeOptimizedMemory(m_system.Kernel());
188 }
189
190 R_SUCCEED();
172} 191}
173 192
174void KMemoryManager::FinalizeOptimizedMemory(u64 process_id, Pool pool) { 193void KMemoryManager::FinalizeOptimizedMemory(u64 process_id, Pool pool) {
175 UNREACHABLE(); 194 const u32 pool_index = static_cast<u32>(pool);
195
196 // Lock the pool.
197 KScopedLightLock lk(m_pool_locks[pool_index]);
198
199 // If the process was optimized, clear it.
200 if (m_has_optimized_process[pool_index] && m_optimized_process_ids[pool_index] == process_id) {
201 m_has_optimized_process[pool_index] = false;
202 }
176} 203}
177 204
178KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, 205KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages,
@@ -207,7 +234,7 @@ KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, siz
207 234
208 // Maintain the optimized memory bitmap, if we should. 235 // Maintain the optimized memory bitmap, if we should.
209 if (m_has_optimized_process[static_cast<size_t>(pool)]) { 236 if (m_has_optimized_process[static_cast<size_t>(pool)]) {
210 UNIMPLEMENTED(); 237 chosen_manager->TrackUnoptimizedAllocation(m_system.Kernel(), allocated_block, num_pages);
211 } 238 }
212 239
213 // Open the first reference to the pages. 240 // Open the first reference to the pages.
@@ -255,7 +282,8 @@ Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages,
255 282
256 // Maintain the optimized memory bitmap, if we should. 283 // Maintain the optimized memory bitmap, if we should.
257 if (unoptimized) { 284 if (unoptimized) {
258 UNIMPLEMENTED(); 285 cur_manager->TrackUnoptimizedAllocation(m_system.Kernel(), allocated_block,
286 pages_per_alloc);
259 } 287 }
260 288
261 num_pages -= pages_per_alloc; 289 num_pages -= pages_per_alloc;
@@ -358,8 +386,8 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
358 // Process part or all of the block. 386 // Process part or all of the block.
359 const size_t cur_pages = 387 const size_t cur_pages =
360 std::min(remaining_pages, manager.GetPageOffsetToEnd(cur_address)); 388 std::min(remaining_pages, manager.GetPageOffsetToEnd(cur_address));
361 any_new = 389 any_new = manager.ProcessOptimizedAllocation(m_system.Kernel(), cur_address,
362 manager.ProcessOptimizedAllocation(cur_address, cur_pages, fill_pattern); 390 cur_pages, fill_pattern);
363 391
364 // Advance. 392 // Advance.
365 cur_address += cur_pages * PageSize; 393 cur_address += cur_pages * PageSize;
@@ -382,7 +410,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
382 // Track some or all of the current pages. 410 // Track some or all of the current pages.
383 const size_t cur_pages = 411 const size_t cur_pages =
384 std::min(remaining_pages, manager.GetPageOffsetToEnd(cur_address)); 412 std::min(remaining_pages, manager.GetPageOffsetToEnd(cur_address));
385 manager.TrackOptimizedAllocation(cur_address, cur_pages); 413 manager.TrackOptimizedAllocation(m_system.Kernel(), cur_address, cur_pages);
386 414
387 // Advance. 415 // Advance.
388 cur_address += cur_pages * PageSize; 416 cur_address += cur_pages * PageSize;
@@ -427,17 +455,86 @@ size_t KMemoryManager::Impl::Initialize(KPhysicalAddress address, size_t size,
427 return total_management_size; 455 return total_management_size;
428} 456}
429 457
430void KMemoryManager::Impl::TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages) { 458void KMemoryManager::Impl::InitializeOptimizedMemory(KernelCore& kernel) {
431 UNREACHABLE(); 459 auto optimize_pa =
460 KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
461 auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
462
463 std::memset(optimize_map, 0, CalculateOptimizedProcessOverheadSize(m_heap.GetSize()));
432} 464}
433 465
434void KMemoryManager::Impl::TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages) { 466void KMemoryManager::Impl::TrackUnoptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
435 UNREACHABLE(); 467 size_t num_pages) {
468 auto optimize_pa =
469 KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
470 auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
471
472 // Get the range we're tracking.
473 size_t offset = this->GetPageOffset(block);
474 const size_t last = offset + num_pages - 1;
475
476 // Track.
477 while (offset <= last) {
478 // Mark the page as not being optimized-allocated.
479 optimize_map[offset / Common::BitSize<u64>()] &=
480 ~(u64(1) << (offset % Common::BitSize<u64>()));
481
482 offset++;
483 }
484}
485
486void KMemoryManager::Impl::TrackOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
487 size_t num_pages) {
488 auto optimize_pa =
489 KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
490 auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
491
492 // Get the range we're tracking.
493 size_t offset = this->GetPageOffset(block);
494 const size_t last = offset + num_pages - 1;
495
496 // Track.
497 while (offset <= last) {
498 // Mark the page as being optimized-allocated.
499 optimize_map[offset / Common::BitSize<u64>()] |=
500 (u64(1) << (offset % Common::BitSize<u64>()));
501
502 offset++;
503 }
436} 504}
437 505
438bool KMemoryManager::Impl::ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, 506bool KMemoryManager::Impl::ProcessOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
439 u8 fill_pattern) { 507 size_t num_pages, u8 fill_pattern) {
440 UNREACHABLE(); 508 auto& device_memory = kernel.System().DeviceMemory();
509 auto optimize_pa =
510 KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
511 auto* optimize_map = device_memory.GetPointer<u64>(optimize_pa);
512
513 // We want to return whether any pages were newly allocated.
514 bool any_new = false;
515
516 // Get the range we're processing.
517 size_t offset = this->GetPageOffset(block);
518 const size_t last = offset + num_pages - 1;
519
520 // Process.
521 while (offset <= last) {
522 // Check if the page has been optimized-allocated before.
523 if ((optimize_map[offset / Common::BitSize<u64>()] &
524 (u64(1) << (offset % Common::BitSize<u64>()))) == 0) {
525 // If not, it's new.
526 any_new = true;
527
528 // Fill the page.
529 auto* ptr = device_memory.GetPointer<u8>(m_heap.GetAddress());
530 std::memset(ptr + offset * PageSize, fill_pattern, PageSize);
531 }
532
533 offset++;
534 }
535
536 // Return the number of pages we processed.
537 return any_new;
441} 538}
442 539
443size_t KMemoryManager::Impl::CalculateManagementOverheadSize(size_t region_size) { 540size_t KMemoryManager::Impl::CalculateManagementOverheadSize(size_t region_size) {
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h
index 7e4b41319..c5a487af9 100644
--- a/src/core/hle/kernel/k_memory_manager.h
+++ b/src/core/hle/kernel/k_memory_manager.h
@@ -216,14 +216,14 @@ private:
216 m_heap.SetInitialUsedSize(reserved_size); 216 m_heap.SetInitialUsedSize(reserved_size);
217 } 217 }
218 218
219 void InitializeOptimizedMemory() { 219 void InitializeOptimizedMemory(KernelCore& kernel);
220 UNIMPLEMENTED();
221 }
222 220
223 void TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages); 221 void TrackUnoptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
224 void TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages); 222 size_t num_pages);
223 void TrackOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block, size_t num_pages);
225 224
226 bool ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, u8 fill_pattern); 225 bool ProcessOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
226 size_t num_pages, u8 fill_pattern);
227 227
228 constexpr Pool GetPool() const { 228 constexpr Pool GetPool() const {
229 return m_pool; 229 return m_pool;
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 217ccbae3..1d47bdf6b 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -82,14 +82,14 @@ public:
82 82
83using namespace Common::Literals; 83using namespace Common::Literals;
84 84
85constexpr size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceType as_type) { 85constexpr size_t GetAddressSpaceWidthFromType(Svc::CreateProcessFlag as_type) {
86 switch (as_type) { 86 switch (as_type) {
87 case FileSys::ProgramAddressSpaceType::Is32Bit: 87 case Svc::CreateProcessFlag::AddressSpace32Bit:
88 case FileSys::ProgramAddressSpaceType::Is32BitNoMap: 88 case Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias:
89 return 32; 89 return 32;
90 case FileSys::ProgramAddressSpaceType::Is36Bit: 90 case Svc::CreateProcessFlag::AddressSpace64BitDeprecated:
91 return 36; 91 return 36;
92 case FileSys::ProgramAddressSpaceType::Is39Bit: 92 case Svc::CreateProcessFlag::AddressSpace64Bit:
93 return 39; 93 return 39;
94 default: 94 default:
95 ASSERT(false); 95 ASSERT(false);
@@ -105,7 +105,7 @@ KPageTable::KPageTable(Core::System& system_)
105 105
106KPageTable::~KPageTable() = default; 106KPageTable::~KPageTable() = default;
107 107
108Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, 108Result KPageTable::InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
109 bool enable_das_merge, bool from_back, 109 bool enable_das_merge, bool from_back,
110 KMemoryManager::Pool pool, KProcessAddress code_addr, 110 KMemoryManager::Pool pool, KProcessAddress code_addr,
111 size_t code_size, KSystemResource* system_resource, 111 size_t code_size, KSystemResource* system_resource,
@@ -133,7 +133,7 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
133 ASSERT(code_addr + code_size - 1 <= end - 1); 133 ASSERT(code_addr + code_size - 1 <= end - 1);
134 134
135 // Adjust heap/alias size if we don't have an alias region 135 // Adjust heap/alias size if we don't have an alias region
136 if (as_type == FileSys::ProgramAddressSpaceType::Is32BitNoMap) { 136 if (as_type == Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias) {
137 heap_region_size += alias_region_size; 137 heap_region_size += alias_region_size;
138 alias_region_size = 0; 138 alias_region_size = 0;
139 } 139 }
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 3d64b6fb0..66f16faaf 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -63,7 +63,7 @@ public:
63 explicit KPageTable(Core::System& system_); 63 explicit KPageTable(Core::System& system_);
64 ~KPageTable(); 64 ~KPageTable();
65 65
66 Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, 66 Result InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
67 bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, 67 bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
68 KProcessAddress code_addr, size_t code_size, 68 KProcessAddress code_addr, size_t code_size,
69 KSystemResource* system_resource, KResourceLimit* resource_limit, 69 KSystemResource* system_resource, KResourceLimit* resource_limit,
@@ -400,7 +400,7 @@ public:
400 constexpr size_t GetAliasCodeRegionSize() const { 400 constexpr size_t GetAliasCodeRegionSize() const {
401 return m_alias_code_region_end - m_alias_code_region_start; 401 return m_alias_code_region_end - m_alias_code_region_start;
402 } 402 }
403 size_t GetNormalMemorySize() { 403 size_t GetNormalMemorySize() const {
404 KScopedLightLock lk(m_general_lock); 404 KScopedLightLock lk(m_general_lock);
405 return GetHeapSize() + m_mapped_physical_memory_size; 405 return GetHeapSize() + m_mapped_physical_memory_size;
406 } 406 }
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 7fa34d693..1f4b0755d 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -1,515 +1,598 @@
1// SPDX-FileCopyrightText: 2015 Citra Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
5#include <bitset>
6#include <ctime>
7#include <memory>
8#include <random> 4#include <random>
9#include "common/alignment.h"
10#include "common/assert.h"
11#include "common/logging/log.h"
12#include "common/scope_exit.h" 5#include "common/scope_exit.h"
13#include "common/settings.h" 6#include "common/settings.h"
14#include "core/core.h" 7#include "core/core.h"
15#include "core/file_sys/program_metadata.h"
16#include "core/hle/kernel/code_set.h"
17#include "core/hle/kernel/k_memory_block_manager.h"
18#include "core/hle/kernel/k_page_table.h"
19#include "core/hle/kernel/k_process.h" 8#include "core/hle/kernel/k_process.h"
20#include "core/hle/kernel/k_resource_limit.h"
21#include "core/hle/kernel/k_scheduler.h"
22#include "core/hle/kernel/k_scoped_resource_reservation.h" 9#include "core/hle/kernel/k_scoped_resource_reservation.h"
23#include "core/hle/kernel/k_shared_memory.h" 10#include "core/hle/kernel/k_shared_memory.h"
24#include "core/hle/kernel/k_shared_memory_info.h" 11#include "core/hle/kernel/k_shared_memory_info.h"
25#include "core/hle/kernel/k_thread.h" 12#include "core/hle/kernel/k_thread_local_page.h"
26#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/k_thread_queue.h"
27#include "core/hle/kernel/svc_results.h" 14#include "core/hle/kernel/k_worker_task_manager.h"
28#include "core/memory.h"
29 15
30namespace Kernel { 16namespace Kernel {
31namespace {
32/**
33 * Sets up the primary application thread
34 *
35 * @param system The system instance to create the main thread under.
36 * @param owner_process The parent process for the main thread
37 * @param priority The priority to give the main thread
38 */
39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
40 KProcessAddress stack_top) {
41 const KProcessAddress entry_point = owner_process.GetEntryPoint();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
43
44 KThread* thread = KThread::Create(system.Kernel());
45 SCOPE_EXIT({ thread->Close(); });
46
47 ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority,
48 owner_process.GetIdealCoreId(),
49 std::addressof(owner_process))
50 .IsSuccess());
51
52 // Register 1 must be a handle to the main thread
53 Handle thread_handle{};
54 owner_process.GetHandleTable().Add(std::addressof(thread_handle), thread);
55
56 thread->GetContext32().cpu_registers[0] = 0;
57 thread->GetContext64().cpu_registers[0] = 0;
58 thread->GetContext32().cpu_registers[1] = thread_handle;
59 thread->GetContext64().cpu_registers[1] = thread_handle;
60
61 if (system.DebuggerEnabled()) {
62 thread->RequestSuspend(SuspendType::Debug);
63 }
64 17
65 // Run our thread. 18namespace {
66 void(thread->Run());
67}
68} // Anonymous namespace
69 19
70Result KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name, 20Result TerminateChildren(KernelCore& kernel, KProcess* process,
71 ProcessType type, KResourceLimit* res_limit) { 21 const KThread* thread_to_not_terminate) {
72 auto& kernel = system.Kernel(); 22 // Request that all children threads terminate.
23 {
24 KScopedLightLock proc_lk(process->GetListLock());
25 KScopedSchedulerLock sl(kernel);
26
27 if (thread_to_not_terminate != nullptr &&
28 process->GetPinnedThread(GetCurrentCoreId(kernel)) == thread_to_not_terminate) {
29 // NOTE: Here Nintendo unpins the current thread instead of the thread_to_not_terminate.
30 // This is valid because the only caller which uses non-nullptr as argument uses
31 // GetCurrentThreadPointer(), but it's still notable because it seems incorrect at
32 // first glance.
33 process->UnpinCurrentThread();
34 }
73 35
74 process->name = std::move(process_name); 36 auto& thread_list = process->GetThreadList();
75 process->m_resource_limit = res_limit; 37 for (auto it = thread_list.begin(); it != thread_list.end(); ++it) {
76 process->m_system_resource_address = 0; 38 if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) {
77 process->m_state = State::Created; 39 if (thread->GetState() != ThreadState::Terminated) {
78 process->m_program_id = 0; 40 thread->RequestTerminate();
79 process->m_process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() 41 }
80 : kernel.CreateNewUserProcessID(); 42 }
81 process->m_capabilities.InitializeForMetadatalessProcess(); 43 }
82 process->m_is_initialized = true; 44 }
83 45
84 std::mt19937 rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue() 46 // Wait for all children threads to terminate.
85 : static_cast<u32>(std::time(nullptr))); 47 while (true) {
86 std::uniform_int_distribution<u64> distribution; 48 // Get the next child.
87 std::generate(process->m_random_entropy.begin(), process->m_random_entropy.end(), 49 KThread* cur_child = nullptr;
88 [&] { return distribution(rng); }); 50 {
51 KScopedLightLock proc_lk(process->GetListLock());
52
53 auto& thread_list = process->GetThreadList();
54 for (auto it = thread_list.begin(); it != thread_list.end(); ++it) {
55 if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) {
56 if (thread->GetState() != ThreadState::Terminated) {
57 if (thread->Open()) {
58 cur_child = thread;
59 break;
60 }
61 }
62 }
63 }
64 }
89 65
90 kernel.AppendNewProcess(process); 66 // If we didn't find any non-terminated children, we're done.
67 if (cur_child == nullptr) {
68 break;
69 }
91 70
92 // Clear remaining fields. 71 // Terminate and close the thread.
93 process->m_num_running_threads = 0; 72 SCOPE_EXIT({ cur_child->Close(); });
94 process->m_is_signaled = false;
95 process->m_exception_thread = nullptr;
96 process->m_is_suspended = false;
97 process->m_schedule_count = 0;
98 process->m_is_handle_table_initialized = false;
99 process->m_is_hbl = false;
100 73
101 // Open a reference to the resource limit. 74 if (const Result terminate_result = cur_child->Terminate();
102 process->m_resource_limit->Open(); 75 ResultTerminationRequested == terminate_result) {
76 R_THROW(terminate_result);
77 }
78 }
103 79
104 R_SUCCEED(); 80 R_SUCCEED();
105} 81}
106 82
107void KProcess::DoWorkerTaskImpl() { 83class ThreadQueueImplForKProcessEnterUserException final : public KThreadQueue {
108 UNIMPLEMENTED(); 84private:
109} 85 KThread** m_exception_thread;
110
111KResourceLimit* KProcess::GetResourceLimit() const {
112 return m_resource_limit;
113}
114 86
115void KProcess::IncrementRunningThreadCount() { 87public:
116 ASSERT(m_num_running_threads.load() >= 0); 88 explicit ThreadQueueImplForKProcessEnterUserException(KernelCore& kernel, KThread** t)
117 ++m_num_running_threads; 89 : KThreadQueue(kernel), m_exception_thread(t) {}
118}
119 90
120void KProcess::DecrementRunningThreadCount() { 91 virtual void EndWait(KThread* waiting_thread, Result wait_result) override {
121 ASSERT(m_num_running_threads.load() > 0); 92 // Set the exception thread.
93 *m_exception_thread = waiting_thread;
122 94
123 if (const auto prev = m_num_running_threads--; prev == 1) { 95 // Invoke the base end wait handler.
124 // TODO(bunnei): Process termination to be implemented when multiprocess is supported. 96 KThreadQueue::EndWait(waiting_thread, wait_result);
125 } 97 }
126}
127 98
128u64 KProcess::GetTotalPhysicalMemoryAvailable() { 99 virtual void CancelWait(KThread* waiting_thread, Result wait_result,
129 const u64 capacity{m_resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) + 100 bool cancel_timer_task) override {
130 m_page_table.GetNormalMemorySize() + GetSystemResourceSize() + m_image_size + 101 // Remove the thread as a waiter on its mutex owner.
131 m_main_thread_stack_size}; 102 waiting_thread->GetLockOwner()->RemoveWaiter(waiting_thread);
132 if (const auto pool_size = m_kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); 103
133 capacity != pool_size) { 104 // Invoke the base cancel wait handler.
134 LOG_WARNING(Kernel, "capacity {} != application pool size {}", capacity, pool_size); 105 KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task);
135 }
136 if (capacity < m_memory_usage_capacity) {
137 return capacity;
138 } 106 }
139 return m_memory_usage_capacity; 107};
140}
141 108
142u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() { 109void GenerateRandom(std::span<u64> out_random) {
143 return this->GetTotalPhysicalMemoryAvailable() - this->GetSystemResourceSize(); 110 std::mt19937 rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue()
111 : static_cast<u32>(std::time(nullptr)));
112 std::uniform_int_distribution<u64> distribution;
113 std::generate(out_random.begin(), out_random.end(), [&] { return distribution(rng); });
144} 114}
145 115
146u64 KProcess::GetTotalPhysicalMemoryUsed() { 116} // namespace
147 return m_image_size + m_main_thread_stack_size + m_page_table.GetNormalMemorySize() +
148 this->GetSystemResourceSize();
149}
150 117
151u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() { 118void KProcess::Finalize() {
152 return this->GetTotalPhysicalMemoryUsed() - this->GetSystemResourceSize(); 119 // Delete the process local region.
153} 120 this->DeleteThreadLocalRegion(m_plr_address);
154 121
155bool KProcess::ReleaseUserException(KThread* thread) { 122 // Get the used memory size.
156 KScopedSchedulerLock sl{m_kernel}; 123 const size_t used_memory_size = this->GetUsedNonSystemUserPhysicalMemorySize();
157 124
158 if (m_exception_thread == thread) { 125 // Finalize the page table.
159 m_exception_thread = nullptr; 126 m_page_table.Finalize();
160 127
161 // Remove waiter thread. 128 // Finish using our system resource.
162 bool has_waiters{}; 129 if (m_system_resource) {
163 if (KThread* next = thread->RemoveKernelWaiterByKey( 130 if (m_system_resource->IsSecureResource()) {
164 std::addressof(has_waiters), 131 // Finalize optimized memory. If memory wasn't optimized, this is a no-op.
165 reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread))); 132 m_kernel.MemoryManager().FinalizeOptimizedMemory(this->GetId(), m_memory_pool);
166 next != nullptr) {
167 next->EndWait(ResultSuccess);
168 } 133 }
169 134
170 KScheduler::SetSchedulerUpdateNeeded(m_kernel); 135 m_system_resource->Close();
171 136 m_system_resource = nullptr;
172 return true;
173 } else {
174 return false;
175 } 137 }
176}
177
178void KProcess::PinCurrentThread(s32 core_id) {
179 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
180 138
181 // Get the current thread. 139 // Free all shared memory infos.
182 KThread* cur_thread = 140 {
183 m_kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread(); 141 auto it = m_shared_memory_list.begin();
142 while (it != m_shared_memory_list.end()) {
143 KSharedMemoryInfo* info = std::addressof(*it);
144 KSharedMemory* shmem = info->GetSharedMemory();
184 145
185 // If the thread isn't terminated, pin it. 146 while (!info->Close()) {
186 if (!cur_thread->IsTerminationRequested()) { 147 shmem->Close();
187 // Pin it. 148 }
188 this->PinThread(core_id, cur_thread); 149 shmem->Close();
189 cur_thread->Pin(core_id);
190 150
191 // An update is needed. 151 it = m_shared_memory_list.erase(it);
192 KScheduler::SetSchedulerUpdateNeeded(m_kernel); 152 KSharedMemoryInfo::Free(m_kernel, info);
153 }
193 } 154 }
194}
195 155
196void KProcess::UnpinCurrentThread(s32 core_id) { 156 // Our thread local page list must be empty at this point.
197 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); 157 ASSERT(m_partially_used_tlp_tree.empty());
198 158 ASSERT(m_fully_used_tlp_tree.empty());
199 // Get the current thread.
200 KThread* cur_thread =
201 m_kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread();
202 159
203 // Unpin it. 160 // Release memory to the resource limit.
204 cur_thread->Unpin(); 161 if (m_resource_limit != nullptr) {
205 this->UnpinThread(core_id, cur_thread); 162 ASSERT(used_memory_size >= m_memory_release_hint);
163 m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, used_memory_size,
164 used_memory_size - m_memory_release_hint);
165 m_resource_limit->Close();
166 }
206 167
207 // An update is needed. 168 // Perform inherited finalization.
208 KScheduler::SetSchedulerUpdateNeeded(m_kernel); 169 KSynchronizationObject::Finalize();
209} 170}
210 171
211void KProcess::UnpinThread(KThread* thread) { 172Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit,
212 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); 173 bool is_real) {
213 174 // TODO: remove this special case
214 // Get the thread's core id. 175 if (is_real) {
215 const auto core_id = thread->GetActiveCore(); 176 // Create and clear the process local region.
177 R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address)));
178 this->GetMemory().ZeroBlock(m_plr_address, Svc::ThreadLocalRegionSize);
179 }
216 180
217 // Unpin it. 181 // Copy in the name from parameters.
218 this->UnpinThread(core_id, thread); 182 static_assert(sizeof(params.name) < sizeof(m_name));
219 thread->Unpin(); 183 std::memcpy(m_name.data(), params.name.data(), sizeof(params.name));
184 m_name[sizeof(params.name)] = 0;
185
186 // Set misc fields.
187 m_state = State::Created;
188 m_main_thread_stack_size = 0;
189 m_used_kernel_memory_size = 0;
190 m_ideal_core_id = 0;
191 m_flags = params.flags;
192 m_version = params.version;
193 m_program_id = params.program_id;
194 m_code_address = params.code_address;
195 m_code_size = params.code_num_pages * PageSize;
196 m_is_application = True(params.flags & Svc::CreateProcessFlag::IsApplication);
197
198 // Set thread fields.
199 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
200 m_running_threads[i] = nullptr;
201 m_pinned_threads[i] = nullptr;
202 m_running_thread_idle_counts[i] = 0;
203 m_running_thread_switch_counts[i] = 0;
204 }
220 205
221 // An update is needed. 206 // Set max memory based on address space type.
222 KScheduler::SetSchedulerUpdateNeeded(m_kernel); 207 switch ((params.flags & Svc::CreateProcessFlag::AddressSpaceMask)) {
223} 208 case Svc::CreateProcessFlag::AddressSpace32Bit:
209 case Svc::CreateProcessFlag::AddressSpace64BitDeprecated:
210 case Svc::CreateProcessFlag::AddressSpace64Bit:
211 m_max_process_memory = m_page_table.GetHeapRegionSize();
212 break;
213 case Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias:
214 m_max_process_memory = m_page_table.GetHeapRegionSize() + m_page_table.GetAliasRegionSize();
215 break;
216 default:
217 UNREACHABLE();
218 }
224 219
225Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address, 220 // Generate random entropy.
226 [[maybe_unused]] size_t size) { 221 GenerateRandom(m_entropy);
227 // Lock ourselves, to prevent concurrent access.
228 KScopedLightLock lk(m_state_lock);
229 222
230 // Try to find an existing info for the memory. 223 // Clear remaining fields.
231 KSharedMemoryInfo* shemen_info = nullptr; 224 m_num_running_threads = 0;
232 const auto iter = std::find_if( 225 m_num_process_switches = 0;
233 m_shared_memory_list.begin(), m_shared_memory_list.end(), 226 m_num_thread_switches = 0;
234 [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); 227 m_num_fpu_switches = 0;
235 if (iter != m_shared_memory_list.end()) { 228 m_num_supervisor_calls = 0;
236 shemen_info = *iter; 229 m_num_ipc_messages = 0;
237 }
238 230
239 if (shemen_info == nullptr) { 231 m_is_signaled = false;
240 shemen_info = KSharedMemoryInfo::Allocate(m_kernel); 232 m_exception_thread = nullptr;
241 R_UNLESS(shemen_info != nullptr, ResultOutOfMemory); 233 m_is_suspended = false;
234 m_memory_release_hint = 0;
235 m_schedule_count = 0;
236 m_is_handle_table_initialized = false;
242 237
243 shemen_info->Initialize(shmem); 238 // Open a reference to our resource limit.
244 m_shared_memory_list.push_back(shemen_info); 239 m_resource_limit = res_limit;
245 } 240 m_resource_limit->Open();
246 241
247 // Open a reference to the shared memory and its info. 242 // We're initialized!
248 shmem->Open(); 243 m_is_initialized = true;
249 shemen_info->Open();
250 244
251 R_SUCCEED(); 245 R_SUCCEED();
252} 246}
253 247
254void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address, 248Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg,
255 [[maybe_unused]] size_t size) { 249 std::span<const u32> caps, KResourceLimit* res_limit,
256 // Lock ourselves, to prevent concurrent access. 250 KMemoryManager::Pool pool, bool immortal) {
257 KScopedLightLock lk(m_state_lock); 251 ASSERT(res_limit != nullptr);
252 ASSERT((params.code_num_pages * PageSize) / PageSize ==
253 static_cast<size_t>(params.code_num_pages));
254
255 // Set members.
256 m_memory_pool = pool;
257 m_is_default_application_system_resource = false;
258 m_is_immortal = immortal;
259
260 // Setup our system resource.
261 if (const size_t system_resource_num_pages = params.system_resource_num_pages;
262 system_resource_num_pages != 0) {
263 // Create a secure system resource.
264 KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel);
265 R_UNLESS(secure_resource != nullptr, ResultOutOfResource);
266
267 ON_RESULT_FAILURE {
268 secure_resource->Close();
269 };
270
271 // Initialize the secure resource.
272 R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, res_limit,
273 m_memory_pool));
274
275 // Set our system resource.
276 m_system_resource = secure_resource;
277 } else {
278 // Use the system-wide system resource.
279 const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication);
280 m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource()
281 : m_kernel.GetSystemSystemResource());
258 282
259 KSharedMemoryInfo* shemen_info = nullptr; 283 m_is_default_application_system_resource = is_app;
260 const auto iter = std::find_if( 284
261 m_shared_memory_list.begin(), m_shared_memory_list.end(), 285 // Open reference to the system resource.
262 [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); 286 m_system_resource->Open();
263 if (iter != m_shared_memory_list.end()) {
264 shemen_info = *iter;
265 } 287 }
266 288
267 ASSERT(shemen_info != nullptr); 289 // Ensure we clean up our secure resource, if we fail.
290 ON_RESULT_FAILURE {
291 m_system_resource->Close();
292 m_system_resource = nullptr;
293 };
268 294
269 if (shemen_info->Close()) { 295 // Setup page table.
270 m_shared_memory_list.erase(iter); 296 {
271 KSharedMemoryInfo::Free(m_kernel, shemen_info); 297 const auto as_type = params.flags & Svc::CreateProcessFlag::AddressSpaceMask;
298 const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
299 const bool enable_das_merge =
300 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
301 R_TRY(m_page_table.InitializeForProcess(
302 as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address,
303 params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetMemory()));
272 } 304 }
305 ON_RESULT_FAILURE_2 {
306 m_page_table.Finalize();
307 };
273 308
274 // Close a reference to the shared memory. 309 // Ensure we can insert the code region.
275 shmem->Close(); 310 R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize,
276} 311 KMemoryState::Code),
312 ResultInvalidMemoryRegion);
277 313
278void KProcess::RegisterThread(KThread* thread) { 314 // Map the code region.
279 KScopedLightLock lk{m_list_lock}; 315 R_TRY(m_page_table.MapPageGroup(params.code_address, pg, KMemoryState::Code,
316 KMemoryPermission::KernelRead));
280 317
281 m_thread_list.push_back(thread); 318 // Initialize capabilities.
282} 319 R_TRY(m_capabilities.InitializeForKip(caps, std::addressof(m_page_table)));
283 320
284void KProcess::UnregisterThread(KThread* thread) { 321 // Initialize the process id.
285 KScopedLightLock lk{m_list_lock}; 322 m_process_id = m_kernel.CreateNewUserProcessID();
323 ASSERT(InitialProcessIdMin <= m_process_id);
324 ASSERT(m_process_id <= InitialProcessIdMax);
286 325
287 m_thread_list.remove(thread); 326 // Initialize the rest of the process.
288} 327 R_TRY(this->Initialize(params, res_limit, true));
289 328
290u64 KProcess::GetFreeThreadCount() const { 329 // We succeeded!
291 if (m_resource_limit != nullptr) { 330 R_SUCCEED();
292 const auto current_value =
293 m_resource_limit->GetCurrentValue(LimitableResource::ThreadCountMax);
294 const auto limit_value = m_resource_limit->GetLimitValue(LimitableResource::ThreadCountMax);
295 return limit_value - current_value;
296 } else {
297 return 0;
298 }
299} 331}
300 332
301Result KProcess::Reset() { 333Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
302 // Lock the process and the scheduler. 334 std::span<const u32> user_caps, KResourceLimit* res_limit,
303 KScopedLightLock lk(m_state_lock); 335 KMemoryManager::Pool pool) {
304 KScopedSchedulerLock sl{m_kernel}; 336 ASSERT(res_limit != nullptr);
305 337
306 // Validate that we're in a state that we can reset. 338 // Set members.
307 R_UNLESS(m_state != State::Terminated, ResultInvalidState); 339 m_memory_pool = pool;
308 R_UNLESS(m_is_signaled, ResultInvalidState); 340 m_is_default_application_system_resource = false;
341 m_is_immortal = false;
309 342
310 // Clear signaled. 343 // Get the memory sizes.
311 m_is_signaled = false; 344 const size_t code_num_pages = params.code_num_pages;
312 R_SUCCEED(); 345 const size_t system_resource_num_pages = params.system_resource_num_pages;
313} 346 const size_t code_size = code_num_pages * PageSize;
347 const size_t system_resource_size = system_resource_num_pages * PageSize;
314 348
315Result KProcess::SetActivity(ProcessActivity activity) { 349 // Reserve memory for our code resource.
316 // Lock ourselves and the scheduler. 350 KScopedResourceReservation memory_reservation(
317 KScopedLightLock lk{m_state_lock}; 351 res_limit, Svc::LimitableResource::PhysicalMemoryMax, code_size);
318 KScopedLightLock list_lk{m_list_lock}; 352 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
319 KScopedSchedulerLock sl{m_kernel};
320 353
321 // Validate our state. 354 // Setup our system resource.
322 R_UNLESS(m_state != State::Terminating, ResultInvalidState); 355 if (system_resource_num_pages != 0) {
323 R_UNLESS(m_state != State::Terminated, ResultInvalidState); 356 // Create a secure system resource.
357 KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel);
358 R_UNLESS(secure_resource != nullptr, ResultOutOfResource);
324 359
325 // Either pause or resume. 360 ON_RESULT_FAILURE {
326 if (activity == ProcessActivity::Paused) { 361 secure_resource->Close();
327 // Verify that we're not suspended. 362 };
328 R_UNLESS(!m_is_suspended, ResultInvalidState);
329 363
330 // Suspend all threads. 364 // Initialize the secure resource.
331 for (auto* thread : this->GetThreadList()) { 365 R_TRY(secure_resource->Initialize(system_resource_size, res_limit, m_memory_pool));
332 thread->RequestSuspend(SuspendType::Process); 366
333 } 367 // Set our system resource.
368 m_system_resource = secure_resource;
334 369
335 // Set ourselves as suspended.
336 this->SetSuspended(true);
337 } else { 370 } else {
338 ASSERT(activity == ProcessActivity::Runnable); 371 // Use the system-wide system resource.
372 const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication);
373 m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource()
374 : m_kernel.GetSystemSystemResource());
339 375
340 // Verify that we're suspended. 376 m_is_default_application_system_resource = is_app;
341 R_UNLESS(m_is_suspended, ResultInvalidState);
342 377
343 // Resume all threads. 378 // Open reference to the system resource.
344 for (auto* thread : this->GetThreadList()) { 379 m_system_resource->Open();
345 thread->Resume(SuspendType::Process); 380 }
346 }
347 381
348 // Set ourselves as resumed. 382 // Ensure we clean up our secure resource, if we fail.
349 this->SetSuspended(false); 383 ON_RESULT_FAILURE {
384 m_system_resource->Close();
385 m_system_resource = nullptr;
386 };
387
388 // Setup page table.
389 {
390 const auto as_type = params.flags & Svc::CreateProcessFlag::AddressSpaceMask;
391 const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
392 const bool enable_das_merge =
393 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
394 R_TRY(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge,
395 !enable_aslr, pool, params.code_address, code_size,
396 m_system_resource, res_limit, this->GetMemory()));
397 }
398 ON_RESULT_FAILURE_2 {
399 m_page_table.Finalize();
400 };
401
402 // Ensure we can insert the code region.
403 R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code),
404 ResultInvalidMemoryRegion);
405
406 // Map the code region.
407 R_TRY(m_page_table.MapPages(params.code_address, code_num_pages, KMemoryState::Code,
408 KMemoryPermission::KernelRead | KMemoryPermission::NotMapped));
409
410 // Initialize capabilities.
411 R_TRY(m_capabilities.InitializeForUser(user_caps, std::addressof(m_page_table)));
412
413 // Initialize the process id.
414 m_process_id = m_kernel.CreateNewUserProcessID();
415 ASSERT(ProcessIdMin <= m_process_id);
416 ASSERT(m_process_id <= ProcessIdMax);
417
418 // If we should optimize memory allocations, do so.
419 if (m_system_resource->IsSecureResource() &&
420 True(params.flags & Svc::CreateProcessFlag::OptimizeMemoryAllocation)) {
421 R_TRY(m_kernel.MemoryManager().InitializeOptimizedMemory(m_process_id, pool));
350 } 422 }
351 423
424 // Initialize the rest of the process.
425 R_TRY(this->Initialize(params, res_limit, true));
426
427 // We succeeded, so commit our memory reservation.
428 memory_reservation.Commit();
352 R_SUCCEED(); 429 R_SUCCEED();
353} 430}
354 431
355Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 432void KProcess::DoWorkerTaskImpl() {
356 bool is_hbl) { 433 // Terminate child threads.
357 m_program_id = metadata.GetTitleID(); 434 TerminateChildren(m_kernel, this, nullptr);
358 m_ideal_core = metadata.GetMainThreadCore();
359 m_is_64bit_process = metadata.Is64BitProgram();
360 m_system_resource_size = metadata.GetSystemResourceSize();
361 m_image_size = code_size;
362 m_is_hbl = is_hbl;
363 435
364 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) { 436 // Finalize the handle table, if we're not immortal.
365 // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large. 437 if (!m_is_immortal && m_is_handle_table_initialized) {
366 // However, some (buggy) programs/libraries like skyline incorrectly depend on the 438 this->FinalizeHandleTable();
367 // existence of ASLR pages before the entry point, so we will adjust the load address
368 // to point to about 2GiB into the ASLR region.
369 m_code_address = 0x8000'0000;
370 } else {
371 // All other processes can be mapped at the beginning of the code region.
372 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
373 m_code_address = 0x800'0000;
374 } else {
375 m_code_address = 0x20'0000;
376 }
377 } 439 }
378 440
379 KScopedResourceReservation memory_reservation( 441 // Finish termination.
380 m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size); 442 this->FinishTermination();
381 if (!memory_reservation.Succeeded()) { 443}
382 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes",
383 code_size + m_system_resource_size);
384 R_RETURN(ResultLimitReached);
385 }
386 // Initialize process address space
387 if (const Result result{m_page_table.InitializeForProcess(
388 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
389 this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
390 m_resource_limit, m_kernel.System().ApplicationMemory())};
391 result.IsError()) {
392 R_RETURN(result);
393 }
394
395 // Map process code region
396 if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
397 KMemoryState::Code,
398 KMemoryPermission::None)};
399 result.IsError()) {
400 R_RETURN(result);
401 }
402
403 // Initialize process capabilities
404 const auto& caps{metadata.GetKernelCapabilities()};
405 if (const Result result{
406 m_capabilities.InitializeForUserProcess(caps.data(), caps.size(), m_page_table)};
407 result.IsError()) {
408 R_RETURN(result);
409 }
410
411 // Set memory usage capacity
412 switch (metadata.GetAddressSpaceType()) {
413 case FileSys::ProgramAddressSpaceType::Is32Bit:
414 case FileSys::ProgramAddressSpaceType::Is36Bit:
415 case FileSys::ProgramAddressSpaceType::Is39Bit:
416 m_memory_usage_capacity =
417 m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart();
418 break;
419 444
420 case FileSys::ProgramAddressSpaceType::Is32BitNoMap: 445Result KProcess::StartTermination() {
421 m_memory_usage_capacity = 446 // Finalize the handle table when we're done, if the process isn't immortal.
422 (m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart()) + 447 SCOPE_EXIT({
423 (m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart()); 448 if (!m_is_immortal) {
424 break; 449 this->FinalizeHandleTable();
450 }
451 });
425 452
426 default: 453 // Terminate child threads other than the current one.
427 ASSERT(false); 454 R_RETURN(TerminateChildren(m_kernel, this, GetCurrentThreadPointer(m_kernel)));
428 break; 455}
429 }
430 456
431 // Create TLS region 457void KProcess::FinishTermination() {
432 R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address))); 458 // Only allow termination to occur if the process isn't immortal.
433 memory_reservation.Commit(); 459 if (!m_is_immortal) {
460 // Release resource limit hint.
461 if (m_resource_limit != nullptr) {
462 m_memory_release_hint = this->GetUsedNonSystemUserPhysicalMemorySize();
463 m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, 0,
464 m_memory_release_hint);
465 }
466
467 // Change state.
468 {
469 KScopedSchedulerLock sl(m_kernel);
470 this->ChangeState(State::Terminated);
471 }
434 472
435 R_RETURN(m_handle_table.Initialize(m_capabilities.GetHandleTableSize())); 473 // Close.
474 this->Close();
475 }
436} 476}
437 477
438void KProcess::Run(s32 main_thread_priority, u64 stack_size) { 478void KProcess::Exit() {
439 ASSERT(this->AllocateMainThreadStack(stack_size) == ResultSuccess); 479 // Determine whether we need to start terminating
440 m_resource_limit->Reserve(LimitableResource::ThreadCountMax, 1); 480 bool needs_terminate = false;
481 {
482 KScopedLightLock lk(m_state_lock);
483 KScopedSchedulerLock sl(m_kernel);
484
485 ASSERT(m_state != State::Created);
486 ASSERT(m_state != State::CreatedAttached);
487 ASSERT(m_state != State::Crashed);
488 ASSERT(m_state != State::Terminated);
489 if (m_state == State::Running || m_state == State::RunningAttached ||
490 m_state == State::DebugBreak) {
491 this->ChangeState(State::Terminating);
492 needs_terminate = true;
493 }
494 }
441 495
442 const std::size_t heap_capacity{m_memory_usage_capacity - 496 // If we need to start termination, do so.
443 (m_main_thread_stack_size + m_image_size)}; 497 if (needs_terminate) {
444 ASSERT(!m_page_table.SetMaxHeapSize(heap_capacity).IsError()); 498 this->StartTermination();
445 499
446 this->ChangeState(State::Running); 500 // Register the process as a work task.
501 m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this);
502 }
447 503
448 SetupMainThread(m_kernel.System(), *this, main_thread_priority, m_main_thread_stack_top); 504 // Exit the current thread.
505 GetCurrentThread(m_kernel).Exit();
449} 506}
450 507
451void KProcess::PrepareForTermination() { 508Result KProcess::Terminate() {
452 this->ChangeState(State::Terminating); 509 // Determine whether we need to start terminating.
510 bool needs_terminate = false;
511 {
512 KScopedLightLock lk(m_state_lock);
453 513
454 const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) { 514 // Check whether we're allowed to terminate.
455 for (auto* thread : in_thread_list) { 515 R_UNLESS(m_state != State::Created, ResultInvalidState);
456 if (thread->GetOwnerProcess() != this) 516 R_UNLESS(m_state != State::CreatedAttached, ResultInvalidState);
457 continue;
458 517
459 if (thread == GetCurrentThreadPointer(m_kernel)) 518 KScopedSchedulerLock sl(m_kernel);
460 continue;
461 519
462 // TODO(Subv): When are the other running/ready threads terminated? 520 if (m_state == State::Running || m_state == State::RunningAttached ||
463 ASSERT_MSG(thread->GetState() == ThreadState::Waiting, 521 m_state == State::Crashed || m_state == State::DebugBreak) {
464 "Exiting processes with non-waiting threads is currently unimplemented"); 522 this->ChangeState(State::Terminating);
523 needs_terminate = true;
524 }
525 }
465 526
466 thread->Exit(); 527 // If we need to terminate, do so.
528 if (needs_terminate) {
529 // Start termination.
530 if (R_SUCCEEDED(this->StartTermination())) {
531 // Finish termination.
532 this->FinishTermination();
533 } else {
534 // Register the process as a work task.
535 m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit,
536 this);
467 } 537 }
468 }; 538 }
469 539
470 stop_threads(m_kernel.System().GlobalSchedulerContext().GetThreadList()); 540 R_SUCCEED();
541}
471 542
472 this->DeleteThreadLocalRegion(m_plr_address); 543Result KProcess::AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) {
473 m_plr_address = 0; 544 // Lock ourselves, to prevent concurrent access.
545 KScopedLightLock lk(m_state_lock);
474 546
475 if (m_resource_limit) { 547 // Try to find an existing info for the memory.
476 m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, 548 KSharedMemoryInfo* info = nullptr;
477 m_main_thread_stack_size + m_image_size); 549 for (auto it = m_shared_memory_list.begin(); it != m_shared_memory_list.end(); ++it) {
550 if (it->GetSharedMemory() == shmem) {
551 info = std::addressof(*it);
552 break;
553 }
478 } 554 }
479 555
480 this->ChangeState(State::Terminated); 556 // If we didn't find an info, create one.
481} 557 if (info == nullptr) {
558 // Allocate a new info.
559 info = KSharedMemoryInfo::Allocate(m_kernel);
560 R_UNLESS(info != nullptr, ResultOutOfResource);
482 561
483void KProcess::Finalize() { 562 // Initialize the info and add it to our list.
484 // Free all shared memory infos. 563 info->Initialize(shmem);
485 { 564 m_shared_memory_list.push_back(*info);
486 auto it = m_shared_memory_list.begin(); 565 }
487 while (it != m_shared_memory_list.end()) {
488 KSharedMemoryInfo* info = *it;
489 KSharedMemory* shmem = info->GetSharedMemory();
490 566
491 while (!info->Close()) { 567 // Open a reference to the shared memory and its info.
492 shmem->Close(); 568 shmem->Open();
493 } 569 info->Open();
494 570
495 shmem->Close(); 571 R_SUCCEED();
572}
496 573
497 it = m_shared_memory_list.erase(it); 574void KProcess::RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) {
498 KSharedMemoryInfo::Free(m_kernel, info); 575 // Lock ourselves, to prevent concurrent access.
576 KScopedLightLock lk(m_state_lock);
577
578 // Find an existing info for the memory.
579 KSharedMemoryInfo* info = nullptr;
580 auto it = m_shared_memory_list.begin();
581 for (; it != m_shared_memory_list.end(); ++it) {
582 if (it->GetSharedMemory() == shmem) {
583 info = std::addressof(*it);
584 break;
499 } 585 }
500 } 586 }
587 ASSERT(info != nullptr);
501 588
502 // Release memory to the resource limit. 589 // Close a reference to the info and its memory.
503 if (m_resource_limit != nullptr) { 590 if (info->Close()) {
504 m_resource_limit->Close(); 591 m_shared_memory_list.erase(it);
505 m_resource_limit = nullptr; 592 KSharedMemoryInfo::Free(m_kernel, info);
506 } 593 }
507 594
508 // Finalize the page table. 595 shmem->Close();
509 m_page_table.Finalize();
510
511 // Perform inherited finalization.
512 KSynchronizationObject::Finalize();
513} 596}
514 597
515Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { 598Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
@@ -518,7 +601,7 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
518 601
519 // See if we can get a region from a partially used TLP. 602 // See if we can get a region from a partially used TLP.
520 { 603 {
521 KScopedSchedulerLock sl{m_kernel}; 604 KScopedSchedulerLock sl(m_kernel);
522 605
523 if (auto it = m_partially_used_tlp_tree.begin(); it != m_partially_used_tlp_tree.end()) { 606 if (auto it = m_partially_used_tlp_tree.begin(); it != m_partially_used_tlp_tree.end()) {
524 tlr = it->Reserve(); 607 tlr = it->Reserve();
@@ -538,7 +621,9 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
538 // Allocate a new page. 621 // Allocate a new page.
539 tlp = KThreadLocalPage::Allocate(m_kernel); 622 tlp = KThreadLocalPage::Allocate(m_kernel);
540 R_UNLESS(tlp != nullptr, ResultOutOfMemory); 623 R_UNLESS(tlp != nullptr, ResultOutOfMemory);
541 auto tlp_guard = SCOPE_GUARD({ KThreadLocalPage::Free(m_kernel, tlp); }); 624 ON_RESULT_FAILURE {
625 KThreadLocalPage::Free(m_kernel, tlp);
626 };
542 627
543 // Initialize the new page. 628 // Initialize the new page.
544 R_TRY(tlp->Initialize(m_kernel, this)); 629 R_TRY(tlp->Initialize(m_kernel, this));
@@ -549,7 +634,7 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
549 634
550 // Insert into our tree. 635 // Insert into our tree.
551 { 636 {
552 KScopedSchedulerLock sl{m_kernel}; 637 KScopedSchedulerLock sl(m_kernel);
553 if (tlp->IsAllUsed()) { 638 if (tlp->IsAllUsed()) {
554 m_fully_used_tlp_tree.insert(*tlp); 639 m_fully_used_tlp_tree.insert(*tlp);
555 } else { 640 } else {
@@ -558,7 +643,6 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
558 } 643 }
559 644
560 // We succeeded! 645 // We succeeded!
561 tlp_guard.Cancel();
562 *out = tlr; 646 *out = tlr;
563 R_SUCCEED(); 647 R_SUCCEED();
564} 648}
@@ -568,7 +652,7 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
568 652
569 // Release the region. 653 // Release the region.
570 { 654 {
571 KScopedSchedulerLock sl{m_kernel}; 655 KScopedSchedulerLock sl(m_kernel);
572 656
573 // Try to find the page in the partially used list. 657 // Try to find the page in the partially used list.
574 auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize)); 658 auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
@@ -611,95 +695,213 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
611 R_SUCCEED(); 695 R_SUCCEED();
612} 696}
613 697
614bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { 698bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value) {
615 const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { 699 if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
616 return wp.type == DebugWatchpointType::None; 700 return rl->Reserve(which, value);
617 })}; 701 } else {
702 return true;
703 }
704}
618 705
619 if (watch == m_watchpoints.end()) { 706bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout) {
620 return false; 707 if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
708 return rl->Reserve(which, value, timeout);
709 } else {
710 return true;
621 } 711 }
712}
622 713
623 watch->start_address = addr; 714void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value) {
624 watch->end_address = addr + size; 715 if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
625 watch->type = type; 716 rl->Release(which, value);
717 }
718}
626 719
627 for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; 720void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint) {
628 page += PageSize) { 721 if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
629 m_debug_page_refcounts[page]++; 722 rl->Release(which, value, hint);
630 this->GetMemory().MarkRegionDebug(page, PageSize, true);
631 } 723 }
724}
632 725
633 return true; 726void KProcess::IncrementRunningThreadCount() {
727 ASSERT(m_num_running_threads.load() >= 0);
728
729 ++m_num_running_threads;
634} 730}
635 731
636bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { 732void KProcess::DecrementRunningThreadCount() {
637 const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { 733 ASSERT(m_num_running_threads.load() > 0);
638 return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
639 })};
640 734
641 if (watch == m_watchpoints.end()) { 735 if (const auto prev = m_num_running_threads--; prev == 1) {
736 this->Terminate();
737 }
738}
739
740bool KProcess::EnterUserException() {
741 // Get the current thread.
742 KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
743 ASSERT(this == cur_thread->GetOwnerProcess());
744
745 // Check that we haven't already claimed the exception thread.
746 if (m_exception_thread == cur_thread) {
642 return false; 747 return false;
643 } 748 }
644 749
645 watch->start_address = 0; 750 // Create the wait queue we'll be using.
646 watch->end_address = 0; 751 ThreadQueueImplForKProcessEnterUserException wait_queue(m_kernel,
647 watch->type = DebugWatchpointType::None; 752 std::addressof(m_exception_thread));
648 753
649 for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; 754 // Claim the exception thread.
650 page += PageSize) { 755 {
651 m_debug_page_refcounts[page]--; 756 // Lock the scheduler.
652 if (!m_debug_page_refcounts[page]) { 757 KScopedSchedulerLock sl(m_kernel);
653 this->GetMemory().MarkRegionDebug(page, PageSize, false); 758
759 // Check that we're not terminating.
760 if (cur_thread->IsTerminationRequested()) {
761 return false;
762 }
763
764 // If we don't have an exception thread, we can just claim it directly.
765 if (m_exception_thread == nullptr) {
766 m_exception_thread = cur_thread;
767 KScheduler::SetSchedulerUpdateNeeded(m_kernel);
768 return true;
654 } 769 }
770
771 // Otherwise, we need to wait until we don't have an exception thread.
772
773 // Add the current thread as a waiter on the current exception thread.
774 cur_thread->SetKernelAddressKey(
775 reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread)) | 1);
776 m_exception_thread->AddWaiter(cur_thread);
777
778 // Wait to claim the exception thread.
779 cur_thread->BeginWait(std::addressof(wait_queue));
655 } 780 }
656 781
657 return true; 782 // If our wait didn't end due to thread termination, we succeeded.
783 return ResultTerminationRequested != cur_thread->GetWaitResult();
658} 784}
659 785
660void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { 786bool KProcess::LeaveUserException() {
661 const auto ReprotectSegment = [&](const CodeSet::Segment& segment, 787 return this->ReleaseUserException(GetCurrentThreadPointer(m_kernel));
662 Svc::MemoryPermission permission) { 788}
663 m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
664 };
665 789
666 this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size()); 790bool KProcess::ReleaseUserException(KThread* thread) {
791 KScopedSchedulerLock sl(m_kernel);
667 792
668 ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); 793 if (m_exception_thread == thread) {
669 ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); 794 m_exception_thread = nullptr;
670 ReprotectSegment(code_set.DataSegment(), Svc::MemoryPermission::ReadWrite); 795
796 // Remove waiter thread.
797 bool has_waiters;
798 if (KThread* next = thread->RemoveKernelWaiterByKey(
799 std::addressof(has_waiters),
800 reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread)) | 1);
801 next != nullptr) {
802 next->EndWait(ResultSuccess);
803 }
804
805 KScheduler::SetSchedulerUpdateNeeded(m_kernel);
806
807 return true;
808 } else {
809 return false;
810 }
671} 811}
672 812
673bool KProcess::IsSignaled() const { 813void KProcess::RegisterThread(KThread* thread) {
674 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); 814 KScopedLightLock lk(m_list_lock);
675 return m_is_signaled; 815
816 m_thread_list.push_back(*thread);
676} 817}
677 818
678KProcess::KProcess(KernelCore& kernel) 819void KProcess::UnregisterThread(KThread* thread) {
679 : KAutoObjectWithSlabHeapAndContainer{kernel}, m_page_table{m_kernel.System()}, 820 KScopedLightLock lk(m_list_lock);
680 m_handle_table{m_kernel}, m_address_arbiter{m_kernel.System()},
681 m_condition_var{m_kernel.System()}, m_state_lock{m_kernel}, m_list_lock{m_kernel} {}
682 821
683KProcess::~KProcess() = default; 822 m_thread_list.erase(m_thread_list.iterator_to(*thread));
823}
824
825size_t KProcess::GetUsedUserPhysicalMemorySize() const {
826 const size_t norm_size = m_page_table.GetNormalMemorySize();
827 const size_t other_size = m_code_size + m_main_thread_stack_size;
828 const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault();
684 829
685void KProcess::ChangeState(State new_state) { 830 return norm_size + other_size + sec_size;
686 if (m_state == new_state) { 831}
687 return; 832
833size_t KProcess::GetTotalUserPhysicalMemorySize() const {
834 // Get the amount of free and used size.
835 const size_t free_size =
836 m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax);
837 const size_t max_size = m_max_process_memory;
838
839 // Determine used size.
840 // NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike
841 // GetUsedUserPhysicalMemorySize().
842 const size_t norm_size = m_page_table.GetNormalMemorySize();
843 const size_t other_size = m_code_size + m_main_thread_stack_size;
844 const size_t sec_size = this->GetRequiredSecureMemorySize();
845 const size_t used_size = norm_size + other_size + sec_size;
846
847 // NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo
848 // does it this way.
849 if (used_size + free_size > max_size) {
850 return max_size;
851 } else {
852 return free_size + this->GetUsedUserPhysicalMemorySize();
688 } 853 }
854}
689 855
690 m_state = new_state; 856size_t KProcess::GetUsedNonSystemUserPhysicalMemorySize() const {
691 m_is_signaled = true; 857 const size_t norm_size = m_page_table.GetNormalMemorySize();
692 this->NotifyAvailable(); 858 const size_t other_size = m_code_size + m_main_thread_stack_size;
859
860 return norm_size + other_size;
861}
862
863size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const {
864 // Get the amount of free and used size.
865 const size_t free_size =
866 m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax);
867 const size_t max_size = m_max_process_memory;
868
869 // Determine used size.
870 // NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike
871 // GetUsedUserPhysicalMemorySize().
872 const size_t norm_size = m_page_table.GetNormalMemorySize();
873 const size_t other_size = m_code_size + m_main_thread_stack_size;
874 const size_t sec_size = this->GetRequiredSecureMemorySize();
875 const size_t used_size = norm_size + other_size + sec_size;
876
877 // NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo
878 // does it this way.
879 if (used_size + free_size > max_size) {
880 return max_size - this->GetRequiredSecureMemorySizeNonDefault();
881 } else {
882 return free_size + this->GetUsedNonSystemUserPhysicalMemorySize();
883 }
693} 884}
694 885
695Result KProcess::AllocateMainThreadStack(std::size_t stack_size) { 886Result KProcess::Run(s32 priority, size_t stack_size) {
887 // Lock ourselves, to prevent concurrent access.
888 KScopedLightLock lk(m_state_lock);
889
890 // Validate that we're in a state where we can initialize.
891 const auto state = m_state;
892 R_UNLESS(state == State::Created || state == State::CreatedAttached, ResultInvalidState);
893
894 // Place a tentative reservation of a thread for this process.
895 KScopedResourceReservation thread_reservation(this, Svc::LimitableResource::ThreadCountMax);
896 R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached);
897
696 // Ensure that we haven't already allocated stack. 898 // Ensure that we haven't already allocated stack.
697 ASSERT(m_main_thread_stack_size == 0); 899 ASSERT(m_main_thread_stack_size == 0);
698 900
699 // Ensure that we're allocating a valid stack. 901 // Ensure that we're allocating a valid stack.
700 stack_size = Common::AlignUp(stack_size, PageSize); 902 stack_size = Common::AlignUp(stack_size, PageSize);
701 // R_UNLESS(stack_size + image_size <= m_max_process_memory, ResultOutOfMemory); 903 R_UNLESS(stack_size + m_code_size <= m_max_process_memory, ResultOutOfMemory);
702 R_UNLESS(stack_size + m_image_size >= m_image_size, ResultOutOfMemory); 904 R_UNLESS(stack_size + m_code_size >= m_code_size, ResultOutOfMemory);
703 905
704 // Place a tentative reservation of memory for our new stack. 906 // Place a tentative reservation of memory for our new stack.
705 KScopedResourceReservation mem_reservation(this, Svc::LimitableResource::PhysicalMemoryMax, 907 KScopedResourceReservation mem_reservation(this, Svc::LimitableResource::PhysicalMemoryMax,
@@ -707,21 +909,359 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) {
707 R_UNLESS(mem_reservation.Succeeded(), ResultLimitReached); 909 R_UNLESS(mem_reservation.Succeeded(), ResultLimitReached);
708 910
709 // Allocate and map our stack. 911 // Allocate and map our stack.
912 KProcessAddress stack_top = 0;
710 if (stack_size) { 913 if (stack_size) {
711 KProcessAddress stack_bottom; 914 KProcessAddress stack_bottom;
712 R_TRY(m_page_table.MapPages(std::addressof(stack_bottom), stack_size / PageSize, 915 R_TRY(m_page_table.MapPages(std::addressof(stack_bottom), stack_size / PageSize,
713 KMemoryState::Stack, KMemoryPermission::UserReadWrite)); 916 KMemoryState::Stack, KMemoryPermission::UserReadWrite));
714 917
715 m_main_thread_stack_top = stack_bottom + stack_size; 918 stack_top = stack_bottom + stack_size;
716 m_main_thread_stack_size = stack_size; 919 m_main_thread_stack_size = stack_size;
717 } 920 }
718 921
922 // Ensure our stack is safe to clean up on exit.
923 ON_RESULT_FAILURE {
924 if (m_main_thread_stack_size) {
925 ASSERT(R_SUCCEEDED(m_page_table.UnmapPages(stack_top - m_main_thread_stack_size,
926 m_main_thread_stack_size / PageSize,
927 KMemoryState::Stack)));
928 m_main_thread_stack_size = 0;
929 }
930 };
931
932 // Set our maximum heap size.
933 R_TRY(m_page_table.SetMaxHeapSize(m_max_process_memory -
934 (m_main_thread_stack_size + m_code_size)));
935
936 // Initialize our handle table.
937 R_TRY(this->InitializeHandleTable(m_capabilities.GetHandleTableSize()));
938 ON_RESULT_FAILURE_2 {
939 this->FinalizeHandleTable();
940 };
941
942 // Create a new thread for the process.
943 KThread* main_thread = KThread::Create(m_kernel);
944 R_UNLESS(main_thread != nullptr, ResultOutOfResource);
945 SCOPE_EXIT({ main_thread->Close(); });
946
947 // Initialize the thread.
948 R_TRY(KThread::InitializeUserThread(m_kernel.System(), main_thread, this->GetEntryPoint(), 0,
949 stack_top, priority, m_ideal_core_id, this));
950
951 // Register the thread, and commit our reservation.
952 KThread::Register(m_kernel, main_thread);
953 thread_reservation.Commit();
954
955 // Add the thread to our handle table.
956 Handle thread_handle;
957 R_TRY(m_handle_table.Add(std::addressof(thread_handle), main_thread));
958
959 // Set the thread arguments.
960 main_thread->GetContext32().cpu_registers[0] = 0;
961 main_thread->GetContext64().cpu_registers[0] = 0;
962 main_thread->GetContext32().cpu_registers[1] = thread_handle;
963 main_thread->GetContext64().cpu_registers[1] = thread_handle;
964
965 // Update our state.
966 this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached);
967 ON_RESULT_FAILURE_2 {
968 this->ChangeState(state);
969 };
970
971 // Suspend for debug, if we should.
972 if (m_kernel.System().DebuggerEnabled()) {
973 main_thread->RequestSuspend(SuspendType::Debug);
974 }
975
976 // Run our thread.
977 R_TRY(main_thread->Run());
978
979 // Open a reference to represent that we're running.
980 this->Open();
981
719 // We succeeded! Commit our memory reservation. 982 // We succeeded! Commit our memory reservation.
720 mem_reservation.Commit(); 983 mem_reservation.Commit();
721 984
722 R_SUCCEED(); 985 R_SUCCEED();
723} 986}
724 987
988Result KProcess::Reset() {
989 // Lock the process and the scheduler.
990 KScopedLightLock lk(m_state_lock);
991 KScopedSchedulerLock sl(m_kernel);
992
993 // Validate that we're in a state that we can reset.
994 R_UNLESS(m_state != State::Terminated, ResultInvalidState);
995 R_UNLESS(m_is_signaled, ResultInvalidState);
996
997 // Clear signaled.
998 m_is_signaled = false;
999 R_SUCCEED();
1000}
1001
1002Result KProcess::SetActivity(Svc::ProcessActivity activity) {
1003 // Lock ourselves and the scheduler.
1004 KScopedLightLock lk(m_state_lock);
1005 KScopedLightLock list_lk(m_list_lock);
1006 KScopedSchedulerLock sl(m_kernel);
1007
1008 // Validate our state.
1009 R_UNLESS(m_state != State::Terminating, ResultInvalidState);
1010 R_UNLESS(m_state != State::Terminated, ResultInvalidState);
1011
1012 // Either pause or resume.
1013 if (activity == Svc::ProcessActivity::Paused) {
1014 // Verify that we're not suspended.
1015 R_UNLESS(!m_is_suspended, ResultInvalidState);
1016
1017 // Suspend all threads.
1018 auto end = this->GetThreadList().end();
1019 for (auto it = this->GetThreadList().begin(); it != end; ++it) {
1020 it->RequestSuspend(SuspendType::Process);
1021 }
1022
1023 // Set ourselves as suspended.
1024 this->SetSuspended(true);
1025 } else {
1026 ASSERT(activity == Svc::ProcessActivity::Runnable);
1027
1028 // Verify that we're suspended.
1029 R_UNLESS(m_is_suspended, ResultInvalidState);
1030
1031 // Resume all threads.
1032 auto end = this->GetThreadList().end();
1033 for (auto it = this->GetThreadList().begin(); it != end; ++it) {
1034 it->Resume(SuspendType::Process);
1035 }
1036
1037 // Set ourselves as resumed.
1038 this->SetSuspended(false);
1039 }
1040
1041 R_SUCCEED();
1042}
1043
1044void KProcess::PinCurrentThread() {
1045 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
1046
1047 // Get the current thread.
1048 const s32 core_id = GetCurrentCoreId(m_kernel);
1049 KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
1050
1051 // If the thread isn't terminated, pin it.
1052 if (!cur_thread->IsTerminationRequested()) {
1053 // Pin it.
1054 this->PinThread(core_id, cur_thread);
1055 cur_thread->Pin(core_id);
1056
1057 // An update is needed.
1058 KScheduler::SetSchedulerUpdateNeeded(m_kernel);
1059 }
1060}
1061
1062void KProcess::UnpinCurrentThread() {
1063 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
1064
1065 // Get the current thread.
1066 const s32 core_id = GetCurrentCoreId(m_kernel);
1067 KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
1068
1069 // Unpin it.
1070 cur_thread->Unpin();
1071 this->UnpinThread(core_id, cur_thread);
1072
1073 // An update is needed.
1074 KScheduler::SetSchedulerUpdateNeeded(m_kernel);
1075}
1076
1077void KProcess::UnpinThread(KThread* thread) {
1078 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
1079
1080 // Get the thread's core id.
1081 const auto core_id = thread->GetActiveCore();
1082
1083 // Unpin it.
1084 this->UnpinThread(core_id, thread);
1085 thread->Unpin();
1086
1087 // An update is needed.
1088 KScheduler::SetSchedulerUpdateNeeded(m_kernel);
1089}
1090
1091Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids,
1092 s32 max_out_count) {
1093 // TODO: use current memory reference
1094 auto& memory = m_kernel.System().ApplicationMemory();
1095
1096 // Lock the list.
1097 KScopedLightLock lk(m_list_lock);
1098
1099 // Iterate over the list.
1100 s32 count = 0;
1101 auto end = this->GetThreadList().end();
1102 for (auto it = this->GetThreadList().begin(); it != end; ++it) {
1103 // If we're within array bounds, write the id.
1104 if (count < max_out_count) {
1105 // Get the thread id.
1106 KThread* thread = std::addressof(*it);
1107 const u64 id = thread->GetId();
1108
1109 // Copy the id to userland.
1110 memory.Write64(out_thread_ids + count * sizeof(u64), id);
1111 }
1112
1113 // Increment the count.
1114 ++count;
1115 }
1116
1117 // We successfully iterated the list.
1118 *out_num_threads = count;
1119 R_SUCCEED();
1120}
1121
1122void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
1123
1124KProcess::KProcess(KernelCore& kernel)
1125 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel.System()},
1126 m_state_lock{kernel}, m_list_lock{kernel}, m_cond_var{kernel.System()},
1127 m_address_arbiter{kernel.System()}, m_handle_table{kernel} {}
1128KProcess::~KProcess() = default;
1129
1130Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
1131 bool is_hbl) {
1132 // Create a resource limit for the process.
1133 const auto physical_memory_size =
1134 m_kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application);
1135 auto* res_limit =
1136 Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size);
1137
1138 // Ensure we maintain a clean state on exit.
1139 SCOPE_EXIT({ res_limit->Close(); });
1140
1141 // Declare flags and code address.
1142 Svc::CreateProcessFlag flag{};
1143 u64 code_address{};
1144
1145 // We are an application.
1146 flag |= Svc::CreateProcessFlag::IsApplication;
1147
1148 // If we are 64-bit, create as such.
1149 if (metadata.Is64BitProgram()) {
1150 flag |= Svc::CreateProcessFlag::Is64Bit;
1151 }
1152
1153 // Set the address space type and code address.
1154 switch (metadata.GetAddressSpaceType()) {
1155 case FileSys::ProgramAddressSpaceType::Is39Bit:
1156 flag |= Svc::CreateProcessFlag::AddressSpace64Bit;
1157
1158 // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
1159 // However, some (buggy) programs/libraries like skyline incorrectly depend on the
1160 // existence of ASLR pages before the entry point, so we will adjust the load address
1161 // to point to about 2GiB into the ASLR region.
1162 code_address = 0x8000'0000;
1163 break;
1164 case FileSys::ProgramAddressSpaceType::Is36Bit:
1165 flag |= Svc::CreateProcessFlag::AddressSpace64BitDeprecated;
1166 code_address = 0x800'0000;
1167 break;
1168 case FileSys::ProgramAddressSpaceType::Is32Bit:
1169 flag |= Svc::CreateProcessFlag::AddressSpace32Bit;
1170 code_address = 0x20'0000;
1171 break;
1172 case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
1173 flag |= Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias;
1174 code_address = 0x20'0000;
1175 break;
1176 }
1177
1178 Svc::CreateProcessParameter params{
1179 .name = {},
1180 .version = {},
1181 .program_id = metadata.GetTitleID(),
1182 .code_address = code_address,
1183 .code_num_pages = static_cast<s32>(code_size / PageSize),
1184 .flags = flag,
1185 .reslimit = Svc::InvalidHandle,
1186 .system_resource_num_pages = static_cast<s32>(metadata.GetSystemResourceSize() / PageSize),
1187 };
1188
1189 // Set the process name.
1190 const auto& name = metadata.GetName();
1191 static_assert(sizeof(params.name) <= sizeof(name));
1192 std::memcpy(params.name.data(), name.data(), sizeof(params.name));
1193
1194 // Initialize for application process.
1195 R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit,
1196 KMemoryManager::Pool::Application));
1197
1198 // Assign remaining properties.
1199 m_is_hbl = is_hbl;
1200 m_ideal_core_id = metadata.GetMainThreadCore();
1201
1202 // We succeeded.
1203 R_SUCCEED();
1204}
1205
1206void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
1207 const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
1208 Svc::MemoryPermission permission) {
1209 m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
1210 };
1211
1212 this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size());
1213
1214 ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute);
1215 ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read);
1216 ReprotectSegment(code_set.DataSegment(), Svc::MemoryPermission::ReadWrite);
1217}
1218
1219bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
1220 const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
1221 return wp.type == DebugWatchpointType::None;
1222 })};
1223
1224 if (watch == m_watchpoints.end()) {
1225 return false;
1226 }
1227
1228 watch->start_address = addr;
1229 watch->end_address = addr + size;
1230 watch->type = type;
1231
1232 for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
1233 page += PageSize) {
1234 m_debug_page_refcounts[page]++;
1235 this->GetMemory().MarkRegionDebug(page, PageSize, true);
1236 }
1237
1238 return true;
1239}
1240
1241bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
1242 const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
1243 return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
1244 })};
1245
1246 if (watch == m_watchpoints.end()) {
1247 return false;
1248 }
1249
1250 watch->start_address = 0;
1251 watch->end_address = 0;
1252 watch->type = DebugWatchpointType::None;
1253
1254 for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
1255 page += PageSize) {
1256 m_debug_page_refcounts[page]--;
1257 if (!m_debug_page_refcounts[page]) {
1258 this->GetMemory().MarkRegionDebug(page, PageSize, false);
1259 }
1260 }
1261
1262 return true;
1263}
1264
725Core::Memory::Memory& KProcess::GetMemory() const { 1265Core::Memory::Memory& KProcess::GetMemory() const {
726 // TODO: per-process memory 1266 // TODO: per-process memory
727 return m_kernel.System().ApplicationMemory(); 1267 return m_kernel.System().ApplicationMemory();
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 146e07a57..f9f755afa 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -1,59 +1,23 @@
1// SPDX-FileCopyrightText: 2015 Citra Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#pragma once 4#pragma once
5 5
6#include <array>
7#include <cstddef>
8#include <list>
9#include <map> 6#include <map>
10#include <string> 7
8#include "core/hle/kernel/code_set.h"
11#include "core/hle/kernel/k_address_arbiter.h" 9#include "core/hle/kernel/k_address_arbiter.h"
12#include "core/hle/kernel/k_auto_object.h" 10#include "core/hle/kernel/k_capabilities.h"
13#include "core/hle/kernel/k_condition_variable.h" 11#include "core/hle/kernel/k_condition_variable.h"
14#include "core/hle/kernel/k_handle_table.h" 12#include "core/hle/kernel/k_handle_table.h"
15#include "core/hle/kernel/k_page_table.h" 13#include "core/hle/kernel/k_page_table.h"
16#include "core/hle/kernel/k_synchronization_object.h" 14#include "core/hle/kernel/k_page_table_manager.h"
15#include "core/hle/kernel/k_system_resource.h"
16#include "core/hle/kernel/k_thread.h"
17#include "core/hle/kernel/k_thread_local_page.h" 17#include "core/hle/kernel/k_thread_local_page.h"
18#include "core/hle/kernel/k_typed_address.h"
19#include "core/hle/kernel/k_worker_task.h"
20#include "core/hle/kernel/process_capability.h"
21#include "core/hle/kernel/slab_helpers.h"
22#include "core/hle/result.h"
23
24namespace Core {
25namespace Memory {
26class Memory;
27};
28
29class System;
30} // namespace Core
31
32namespace FileSys {
33class ProgramMetadata;
34}
35 18
36namespace Kernel { 19namespace Kernel {
37 20
38class KernelCore;
39class KResourceLimit;
40class KThread;
41class KSharedMemoryInfo;
42class TLSPage;
43
44struct CodeSet;
45
46enum class MemoryRegion : u16 {
47 APPLICATION = 1,
48 SYSTEM = 2,
49 BASE = 3,
50};
51
52enum class ProcessActivity : u32 {
53 Runnable,
54 Paused,
55};
56
57enum class DebugWatchpointType : u8 { 21enum class DebugWatchpointType : u8 {
58 None = 0, 22 None = 0,
59 Read = 1 << 0, 23 Read = 1 << 0,
@@ -72,9 +36,6 @@ class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWor
72 KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); 36 KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
73 37
74public: 38public:
75 explicit KProcess(KernelCore& kernel);
76 ~KProcess() override;
77
78 enum class State { 39 enum class State {
79 Created = static_cast<u32>(Svc::ProcessState::Created), 40 Created = static_cast<u32>(Svc::ProcessState::Created),
80 CreatedAttached = static_cast<u32>(Svc::ProcessState::CreatedAttached), 41 CreatedAttached = static_cast<u32>(Svc::ProcessState::CreatedAttached),
@@ -86,470 +47,493 @@ public:
86 DebugBreak = static_cast<u32>(Svc::ProcessState::DebugBreak), 47 DebugBreak = static_cast<u32>(Svc::ProcessState::DebugBreak),
87 }; 48 };
88 49
89 enum : u64 { 50 using ThreadList = Common::IntrusiveListMemberTraits<&KThread::m_process_list_node>::ListType;
90 /// Lowest allowed process ID for a kernel initial process.
91 InitialKIPIDMin = 1,
92 /// Highest allowed process ID for a kernel initial process.
93 InitialKIPIDMax = 80,
94
95 /// Lowest allowed process ID for a userland process.
96 ProcessIDMin = 81,
97 /// Highest allowed process ID for a userland process.
98 ProcessIDMax = 0xFFFFFFFFFFFFFFFF,
99 };
100 51
101 // Used to determine how process IDs are assigned. 52 static constexpr size_t AslrAlignment = 2_MiB;
102 enum class ProcessType {
103 KernelInternal,
104 Userland,
105 };
106 53
107 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; 54public:
55 static constexpr u64 InitialProcessIdMin = 1;
56 static constexpr u64 InitialProcessIdMax = 0x50;
108 57
109 static Result Initialize(KProcess* process, Core::System& system, std::string process_name, 58 static constexpr u64 ProcessIdMin = InitialProcessIdMax + 1;
110 ProcessType type, KResourceLimit* res_limit); 59 static constexpr u64 ProcessIdMax = std::numeric_limits<u64>::max();
111 60
112 /// Gets a reference to the process' page table. 61private:
113 KPageTable& GetPageTable() { 62 using SharedMemoryInfoList = Common::IntrusiveListBaseTraits<KSharedMemoryInfo>::ListType;
114 return m_page_table; 63 using TLPTree =
115 } 64 Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
65 using TLPIterator = TLPTree::iterator;
116 66
117 /// Gets const a reference to the process' page table. 67private:
118 const KPageTable& GetPageTable() const { 68 KPageTable m_page_table;
119 return m_page_table; 69 std::atomic<size_t> m_used_kernel_memory_size{};
120 } 70 TLPTree m_fully_used_tlp_tree{};
71 TLPTree m_partially_used_tlp_tree{};
72 s32 m_ideal_core_id{};
73 KResourceLimit* m_resource_limit{};
74 KSystemResource* m_system_resource{};
75 size_t m_memory_release_hint{};
76 State m_state{};
77 KLightLock m_state_lock;
78 KLightLock m_list_lock;
79 KConditionVariable m_cond_var;
80 KAddressArbiter m_address_arbiter;
81 std::array<u64, 4> m_entropy{};
82 bool m_is_signaled{};
83 bool m_is_initialized{};
84 bool m_is_application{};
85 bool m_is_default_application_system_resource{};
86 bool m_is_hbl{};
87 std::array<char, 13> m_name{};
88 std::atomic<u16> m_num_running_threads{};
89 Svc::CreateProcessFlag m_flags{};
90 KMemoryManager::Pool m_memory_pool{};
91 s64 m_schedule_count{};
92 KCapabilities m_capabilities{};
93 u64 m_program_id{};
94 u64 m_process_id{};
95 KProcessAddress m_code_address{};
96 size_t m_code_size{};
97 size_t m_main_thread_stack_size{};
98 size_t m_max_process_memory{};
99 u32 m_version{};
100 KHandleTable m_handle_table;
101 KProcessAddress m_plr_address{};
102 KThread* m_exception_thread{};
103 ThreadList m_thread_list{};
104 SharedMemoryInfoList m_shared_memory_list{};
105 bool m_is_suspended{};
106 bool m_is_immortal{};
107 bool m_is_handle_table_initialized{};
108 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_running_threads{};
109 std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
110 std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_switch_counts{};
111 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
112 std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
113 std::map<KProcessAddress, u64> m_debug_page_refcounts{};
114 std::atomic<s64> m_cpu_time{};
115 std::atomic<s64> m_num_process_switches{};
116 std::atomic<s64> m_num_thread_switches{};
117 std::atomic<s64> m_num_fpu_switches{};
118 std::atomic<s64> m_num_supervisor_calls{};
119 std::atomic<s64> m_num_ipc_messages{};
120 std::atomic<s64> m_num_ipc_replies{};
121 std::atomic<s64> m_num_ipc_receives{};
121 122
122 /// Gets a reference to the process' handle table. 123private:
123 KHandleTable& GetHandleTable() { 124 Result StartTermination();
124 return m_handle_table; 125 void FinishTermination();
125 }
126 126
127 /// Gets a const reference to the process' handle table. 127 void PinThread(s32 core_id, KThread* thread) {
128 const KHandleTable& GetHandleTable() const { 128 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
129 return m_handle_table; 129 ASSERT(thread != nullptr);
130 ASSERT(m_pinned_threads[core_id] == nullptr);
131 m_pinned_threads[core_id] = thread;
130 } 132 }
131 133
132 /// Gets a reference to process's memory. 134 void UnpinThread(s32 core_id, KThread* thread) {
133 Core::Memory::Memory& GetMemory() const; 135 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
134 136 ASSERT(thread != nullptr);
135 Result SignalToAddress(KProcessAddress address) { 137 ASSERT(m_pinned_threads[core_id] == thread);
136 return m_condition_var.SignalToAddress(address); 138 m_pinned_threads[core_id] = nullptr;
137 } 139 }
138 140
139 Result WaitForAddress(Handle handle, KProcessAddress address, u32 tag) { 141public:
140 return m_condition_var.WaitForAddress(handle, address, tag); 142 explicit KProcess(KernelCore& kernel);
141 } 143 ~KProcess() override;
142 144
143 void SignalConditionVariable(u64 cv_key, int32_t count) { 145 Result Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit,
144 return m_condition_var.Signal(cv_key, count); 146 bool is_real);
145 }
146 147
147 Result WaitConditionVariable(KProcessAddress address, u64 cv_key, u32 tag, s64 ns) { 148 Result Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg,
148 R_RETURN(m_condition_var.Wait(address, cv_key, tag, ns)); 149 std::span<const u32> caps, KResourceLimit* res_limit,
149 } 150 KMemoryManager::Pool pool, bool immortal);
151 Result Initialize(const Svc::CreateProcessParameter& params, std::span<const u32> user_caps,
152 KResourceLimit* res_limit, KMemoryManager::Pool pool);
153 void Exit();
150 154
151 Result SignalAddressArbiter(uint64_t address, Svc::SignalType signal_type, s32 value, 155 const char* GetName() const {
152 s32 count) { 156 return m_name.data();
153 R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
154 } 157 }
155 158
156 Result WaitAddressArbiter(uint64_t address, Svc::ArbitrationType arb_type, s32 value, 159 u64 GetProgramId() const {
157 s64 timeout) { 160 return m_program_id;
158 R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
159 } 161 }
160 162
161 KProcessAddress GetProcessLocalRegionAddress() const { 163 u64 GetProcessId() const {
162 return m_plr_address; 164 return m_process_id;
163 } 165 }
164 166
165 /// Gets the current status of the process
166 State GetState() const { 167 State GetState() const {
167 return m_state; 168 return m_state;
168 } 169 }
169 170
170 /// Gets the unique ID that identifies this particular process. 171 u64 GetCoreMask() const {
171 u64 GetProcessId() const { 172 return m_capabilities.GetCoreMask();
172 return m_process_id; 173 }
174 u64 GetPhysicalCoreMask() const {
175 return m_capabilities.GetPhysicalCoreMask();
176 }
177 u64 GetPriorityMask() const {
178 return m_capabilities.GetPriorityMask();
173 } 179 }
174 180
175 /// Gets the program ID corresponding to this process. 181 s32 GetIdealCoreId() const {
176 u64 GetProgramId() const { 182 return m_ideal_core_id;
177 return m_program_id; 183 }
184 void SetIdealCoreId(s32 core_id) {
185 m_ideal_core_id = core_id;
178 } 186 }
179 187
180 KProcessAddress GetEntryPoint() const { 188 bool CheckThreadPriority(s32 prio) const {
181 return m_code_address; 189 return ((1ULL << prio) & this->GetPriorityMask()) != 0;
182 } 190 }
183 191
184 /// Gets the resource limit descriptor for this process 192 u32 GetCreateProcessFlags() const {
185 KResourceLimit* GetResourceLimit() const; 193 return static_cast<u32>(m_flags);
194 }
186 195
187 /// Gets the ideal CPU core ID for this process 196 bool Is64Bit() const {
188 u8 GetIdealCoreId() const { 197 return True(m_flags & Svc::CreateProcessFlag::Is64Bit);
189 return m_ideal_core;
190 } 198 }
191 199
192 /// Checks if the specified thread priority is valid. 200 KProcessAddress GetEntryPoint() const {
193 bool CheckThreadPriority(s32 prio) const { 201 return m_code_address;
194 return ((1ULL << prio) & GetPriorityMask()) != 0;
195 } 202 }
196 203
197 /// Gets the bitmask of allowed cores that this process' threads can run on. 204 size_t GetMainStackSize() const {
198 u64 GetCoreMask() const { 205 return m_main_thread_stack_size;
199 return m_capabilities.GetCoreMask();
200 } 206 }
201 207
202 /// Gets the bitmask of allowed thread priorities. 208 KMemoryManager::Pool GetMemoryPool() const {
203 u64 GetPriorityMask() const { 209 return m_memory_pool;
204 return m_capabilities.GetPriorityMask();
205 } 210 }
206 211
207 /// Gets the amount of secure memory to allocate for memory management. 212 u64 GetRandomEntropy(size_t i) const {
208 u32 GetSystemResourceSize() const { 213 return m_entropy[i];
209 return m_system_resource_size;
210 } 214 }
211 215
212 /// Gets the amount of secure memory currently in use for memory management. 216 bool IsApplication() const {
213 u32 GetSystemResourceUsage() const { 217 return m_is_application;
214 // On hardware, this returns the amount of system resource memory that has
215 // been used by the kernel. This is problematic for Yuzu to emulate, because
216 // system resource memory is used for page tables -- and yuzu doesn't really
217 // have a way to calculate how much memory is required for page tables for
218 // the current process at any given time.
219 // TODO: Is this even worth implementing? Games may retrieve this value via
220 // an SDK function that gets used + available system resource size for debug
221 // or diagnostic purposes. However, it seems unlikely that a game would make
222 // decisions based on how much system memory is dedicated to its page tables.
223 // Is returning a value other than zero wise?
224 return 0;
225 } 218 }
226 219
227 /// Whether this process is an AArch64 or AArch32 process. 220 bool IsDefaultApplicationSystemResource() const {
228 bool Is64BitProcess() const { 221 return m_is_default_application_system_resource;
229 return m_is_64bit_process;
230 } 222 }
231 223
232 bool IsSuspended() const { 224 bool IsSuspended() const {
233 return m_is_suspended; 225 return m_is_suspended;
234 } 226 }
235
236 void SetSuspended(bool suspended) { 227 void SetSuspended(bool suspended) {
237 m_is_suspended = suspended; 228 m_is_suspended = suspended;
238 } 229 }
239 230
240 /// Gets the total running time of the process instance in ticks. 231 Result Terminate();
241 u64 GetCPUTimeTicks() const { 232
242 return m_total_process_running_time_ticks; 233 bool IsTerminated() const {
234 return m_state == State::Terminated;
243 } 235 }
244 236
245 /// Updates the total running time, adding the given ticks to it. 237 bool IsPermittedSvc(u32 svc_id) const {
246 void UpdateCPUTimeTicks(u64 ticks) { 238 return m_capabilities.IsPermittedSvc(svc_id);
247 m_total_process_running_time_ticks += ticks;
248 } 239 }
249 240
250 /// Gets the process schedule count, used for thread yielding 241 bool IsPermittedInterrupt(s32 interrupt_id) const {
251 s64 GetScheduledCount() const { 242 return m_capabilities.IsPermittedInterrupt(interrupt_id);
252 return m_schedule_count;
253 } 243 }
254 244
255 /// Increments the process schedule count, used for thread yielding. 245 bool IsPermittedDebug() const {
256 void IncrementScheduledCount() { 246 return m_capabilities.IsPermittedDebug();
257 ++m_schedule_count;
258 } 247 }
259 248
260 void IncrementRunningThreadCount(); 249 bool CanForceDebug() const {
261 void DecrementRunningThreadCount(); 250 return m_capabilities.CanForceDebug();
251 }
262 252
263 void SetRunningThread(s32 core, KThread* thread, u64 idle_count) { 253 bool IsHbl() const {
264 m_running_threads[core] = thread; 254 return m_is_hbl;
265 m_running_thread_idle_counts[core] = idle_count;
266 } 255 }
267 256
268 void ClearRunningThread(KThread* thread) { 257 Kernel::KMemoryManager::Direction GetAllocateOption() const {
269 for (size_t i = 0; i < m_running_threads.size(); ++i) { 258 // TODO: property of the KPageTableBase
270 if (m_running_threads[i] == thread) { 259 return KMemoryManager::Direction::FromFront;
271 m_running_threads[i] = nullptr;
272 }
273 }
274 } 260 }
275 261
276 [[nodiscard]] KThread* GetRunningThread(s32 core) const { 262 ThreadList& GetThreadList() {
277 return m_running_threads[core]; 263 return m_thread_list;
264 }
265 const ThreadList& GetThreadList() const {
266 return m_thread_list;
278 } 267 }
279 268
269 bool EnterUserException();
270 bool LeaveUserException();
280 bool ReleaseUserException(KThread* thread); 271 bool ReleaseUserException(KThread* thread);
281 272
282 [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const { 273 KThread* GetPinnedThread(s32 core_id) const {
283 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES)); 274 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
284 return m_pinned_threads[core_id]; 275 return m_pinned_threads[core_id];
285 } 276 }
286 277
287 /// Gets 8 bytes of random data for svcGetInfo RandomEntropy 278 const Svc::SvcAccessFlagSet& GetSvcPermissions() const {
288 u64 GetRandomEntropy(std::size_t index) const { 279 return m_capabilities.GetSvcPermissions();
289 return m_random_entropy.at(index);
290 } 280 }
291 281
292 /// Retrieves the total physical memory available to this process in bytes. 282 KResourceLimit* GetResourceLimit() const {
293 u64 GetTotalPhysicalMemoryAvailable(); 283 return m_resource_limit;
294
295 /// Retrieves the total physical memory available to this process in bytes,
296 /// without the size of the personal system resource heap added to it.
297 u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource();
298
299 /// Retrieves the total physical memory used by this process in bytes.
300 u64 GetTotalPhysicalMemoryUsed();
301
302 /// Retrieves the total physical memory used by this process in bytes,
303 /// without the size of the personal system resource heap added to it.
304 u64 GetTotalPhysicalMemoryUsedWithoutSystemResource();
305
306 /// Gets the list of all threads created with this process as their owner.
307 std::list<KThread*>& GetThreadList() {
308 return m_thread_list;
309 } 284 }
310 285
311 /// Registers a thread as being created under this process, 286 bool ReserveResource(Svc::LimitableResource which, s64 value);
312 /// adding it to this process' thread list. 287 bool ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout);
313 void RegisterThread(KThread* thread); 288 void ReleaseResource(Svc::LimitableResource which, s64 value);
289 void ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint);
314 290
315 /// Unregisters a thread from this process, removing it 291 KLightLock& GetStateLock() {
316 /// from this process' thread list. 292 return m_state_lock;
317 void UnregisterThread(KThread* thread); 293 }
294 KLightLock& GetListLock() {
295 return m_list_lock;
296 }
318 297
319 /// Retrieves the number of available threads for this process. 298 KPageTable& GetPageTable() {
320 u64 GetFreeThreadCount() const; 299 return m_page_table;
321 300 }
322 /// Clears the signaled state of the process if and only if it's signaled. 301 const KPageTable& GetPageTable() const {
323 /// 302 return m_page_table;
324 /// @pre The process must not be already terminated. If this is called on a 303 }
325 /// terminated process, then ResultInvalidState will be returned.
326 ///
327 /// @pre The process must be in a signaled state. If this is called on a
328 /// process instance that is not signaled, ResultInvalidState will be
329 /// returned.
330 Result Reset();
331 304
332 /** 305 KHandleTable& GetHandleTable() {
333 * Loads process-specifics configuration info with metadata provided 306 return m_handle_table;
334 * by an executable. 307 }
335 * 308 const KHandleTable& GetHandleTable() const {
336 * @param metadata The provided metadata to load process specific info from. 309 return m_handle_table;
337 * 310 }
338 * @returns ResultSuccess if all relevant metadata was able to be
339 * loaded and parsed. Otherwise, an error code is returned.
340 */
341 Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
342 bool is_hbl);
343 311
344 /** 312 size_t GetUsedUserPhysicalMemorySize() const;
345 * Starts the main application thread for this process. 313 size_t GetTotalUserPhysicalMemorySize() const;
346 * 314 size_t GetUsedNonSystemUserPhysicalMemorySize() const;
347 * @param main_thread_priority The priority for the main thread. 315 size_t GetTotalNonSystemUserPhysicalMemorySize() const;
348 * @param stack_size The stack size for the main thread in bytes.
349 */
350 void Run(s32 main_thread_priority, u64 stack_size);
351 316
352 /** 317 Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
353 * Prepares a process for termination by stopping all of its threads 318 void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
354 * and clearing any other resources.
355 */
356 void PrepareForTermination();
357 319
358 void LoadModule(CodeSet code_set, KProcessAddress base_addr); 320 Result CreateThreadLocalRegion(KProcessAddress* out);
321 Result DeleteThreadLocalRegion(KProcessAddress addr);
359 322
360 bool IsInitialized() const override { 323 KProcessAddress GetProcessLocalRegionAddress() const {
361 return m_is_initialized; 324 return m_plr_address;
362 } 325 }
363 326
364 static void PostDestroy(uintptr_t arg) {} 327 KThread* GetExceptionThread() const {
365 328 return m_exception_thread;
366 void Finalize() override;
367
368 u64 GetId() const override {
369 return GetProcessId();
370 } 329 }
371 330
372 bool IsHbl() const { 331 void AddCpuTime(s64 diff) {
373 return m_is_hbl; 332 m_cpu_time += diff;
333 }
334 s64 GetCpuTime() {
335 return m_cpu_time.load();
374 } 336 }
375 337
376 bool IsSignaled() const override; 338 s64 GetScheduledCount() const {
377 339 return m_schedule_count;
378 void DoWorkerTaskImpl(); 340 }
341 void IncrementScheduledCount() {
342 ++m_schedule_count;
343 }
379 344
380 Result SetActivity(ProcessActivity activity); 345 void IncrementRunningThreadCount();
346 void DecrementRunningThreadCount();
381 347
382 void PinCurrentThread(s32 core_id); 348 size_t GetRequiredSecureMemorySizeNonDefault() const {
383 void UnpinCurrentThread(s32 core_id); 349 if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
384 void UnpinThread(KThread* thread); 350 auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
351 return secure_system_resource->CalculateRequiredSecureMemorySize();
352 }
385 353
386 KLightLock& GetStateLock() { 354 return 0;
387 return m_state_lock;
388 } 355 }
389 356
390 Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); 357 size_t GetRequiredSecureMemorySize() const {
391 void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); 358 if (m_system_resource->IsSecureResource()) {
392 359 auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
393 /////////////////////////////////////////////////////////////////////////////////////////////// 360 return secure_system_resource->CalculateRequiredSecureMemorySize();
394 // Thread-local storage management 361 }
395
396 // Marks the next available region as used and returns the address of the slot.
397 [[nodiscard]] Result CreateThreadLocalRegion(KProcessAddress* out);
398 362
399 // Frees a used TLS slot identified by the given address 363 return 0;
400 Result DeleteThreadLocalRegion(KProcessAddress addr); 364 }
401 365
402 /////////////////////////////////////////////////////////////////////////////////////////////// 366 size_t GetTotalSystemResourceSize() const {
403 // Debug watchpoint management 367 if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
368 auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
369 return secure_system_resource->GetSize();
370 }
404 371
405 // Attempts to insert a watchpoint into a free slot. Returns false if none are available. 372 return 0;
406 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); 373 }
407 374
408 // Attempts to remove the watchpoint specified by the given parameters. 375 size_t GetUsedSystemResourceSize() const {
409 bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); 376 if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
377 auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
378 return secure_system_resource->GetUsedSize();
379 }
410 380
411 const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { 381 return 0;
412 return m_watchpoints;
413 } 382 }
414 383
415 const std::string& GetName() { 384 void SetRunningThread(s32 core, KThread* thread, u64 idle_count, u64 switch_count) {
416 return name; 385 m_running_threads[core] = thread;
386 m_running_thread_idle_counts[core] = idle_count;
387 m_running_thread_switch_counts[core] = switch_count;
417 } 388 }
418 389
419private: 390 void ClearRunningThread(KThread* thread) {
420 void PinThread(s32 core_id, KThread* thread) { 391 for (size_t i = 0; i < m_running_threads.size(); ++i) {
421 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES)); 392 if (m_running_threads[i] == thread) {
422 ASSERT(thread != nullptr); 393 m_running_threads[i] = nullptr;
423 ASSERT(m_pinned_threads[core_id] == nullptr); 394 }
424 m_pinned_threads[core_id] = thread; 395 }
425 } 396 }
426 397
427 void UnpinThread(s32 core_id, KThread* thread) { 398 const KSystemResource& GetSystemResource() const {
428 ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES)); 399 return *m_system_resource;
429 ASSERT(thread != nullptr);
430 ASSERT(m_pinned_threads[core_id] == thread);
431 m_pinned_threads[core_id] = nullptr;
432 } 400 }
433 401
434 void FinalizeHandleTable() { 402 const KMemoryBlockSlabManager& GetMemoryBlockSlabManager() const {
435 // Finalize the table. 403 return m_system_resource->GetMemoryBlockSlabManager();
436 m_handle_table.Finalize(); 404 }
437 405 const KBlockInfoManager& GetBlockInfoManager() const {
438 // Note that the table is finalized. 406 return m_system_resource->GetBlockInfoManager();
439 m_is_handle_table_initialized = false; 407 }
408 const KPageTableManager& GetPageTableManager() const {
409 return m_system_resource->GetPageTableManager();
440 } 410 }
441 411
442 void ChangeState(State new_state); 412 KThread* GetRunningThread(s32 core) const {
443 413 return m_running_threads[core];
444 /// Allocates the main thread stack for the process, given the stack size in bytes. 414 }
445 Result AllocateMainThreadStack(std::size_t stack_size); 415 u64 GetRunningThreadIdleCount(s32 core) const {
446 416 return m_running_thread_idle_counts[core];
447 /// Memory manager for this process 417 }
448 KPageTable m_page_table; 418 u64 GetRunningThreadSwitchCount(s32 core) const {
449 419 return m_running_thread_switch_counts[core];
450 /// Current status of the process 420 }
451 State m_state{};
452 421
453 /// The ID of this process 422 void RegisterThread(KThread* thread);
454 u64 m_process_id = 0; 423 void UnregisterThread(KThread* thread);
455 424
456 /// Title ID corresponding to the process 425 Result Run(s32 priority, size_t stack_size);
457 u64 m_program_id = 0;
458 426
459 /// Specifies additional memory to be reserved for the process's memory management by the 427 Result Reset();
460 /// system. When this is non-zero, secure memory is allocated and used for page table allocation
461 /// instead of using the normal global page tables/memory block management.
462 u32 m_system_resource_size = 0;
463 428
464 /// Resource limit descriptor for this process 429 void SetDebugBreak() {
465 KResourceLimit* m_resource_limit{}; 430 if (m_state == State::RunningAttached) {
431 this->ChangeState(State::DebugBreak);
432 }
433 }
466 434
467 KVirtualAddress m_system_resource_address{}; 435 void SetAttached() {
436 if (m_state == State::DebugBreak) {
437 this->ChangeState(State::RunningAttached);
438 }
439 }
468 440
469 /// The ideal CPU core for this process, threads are scheduled on this core by default. 441 Result SetActivity(Svc::ProcessActivity activity);
470 u8 m_ideal_core = 0;
471 442
472 /// Contains the parsed process capability descriptors. 443 void PinCurrentThread();
473 ProcessCapabilities m_capabilities; 444 void UnpinCurrentThread();
445 void UnpinThread(KThread* thread);
474 446
475 /// Whether or not this process is AArch64, or AArch32. 447 void SignalConditionVariable(uintptr_t cv_key, int32_t count) {
476 /// By default, we currently assume this is true, unless otherwise 448 return m_cond_var.Signal(cv_key, count);
477 /// specified by metadata provided to the process during loading. 449 }
478 bool m_is_64bit_process = true;
479 450
480 /// Total running time for the process in ticks. 451 Result WaitConditionVariable(KProcessAddress address, uintptr_t cv_key, u32 tag, s64 ns) {
481 std::atomic<u64> m_total_process_running_time_ticks = 0; 452 R_RETURN(m_cond_var.Wait(address, cv_key, tag, ns));
453 }
482 454
483 /// Per-process handle table for storing created object handles in. 455 Result SignalAddressArbiter(uintptr_t address, Svc::SignalType signal_type, s32 value,
484 KHandleTable m_handle_table; 456 s32 count) {
457 R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
458 }
485 459
486 /// Per-process address arbiter. 460 Result WaitAddressArbiter(uintptr_t address, Svc::ArbitrationType arb_type, s32 value,
487 KAddressArbiter m_address_arbiter; 461 s64 timeout) {
462 R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
463 }
488 464
489 /// The per-process mutex lock instance used for handling various 465 Result GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, s32 max_out_count);
490 /// forms of services, such as lock arbitration, and condition
491 /// variable related facilities.
492 KConditionVariable m_condition_var;
493 466
494 /// Address indicating the location of the process' dedicated TLS region. 467 static void Switch(KProcess* cur_process, KProcess* next_process);
495 KProcessAddress m_plr_address = 0;
496 468
497 /// Address indicating the location of the process's entry point. 469public:
498 KProcessAddress m_code_address = 0; 470 // Attempts to insert a watchpoint into a free slot. Returns false if none are available.
471 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
499 472
500 /// Random values for svcGetInfo RandomEntropy 473 // Attempts to remove the watchpoint specified by the given parameters.
501 std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{}; 474 bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
502 475
503 /// List of threads that are running with this process as their owner. 476 const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
504 std::list<KThread*> m_thread_list; 477 return m_watchpoints;
478 }
505 479
506 /// List of shared memory that are running with this process as their owner. 480public:
507 std::list<KSharedMemoryInfo*> m_shared_memory_list; 481 Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
482 bool is_hbl);
508 483
509 /// Address of the top of the main thread's stack 484 void LoadModule(CodeSet code_set, KProcessAddress base_addr);
510 KProcessAddress m_main_thread_stack_top{};
511 485
512 /// Size of the main thread's stack 486 Core::Memory::Memory& GetMemory() const;
513 std::size_t m_main_thread_stack_size{};
514 487
515 /// Memory usage capacity for the process 488public:
516 std::size_t m_memory_usage_capacity{}; 489 // Overridden parent functions.
490 bool IsInitialized() const override {
491 return m_is_initialized;
492 }
517 493
518 /// Process total image size 494 static void PostDestroy(uintptr_t arg) {}
519 std::size_t m_image_size{};
520 495
521 /// Schedule count of this process 496 void Finalize() override;
522 s64 m_schedule_count{};
523 497
524 size_t m_memory_release_hint{}; 498 u64 GetIdImpl() const {
499 return this->GetProcessId();
500 }
501 u64 GetId() const override {
502 return this->GetIdImpl();
503 }
525 504
526 std::string name{}; 505 virtual bool IsSignaled() const override {
506 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
507 return m_is_signaled;
508 }
527 509
528 bool m_is_signaled{}; 510 void DoWorkerTaskImpl();
529 bool m_is_suspended{};
530 bool m_is_immortal{};
531 bool m_is_handle_table_initialized{};
532 bool m_is_initialized{};
533 bool m_is_hbl{};
534 511
535 std::atomic<u16> m_num_running_threads{}; 512private:
513 void ChangeState(State new_state) {
514 if (m_state != new_state) {
515 m_state = new_state;
516 m_is_signaled = true;
517 this->NotifyAvailable();
518 }
519 }
536 520
537 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_running_threads{}; 521 Result InitializeHandleTable(s32 size) {
538 std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{}; 522 // Try to initialize the handle table.
539 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{}; 523 R_TRY(m_handle_table.Initialize(size));
540 std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
541 std::map<KProcessAddress, u64> m_debug_page_refcounts;
542 524
543 KThread* m_exception_thread{}; 525 // We succeeded, so note that we did.
526 m_is_handle_table_initialized = true;
527 R_SUCCEED();
528 }
544 529
545 KLightLock m_state_lock; 530 void FinalizeHandleTable() {
546 KLightLock m_list_lock; 531 // Finalize the table.
532 m_handle_table.Finalize();
547 533
548 using TLPTree = 534 // Note that the table is finalized.
549 Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; 535 m_is_handle_table_initialized = false;
550 using TLPIterator = TLPTree::iterator; 536 }
551 TLPTree m_fully_used_tlp_tree;
552 TLPTree m_partially_used_tlp_tree;
553}; 537};
554 538
555} // namespace Kernel 539} // namespace Kernel
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index d8143c650..1bce63a56 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -190,7 +190,7 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) {
190 if (m_state.should_count_idle) { 190 if (m_state.should_count_idle) {
191 if (highest_thread != nullptr) [[likely]] { 191 if (highest_thread != nullptr) [[likely]] {
192 if (KProcess* process = highest_thread->GetOwnerProcess(); process != nullptr) { 192 if (KProcess* process = highest_thread->GetOwnerProcess(); process != nullptr) {
193 process->SetRunningThread(m_core_id, highest_thread, m_state.idle_count); 193 process->SetRunningThread(m_core_id, highest_thread, m_state.idle_count, 0);
194 } 194 }
195 } else { 195 } else {
196 m_state.idle_count++; 196 m_state.idle_count++;
@@ -356,7 +356,7 @@ void KScheduler::SwitchThread(KThread* next_thread) {
356 const s64 tick_diff = cur_tick - prev_tick; 356 const s64 tick_diff = cur_tick - prev_tick;
357 cur_thread->AddCpuTime(m_core_id, tick_diff); 357 cur_thread->AddCpuTime(m_core_id, tick_diff);
358 if (cur_process != nullptr) { 358 if (cur_process != nullptr) {
359 cur_process->UpdateCPUTimeTicks(tick_diff); 359 cur_process->AddCpuTime(tick_diff);
360 } 360 }
361 m_last_context_switch_time = cur_tick; 361 m_last_context_switch_time = cur_tick;
362 362
diff --git a/src/core/hle/kernel/k_system_resource.cpp b/src/core/hle/kernel/k_system_resource.cpp
index e6c8d589a..07e92aa80 100644
--- a/src/core/hle/kernel/k_system_resource.cpp
+++ b/src/core/hle/kernel/k_system_resource.cpp
@@ -1,25 +1,100 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
5#include "core/hle/kernel/k_scoped_resource_reservation.h"
4#include "core/hle/kernel/k_system_resource.h" 6#include "core/hle/kernel/k_system_resource.h"
5 7
6namespace Kernel { 8namespace Kernel {
7 9
8Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_limit, 10Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_limit,
9 KMemoryManager::Pool pool) { 11 KMemoryManager::Pool pool) {
10 // Unimplemented 12 // Set members.
11 UNREACHABLE(); 13 m_resource_limit = resource_limit;
14 m_resource_size = size;
15 m_resource_pool = pool;
16
17 // Determine required size for our secure resource.
18 const size_t secure_size = this->CalculateRequiredSecureMemorySize();
19
20 // Reserve memory for our secure resource.
21 KScopedResourceReservation memory_reservation(
22 m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, secure_size);
23 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
24
25 // Allocate secure memory.
26 R_TRY(KSystemControl::AllocateSecureMemory(m_kernel, std::addressof(m_resource_address),
27 m_resource_size, static_cast<u32>(m_resource_pool)));
28 ASSERT(m_resource_address != 0);
29
30 // Ensure we clean up the secure memory, if we fail past this point.
31 ON_RESULT_FAILURE {
32 KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size,
33 static_cast<u32>(m_resource_pool));
34 };
35
36 // Check that our allocation is bigger than the reference counts needed for it.
37 const size_t rc_size =
38 Common::AlignUp(KPageTableSlabHeap::CalculateReferenceCountSize(m_resource_size), PageSize);
39 R_UNLESS(m_resource_size > rc_size, ResultOutOfMemory);
40
41 // Get resource pointer.
42 KPhysicalAddress resource_paddr =
43 KPageTable::GetHeapPhysicalAddress(m_kernel.MemoryLayout(), m_resource_address);
44 auto* resource =
45 m_kernel.System().DeviceMemory().GetPointer<KPageTableManager::RefCount>(resource_paddr);
46
47 // Initialize slab heaps.
48 m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size,
49 PageSize);
50 m_page_table_heap.Initialize(std::addressof(m_dynamic_page_manager), 0, resource);
51 m_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
52 m_block_info_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
53
54 // Initialize managers.
55 m_page_table_manager.Initialize(std::addressof(m_dynamic_page_manager),
56 std::addressof(m_page_table_heap));
57 m_memory_block_slab_manager.Initialize(std::addressof(m_dynamic_page_manager),
58 std::addressof(m_memory_block_heap));
59 m_block_info_manager.Initialize(std::addressof(m_dynamic_page_manager),
60 std::addressof(m_block_info_heap));
61
62 // Set our managers.
63 this->SetManagers(m_memory_block_slab_manager, m_block_info_manager, m_page_table_manager);
64
65 // Commit the memory reservation.
66 memory_reservation.Commit();
67
68 // Open reference to our resource limit.
69 m_resource_limit->Open();
70
71 // Set ourselves as initialized.
72 m_is_initialized = true;
73
74 R_SUCCEED();
12} 75}
13 76
14void KSecureSystemResource::Finalize() { 77void KSecureSystemResource::Finalize() {
15 // Unimplemented 78 // Check that we have no outstanding allocations.
16 UNREACHABLE(); 79 ASSERT(m_memory_block_slab_manager.GetUsed() == 0);
80 ASSERT(m_block_info_manager.GetUsed() == 0);
81 ASSERT(m_page_table_manager.GetUsed() == 0);
82
83 // Free our secure memory.
84 KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size,
85 static_cast<u32>(m_resource_pool));
86
87 // Release the memory reservation.
88 m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
89 this->CalculateRequiredSecureMemorySize());
90
91 // Close reference to our resource limit.
92 m_resource_limit->Close();
17} 93}
18 94
19size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, 95size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size,
20 KMemoryManager::Pool pool) { 96 KMemoryManager::Pool pool) {
21 // Unimplemented 97 return KSystemControl::CalculateRequiredSecureMemorySize(size, static_cast<u32>(pool));
22 UNREACHABLE();
23} 98}
24 99
25} // namespace Kernel 100} // namespace Kernel
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 7df8fd7f7..a6deb50ec 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -122,16 +122,15 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress
122 case ThreadType::Main: 122 case ThreadType::Main:
123 ASSERT(arg == 0); 123 ASSERT(arg == 0);
124 [[fallthrough]]; 124 [[fallthrough]];
125 case ThreadType::HighPriority:
126 [[fallthrough]];
127 case ThreadType::Dummy:
128 [[fallthrough]];
129 case ThreadType::User: 125 case ThreadType::User:
130 ASSERT(((owner == nullptr) || 126 ASSERT(((owner == nullptr) ||
131 (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask())); 127 (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
132 ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) || 128 ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
133 (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask())); 129 (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
134 break; 130 break;
131 case ThreadType::HighPriority:
132 case ThreadType::Dummy:
133 break;
135 case ThreadType::Kernel: 134 case ThreadType::Kernel:
136 UNIMPLEMENTED(); 135 UNIMPLEMENTED();
137 break; 136 break;
@@ -216,6 +215,7 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress
216 // Setup the TLS, if needed. 215 // Setup the TLS, if needed.
217 if (type == ThreadType::User) { 216 if (type == ThreadType::User) {
218 R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address))); 217 R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address)));
218 owner->GetMemory().ZeroBlock(m_tls_address, Svc::ThreadLocalRegionSize);
219 } 219 }
220 220
221 m_parent = owner; 221 m_parent = owner;
@@ -403,7 +403,7 @@ void KThread::StartTermination() {
403 if (m_parent != nullptr) { 403 if (m_parent != nullptr) {
404 m_parent->ReleaseUserException(this); 404 m_parent->ReleaseUserException(this);
405 if (m_parent->GetPinnedThread(GetCurrentCoreId(m_kernel)) == this) { 405 if (m_parent->GetPinnedThread(GetCurrentCoreId(m_kernel)) == this) {
406 m_parent->UnpinCurrentThread(m_core_id); 406 m_parent->UnpinCurrentThread();
407 } 407 }
408 } 408 }
409 409
@@ -415,10 +415,6 @@ void KThread::StartTermination() {
415 m_parent->ClearRunningThread(this); 415 m_parent->ClearRunningThread(this);
416 } 416 }
417 417
418 // Signal.
419 m_signaled = true;
420 KSynchronizationObject::NotifyAvailable();
421
422 // Clear previous thread in KScheduler. 418 // Clear previous thread in KScheduler.
423 KScheduler::ClearPreviousThread(m_kernel, this); 419 KScheduler::ClearPreviousThread(m_kernel, this);
424 420
@@ -437,6 +433,13 @@ void KThread::FinishTermination() {
437 } 433 }
438 } 434 }
439 435
436 // Acquire the scheduler lock.
437 KScopedSchedulerLock sl{m_kernel};
438
439 // Signal.
440 m_signaled = true;
441 KSynchronizationObject::NotifyAvailable();
442
440 // Close the thread. 443 // Close the thread.
441 this->Close(); 444 this->Close();
442} 445}
@@ -820,7 +823,7 @@ void KThread::CloneFpuStatus() {
820 ASSERT(this->GetOwnerProcess() != nullptr); 823 ASSERT(this->GetOwnerProcess() != nullptr);
821 ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(m_kernel)); 824 ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(m_kernel));
822 825
823 if (this->GetOwnerProcess()->Is64BitProcess()) { 826 if (this->GetOwnerProcess()->Is64Bit()) {
824 // Clone FPSR and FPCR. 827 // Clone FPSR and FPCR.
825 ThreadContext64 cur_ctx{}; 828 ThreadContext64 cur_ctx{};
826 m_kernel.System().CurrentArmInterface().SaveContext(cur_ctx); 829 m_kernel.System().CurrentArmInterface().SaveContext(cur_ctx);
@@ -923,7 +926,7 @@ Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) {
923 926
924 // If we're not terminating, get the thread's user context. 927 // If we're not terminating, get the thread's user context.
925 if (!this->IsTerminationRequested()) { 928 if (!this->IsTerminationRequested()) {
926 if (m_parent->Is64BitProcess()) { 929 if (m_parent->Is64Bit()) {
927 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. 930 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
928 auto context = GetContext64(); 931 auto context = GetContext64();
929 context.pstate &= 0xFF0FFE20; 932 context.pstate &= 0xFF0FFE20;
@@ -1174,6 +1177,9 @@ Result KThread::Run() {
1174 owner->IncrementRunningThreadCount(); 1177 owner->IncrementRunningThreadCount();
1175 } 1178 }
1176 1179
1180 // Open a reference, now that we're running.
1181 this->Open();
1182
1177 // Set our state and finish. 1183 // Set our state and finish.
1178 this->SetState(ThreadState::Runnable); 1184 this->SetState(ThreadState::Runnable);
1179 1185
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index d178c2453..e1f80b04f 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -721,6 +721,7 @@ private:
721 // For core KThread implementation 721 // For core KThread implementation
722 ThreadContext32 m_thread_context_32{}; 722 ThreadContext32 m_thread_context_32{};
723 ThreadContext64 m_thread_context_64{}; 723 ThreadContext64 m_thread_context_64{};
724 Common::IntrusiveListNode m_process_list_node;
724 Common::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{}; 725 Common::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{};
725 s32 m_priority{}; 726 s32 m_priority{};
726 using ConditionVariableThreadTreeTraits = 727 using ConditionVariableThreadTreeTraits =
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 24433d32b..4a1559291 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -101,35 +101,31 @@ struct KernelCore::Impl {
101 101
102 void InitializeCores() { 102 void InitializeCores() {
103 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { 103 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
104 cores[core_id]->Initialize((*application_process).Is64BitProcess()); 104 cores[core_id]->Initialize((*application_process).Is64Bit());
105 system.ApplicationMemory().SetCurrentPageTable(*application_process, core_id); 105 system.ApplicationMemory().SetCurrentPageTable(*application_process, core_id);
106 } 106 }
107 } 107 }
108 108
109 void CloseApplicationProcess() { 109 void TerminateApplicationProcess() {
110 KProcess* old_process = application_process.exchange(nullptr); 110 application_process.load()->Terminate();
111 if (old_process == nullptr) {
112 return;
113 }
114
115 // old_process->Close();
116 // TODO: The process should be destroyed based on accurate ref counting after
117 // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
118 old_process->Finalize();
119 old_process->Destroy();
120 } 111 }
121 112
122 void Shutdown() { 113 void Shutdown() {
123 is_shutting_down.store(true, std::memory_order_relaxed); 114 is_shutting_down.store(true, std::memory_order_relaxed);
124 SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); }); 115 SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); });
125 116
126 process_list.clear();
127
128 CloseServices(); 117 CloseServices();
129 118
119 auto* old_process = application_process.exchange(nullptr);
120 if (old_process) {
121 old_process->Close();
122 }
123
124 process_list.clear();
125
130 next_object_id = 0; 126 next_object_id = 0;
131 next_kernel_process_id = KProcess::InitialKIPIDMin; 127 next_kernel_process_id = KProcess::InitialProcessIdMin;
132 next_user_process_id = KProcess::ProcessIDMin; 128 next_user_process_id = KProcess::ProcessIdMin;
133 next_thread_id = 1; 129 next_thread_id = 1;
134 130
135 global_handle_table->Finalize(); 131 global_handle_table->Finalize();
@@ -176,8 +172,6 @@ struct KernelCore::Impl {
176 } 172 }
177 } 173 }
178 174
179 CloseApplicationProcess();
180
181 // Track kernel objects that were not freed on shutdown 175 // Track kernel objects that were not freed on shutdown
182 { 176 {
183 std::scoped_lock lk{registered_objects_lock}; 177 std::scoped_lock lk{registered_objects_lock};
@@ -344,6 +338,8 @@ struct KernelCore::Impl {
344 // Create the system page table managers. 338 // Create the system page table managers.
345 app_system_resource = std::make_unique<KSystemResource>(kernel); 339 app_system_resource = std::make_unique<KSystemResource>(kernel);
346 sys_system_resource = std::make_unique<KSystemResource>(kernel); 340 sys_system_resource = std::make_unique<KSystemResource>(kernel);
341 KAutoObject::Create(std::addressof(*app_system_resource));
342 KAutoObject::Create(std::addressof(*sys_system_resource));
347 343
348 // Set the managers for the system resources. 344 // Set the managers for the system resources.
349 app_system_resource->SetManagers(*app_memory_block_manager, *app_block_info_manager, 345 app_system_resource->SetManagers(*app_memory_block_manager, *app_block_info_manager,
@@ -792,8 +788,8 @@ struct KernelCore::Impl {
792 std::mutex registered_in_use_objects_lock; 788 std::mutex registered_in_use_objects_lock;
793 789
794 std::atomic<u32> next_object_id{0}; 790 std::atomic<u32> next_object_id{0};
795 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; 791 std::atomic<u64> next_kernel_process_id{KProcess::InitialProcessIdMin};
796 std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; 792 std::atomic<u64> next_user_process_id{KProcess::ProcessIdMin};
797 std::atomic<u64> next_thread_id{1}; 793 std::atomic<u64> next_thread_id{1};
798 794
799 // Lists all processes that exist in the current session. 795 // Lists all processes that exist in the current session.
@@ -924,10 +920,6 @@ const KProcess* KernelCore::ApplicationProcess() const {
924 return impl->application_process; 920 return impl->application_process;
925} 921}
926 922
927void KernelCore::CloseApplicationProcess() {
928 impl->CloseApplicationProcess();
929}
930
931const std::vector<KProcess*>& KernelCore::GetProcessList() const { 923const std::vector<KProcess*>& KernelCore::GetProcessList() const {
932 return impl->process_list; 924 return impl->process_list;
933} 925}
@@ -1128,8 +1120,8 @@ std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name,
1128 std::function<void()> func) { 1120 std::function<void()> func) {
1129 // Make a new process. 1121 // Make a new process.
1130 KProcess* process = KProcess::Create(*this); 1122 KProcess* process = KProcess::Create(*this);
1131 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland, 1123 ASSERT(R_SUCCEEDED(
1132 GetSystemResourceLimit()))); 1124 process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false)));
1133 1125
1134 // Ensure that we don't hold onto any extra references. 1126 // Ensure that we don't hold onto any extra references.
1135 SCOPE_EXIT({ process->Close(); }); 1127 SCOPE_EXIT({ process->Close(); });
@@ -1156,8 +1148,8 @@ void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function
1156 1148
1157 // Make a new process. 1149 // Make a new process.
1158 KProcess* process = KProcess::Create(*this); 1150 KProcess* process = KProcess::Create(*this);
1159 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland, 1151 ASSERT(R_SUCCEEDED(
1160 GetSystemResourceLimit()))); 1152 process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false)));
1161 1153
1162 // Ensure that we don't hold onto any extra references. 1154 // Ensure that we don't hold onto any extra references.
1163 SCOPE_EXIT({ process->Close(); }); 1155 SCOPE_EXIT({ process->Close(); });
@@ -1266,7 +1258,8 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const {
1266 1258
1267void KernelCore::SuspendApplication(bool suspended) { 1259void KernelCore::SuspendApplication(bool suspended) {
1268 const bool should_suspend{exception_exited || suspended}; 1260 const bool should_suspend{exception_exited || suspended};
1269 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; 1261 const auto activity =
1262 should_suspend ? Svc::ProcessActivity::Paused : Svc::ProcessActivity::Runnable;
1270 1263
1271 // Get the application process. 1264 // Get the application process.
1272 KScopedAutoObject<KProcess> process = ApplicationProcess(); 1265 KScopedAutoObject<KProcess> process = ApplicationProcess();
@@ -1300,6 +1293,8 @@ void KernelCore::SuspendApplication(bool suspended) {
1300} 1293}
1301 1294
1302void KernelCore::ShutdownCores() { 1295void KernelCore::ShutdownCores() {
1296 impl->TerminateApplicationProcess();
1297
1303 KScopedSchedulerLock lk{*this}; 1298 KScopedSchedulerLock lk{*this};
1304 1299
1305 for (auto* thread : impl->shutdown_threads) { 1300 for (auto* thread : impl->shutdown_threads) {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index d5b08eeb5..d8086c0ea 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -134,9 +134,6 @@ public:
134 /// Retrieves a const pointer to the application process. 134 /// Retrieves a const pointer to the application process.
135 const KProcess* ApplicationProcess() const; 135 const KProcess* ApplicationProcess() const;
136 136
137 /// Closes the application process.
138 void CloseApplicationProcess();
139
140 /// Retrieves the list of processes. 137 /// Retrieves the list of processes.
141 const std::vector<KProcess*>& GetProcessList() const; 138 const std::vector<KProcess*>& GetProcessList() const;
142 139
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 871d541d4..b76683969 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -4426,7 +4426,7 @@ void Call(Core::System& system, u32 imm) {
4426 auto& kernel = system.Kernel(); 4426 auto& kernel = system.Kernel();
4427 kernel.EnterSVCProfile(); 4427 kernel.EnterSVCProfile();
4428 4428
4429 if (GetCurrentProcess(system.Kernel()).Is64BitProcess()) { 4429 if (GetCurrentProcess(system.Kernel()).Is64Bit()) {
4430 Call64(system, imm); 4430 Call64(system, imm);
4431 } else { 4431 } else {
4432 Call32(system, imm); 4432 Call32(system, imm);
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index f99964028..ada998772 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -86,20 +86,19 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
86 R_SUCCEED(); 86 R_SUCCEED();
87 87
88 case InfoType::TotalMemorySize: 88 case InfoType::TotalMemorySize:
89 *result = process->GetTotalPhysicalMemoryAvailable(); 89 *result = process->GetTotalUserPhysicalMemorySize();
90 R_SUCCEED(); 90 R_SUCCEED();
91 91
92 case InfoType::UsedMemorySize: 92 case InfoType::UsedMemorySize:
93 *result = process->GetTotalPhysicalMemoryUsed(); 93 *result = process->GetUsedUserPhysicalMemorySize();
94 R_SUCCEED(); 94 R_SUCCEED();
95 95
96 case InfoType::SystemResourceSizeTotal: 96 case InfoType::SystemResourceSizeTotal:
97 *result = process->GetSystemResourceSize(); 97 *result = process->GetTotalSystemResourceSize();
98 R_SUCCEED(); 98 R_SUCCEED();
99 99
100 case InfoType::SystemResourceSizeUsed: 100 case InfoType::SystemResourceSizeUsed:
101 LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query system resource usage"); 101 *result = process->GetUsedSystemResourceSize();
102 *result = process->GetSystemResourceUsage();
103 R_SUCCEED(); 102 R_SUCCEED();
104 103
105 case InfoType::ProgramId: 104 case InfoType::ProgramId:
@@ -111,20 +110,29 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
111 R_SUCCEED(); 110 R_SUCCEED();
112 111
113 case InfoType::TotalNonSystemMemorySize: 112 case InfoType::TotalNonSystemMemorySize:
114 *result = process->GetTotalPhysicalMemoryAvailableWithoutSystemResource(); 113 *result = process->GetTotalNonSystemUserPhysicalMemorySize();
115 R_SUCCEED(); 114 R_SUCCEED();
116 115
117 case InfoType::UsedNonSystemMemorySize: 116 case InfoType::UsedNonSystemMemorySize:
118 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); 117 *result = process->GetUsedNonSystemUserPhysicalMemorySize();
119 R_SUCCEED(); 118 R_SUCCEED();
120 119
121 case InfoType::IsApplication: 120 case InfoType::IsApplication:
122 LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application"); 121 LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application");
123 *result = true; 122 *result = process->IsApplication();
124 R_SUCCEED(); 123 R_SUCCEED();
125 124
126 case InfoType::FreeThreadCount: 125 case InfoType::FreeThreadCount:
127 *result = process->GetFreeThreadCount(); 126 if (KResourceLimit* resource_limit = process->GetResourceLimit();
127 resource_limit != nullptr) {
128 const auto current_value =
129 resource_limit->GetCurrentValue(Svc::LimitableResource::ThreadCountMax);
130 const auto limit_value =
131 resource_limit->GetLimitValue(Svc::LimitableResource::ThreadCountMax);
132 *result = limit_value - current_value;
133 } else {
134 *result = 0;
135 }
128 R_SUCCEED(); 136 R_SUCCEED();
129 137
130 default: 138 default:
@@ -161,7 +169,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
161 169
162 case InfoType::RandomEntropy: 170 case InfoType::RandomEntropy:
163 R_UNLESS(handle == 0, ResultInvalidHandle); 171 R_UNLESS(handle == 0, ResultInvalidHandle);
164 R_UNLESS(info_sub_id < KProcess::RANDOM_ENTROPY_SIZE, ResultInvalidCombination); 172 R_UNLESS(info_sub_id < 4, ResultInvalidCombination);
165 173
166 *result = GetCurrentProcess(system.Kernel()).GetRandomEntropy(info_sub_id); 174 *result = GetCurrentProcess(system.Kernel()).GetRandomEntropy(info_sub_id);
167 R_SUCCEED(); 175 R_SUCCEED();
diff --git a/src/core/hle/kernel/svc/svc_lock.cpp b/src/core/hle/kernel/svc/svc_lock.cpp
index 1d7bc4246..5f0833fcb 100644
--- a/src/core/hle/kernel/svc/svc_lock.cpp
+++ b/src/core/hle/kernel/svc/svc_lock.cpp
@@ -17,7 +17,7 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, u64 address, u3
17 R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory); 17 R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory);
18 R_UNLESS(Common::IsAligned(address, sizeof(u32)), ResultInvalidAddress); 18 R_UNLESS(Common::IsAligned(address, sizeof(u32)), ResultInvalidAddress);
19 19
20 R_RETURN(GetCurrentProcess(system.Kernel()).WaitForAddress(thread_handle, address, tag)); 20 R_RETURN(KConditionVariable::WaitForAddress(system.Kernel(), thread_handle, address, tag));
21} 21}
22 22
23/// Unlock a mutex 23/// Unlock a mutex
@@ -28,7 +28,7 @@ Result ArbitrateUnlock(Core::System& system, u64 address) {
28 R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory); 28 R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory);
29 R_UNLESS(Common::IsAligned(address, sizeof(u32)), ResultInvalidAddress); 29 R_UNLESS(Common::IsAligned(address, sizeof(u32)), ResultInvalidAddress);
30 30
31 R_RETURN(GetCurrentProcess(system.Kernel()).SignalToAddress(address)); 31 R_RETURN(KConditionVariable::SignalToAddress(system.Kernel(), address));
32} 32}
33 33
34Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag) { 34Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag) {
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index d3545f232..99330d02a 100644
--- a/src/core/hle/kernel/svc/svc_physical_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp
@@ -46,7 +46,7 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
46 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; 46 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
47 auto& page_table{current_process->GetPageTable()}; 47 auto& page_table{current_process->GetPageTable()};
48 48
49 if (current_process->GetSystemResourceSize() == 0) { 49 if (current_process->GetTotalSystemResourceSize() == 0) {
50 LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); 50 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
51 R_THROW(ResultInvalidState); 51 R_THROW(ResultInvalidState);
52 } 52 }
@@ -95,7 +95,7 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
95 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; 95 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
96 auto& page_table{current_process->GetPageTable()}; 96 auto& page_table{current_process->GetPageTable()};
97 97
98 if (current_process->GetSystemResourceSize() == 0) { 98 if (current_process->GetTotalSystemResourceSize() == 0) {
99 LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); 99 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
100 R_THROW(ResultInvalidState); 100 R_THROW(ResultInvalidState);
101 } 101 }
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 8ebc1bd1c..6c79cfd8d 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -132,7 +132,7 @@ void SynchronizePreemptionState(Core::System& system) {
132 GetCurrentThread(kernel).ClearInterruptFlag(); 132 GetCurrentThread(kernel).ClearInterruptFlag();
133 133
134 // Unpin the current thread. 134 // Unpin the current thread.
135 cur_process->UnpinCurrentThread(core_id); 135 cur_process->UnpinCurrentThread();
136 } 136 }
137} 137}
138 138
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index 933b82e30..755fd62b5 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -85,10 +85,6 @@ Result StartThread(Core::System& system, Handle thread_handle) {
85 // Try to start the thread. 85 // Try to start the thread.
86 R_TRY(thread->Run()); 86 R_TRY(thread->Run());
87 87
88 // If we succeeded, persist a reference to the thread.
89 thread->Open();
90 system.Kernel().RegisterInUseObject(thread.GetPointerUnsafe());
91
92 R_SUCCEED(); 88 R_SUCCEED();
93} 89}
94 90
@@ -99,7 +95,6 @@ void ExitThread(Core::System& system) {
99 auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); 95 auto* const current_thread = GetCurrentThreadPointer(system.Kernel());
100 system.GlobalSchedulerContext().RemoveThread(current_thread); 96 system.GlobalSchedulerContext().RemoveThread(current_thread);
101 current_thread->Exit(); 97 current_thread->Exit();
102 system.Kernel().UnregisterInUseObject(current_thread);
103} 98}
104 99
105/// Sleep the current thread 100/// Sleep the current thread
@@ -260,7 +255,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_
260 255
261 auto list_iter = thread_list.cbegin(); 256 auto list_iter = thread_list.cbegin();
262 for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { 257 for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) {
263 memory.Write64(out_thread_ids, (*list_iter)->GetThreadId()); 258 memory.Write64(out_thread_ids, list_iter->GetThreadId());
264 out_thread_ids += sizeof(u64); 259 out_thread_ids += sizeof(u64);
265 } 260 }
266 261
diff --git a/src/core/hle/kernel/svc_generator.py b/src/core/hle/kernel/svc_generator.py
index 7fcbb1ba1..5531faac6 100644
--- a/src/core/hle/kernel/svc_generator.py
+++ b/src/core/hle/kernel/svc_generator.py
@@ -592,7 +592,7 @@ void Call(Core::System& system, u32 imm) {
592 auto& kernel = system.Kernel(); 592 auto& kernel = system.Kernel();
593 kernel.EnterSVCProfile(); 593 kernel.EnterSVCProfile();
594 594
595 if (GetCurrentProcess(system.Kernel()).Is64BitProcess()) { 595 if (GetCurrentProcess(system.Kernel()).Is64Bit()) {
596 Call64(system, imm); 596 Call64(system, imm);
597 } else { 597 } else {
598 Call32(system, imm); 598 Call32(system, imm);
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index 251e6013c..50de02e36 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -604,13 +604,57 @@ enum class ProcessActivity : u32 {
604 Paused, 604 Paused,
605}; 605};
606 606
607enum class CreateProcessFlag : u32 {
608 // Is 64 bit?
609 Is64Bit = (1 << 0),
610
611 // What kind of address space?
612 AddressSpaceShift = 1,
613 AddressSpaceMask = (7 << AddressSpaceShift),
614 AddressSpace32Bit = (0 << AddressSpaceShift),
615 AddressSpace64BitDeprecated = (1 << AddressSpaceShift),
616 AddressSpace32BitWithoutAlias = (2 << AddressSpaceShift),
617 AddressSpace64Bit = (3 << AddressSpaceShift),
618
619 // Should JIT debug be done on crash?
620 EnableDebug = (1 << 4),
621
622 // Should ASLR be enabled for the process?
623 EnableAslr = (1 << 5),
624
625 // Is the process an application?
626 IsApplication = (1 << 6),
627
628 // 4.x deprecated: Should use secure memory?
629 DeprecatedUseSecureMemory = (1 << 7),
630
631 // 5.x+ Pool partition type.
632 PoolPartitionShift = 7,
633 PoolPartitionMask = (0xF << PoolPartitionShift),
634 PoolPartitionApplication = (0 << PoolPartitionShift),
635 PoolPartitionApplet = (1 << PoolPartitionShift),
636 PoolPartitionSystem = (2 << PoolPartitionShift),
637 PoolPartitionSystemNonSecure = (3 << PoolPartitionShift),
638
639 // 7.x+ Should memory allocation be optimized? This requires IsApplication.
640 OptimizeMemoryAllocation = (1 << 11),
641
642 // 11.x+ DisableDeviceAddressSpaceMerge.
643 DisableDeviceAddressSpaceMerge = (1 << 12),
644
645 // Mask of all flags.
646 All = Is64Bit | AddressSpaceMask | EnableDebug | EnableAslr | IsApplication |
647 PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge,
648};
649DECLARE_ENUM_FLAG_OPERATORS(CreateProcessFlag);
650
607struct CreateProcessParameter { 651struct CreateProcessParameter {
608 std::array<char, 12> name; 652 std::array<char, 12> name;
609 u32 version; 653 u32 version;
610 u64 program_id; 654 u64 program_id;
611 u64 code_address; 655 u64 code_address;
612 s32 code_num_pages; 656 s32 code_num_pages;
613 u32 flags; 657 CreateProcessFlag flags;
614 Handle reslimit; 658 Handle reslimit;
615 s32 system_resource_num_pages; 659 s32 system_resource_num_pages;
616}; 660};
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 98765b81a..cc643ea09 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -23,6 +23,7 @@
23#include "core/hle/service/am/applets/applet_cabinet.h" 23#include "core/hle/service/am/applets/applet_cabinet.h"
24#include "core/hle/service/am/applets/applet_mii_edit_types.h" 24#include "core/hle/service/am/applets/applet_mii_edit_types.h"
25#include "core/hle/service/am/applets/applet_profile_select.h" 25#include "core/hle/service/am/applets/applet_profile_select.h"
26#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
26#include "core/hle/service/am/applets/applet_web_browser.h" 27#include "core/hle/service/am/applets/applet_web_browser.h"
27#include "core/hle/service/am/applets/applets.h" 28#include "core/hle/service/am/applets/applets.h"
28#include "core/hle/service/am/idle.h" 29#include "core/hle/service/am/idle.h"
@@ -31,6 +32,7 @@
31#include "core/hle/service/apm/apm_controller.h" 32#include "core/hle/service/apm/apm_controller.h"
32#include "core/hle/service/apm/apm_interface.h" 33#include "core/hle/service/apm/apm_interface.h"
33#include "core/hle/service/bcat/backend/backend.h" 34#include "core/hle/service/bcat/backend/backend.h"
35#include "core/hle/service/caps/caps_su.h"
34#include "core/hle/service/caps/caps_types.h" 36#include "core/hle/service/caps/caps_types.h"
35#include "core/hle/service/filesystem/filesystem.h" 37#include "core/hle/service/filesystem/filesystem.h"
36#include "core/hle/service/ipc_helpers.h" 38#include "core/hle/service/ipc_helpers.h"
@@ -702,9 +704,17 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& c
702void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) { 704void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
703 IPC::RequestParser rp{ctx}; 705 IPC::RequestParser rp{ctx};
704 706
705 const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>(); 707 const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
706 708
707 LOG_WARNING(Service_AM, "(STUBBED) called. album_report_option={}", album_report_option); 709 LOG_INFO(Service_AM, "called, report_option={}", report_option);
710
711 const auto screenshot_service =
712 system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
713 "caps:su");
714
715 if (screenshot_service) {
716 screenshot_service->CaptureAndSaveScreenshot(report_option);
717 }
708 718
709 IPC::ResponseBuilder rb{ctx, 2}; 719 IPC::ResponseBuilder rb{ctx, 2};
710 rb.Push(ResultSuccess); 720 rb.Push(ResultSuccess);
@@ -796,7 +806,9 @@ ILockAccessor::ILockAccessor(Core::System& system_)
796 lock_event = service_context.CreateEvent("ILockAccessor::LockEvent"); 806 lock_event = service_context.CreateEvent("ILockAccessor::LockEvent");
797} 807}
798 808
799ILockAccessor::~ILockAccessor() = default; 809ILockAccessor::~ILockAccessor() {
810 service_context.CloseEvent(lock_event);
811};
800 812
801void ILockAccessor::TryLock(HLERequestContext& ctx) { 813void ILockAccessor::TryLock(HLERequestContext& ctx) {
802 IPC::RequestParser rp{ctx}; 814 IPC::RequestParser rp{ctx};
@@ -909,7 +921,9 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
909 msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); 921 msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
910} 922}
911 923
912ICommonStateGetter::~ICommonStateGetter() = default; 924ICommonStateGetter::~ICommonStateGetter() {
925 service_context.CloseEvent(sleep_lock_event);
926};
913 927
914void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) { 928void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) {
915 LOG_DEBUG(Service_AM, "called"); 929 LOG_DEBUG(Service_AM, "called");
@@ -1558,7 +1572,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
1558 {16, nullptr, "GetMainAppletStorageId"}, 1572 {16, nullptr, "GetMainAppletStorageId"},
1559 {17, nullptr, "GetCallerAppletIdentityInfoStack"}, 1573 {17, nullptr, "GetCallerAppletIdentityInfoStack"},
1560 {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"}, 1574 {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
1561 {19, nullptr, "GetDesirableKeyboardLayout"}, 1575 {19, &ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout, "GetDesirableKeyboardLayout"},
1562 {20, nullptr, "PopExtraStorage"}, 1576 {20, nullptr, "PopExtraStorage"},
1563 {25, nullptr, "GetPopExtraStorageEvent"}, 1577 {25, nullptr, "GetPopExtraStorageEvent"},
1564 {30, nullptr, "UnpopInData"}, 1578 {30, nullptr, "UnpopInData"},
@@ -1577,7 +1591,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
1577 {120, nullptr, "GetLaunchStorageInfoForDebug"}, 1591 {120, nullptr, "GetLaunchStorageInfoForDebug"},
1578 {130, nullptr, "GetGpuErrorDetectedSystemEvent"}, 1592 {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
1579 {140, nullptr, "SetApplicationMemoryReservation"}, 1593 {140, nullptr, "SetApplicationMemoryReservation"},
1580 {150, nullptr, "ShouldSetGpuTimeSliceManually"}, 1594 {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"},
1581 }; 1595 };
1582 // clang-format on 1596 // clang-format on
1583 RegisterHandlers(functions); 1597 RegisterHandlers(functions);
@@ -1592,6 +1606,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
1592 case Applets::AppletId::PhotoViewer: 1606 case Applets::AppletId::PhotoViewer:
1593 PushInShowAlbum(); 1607 PushInShowAlbum();
1594 break; 1608 break;
1609 case Applets::AppletId::SoftwareKeyboard:
1610 PushInShowSoftwareKeyboard();
1611 break;
1595 default: 1612 default:
1596 break; 1613 break;
1597 } 1614 }
@@ -1668,6 +1685,14 @@ void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext&
1668 rb.PushRaw(applet_info); 1685 rb.PushRaw(applet_info);
1669} 1686}
1670 1687
1688void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) {
1689 LOG_WARNING(Service_AM, "(STUBBED) called");
1690
1691 IPC::ResponseBuilder rb{ctx, 3};
1692 rb.Push(ResultSuccess);
1693 rb.Push<u32>(0);
1694}
1695
1671void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) { 1696void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) {
1672 const Service::Account::ProfileManager manager{}; 1697 const Service::Account::ProfileManager manager{};
1673 bool is_empty{true}; 1698 bool is_empty{true};
@@ -1687,6 +1712,14 @@ void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext&
1687 rb.Push(user_count); 1712 rb.Push(user_count);
1688} 1713}
1689 1714
1715void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext& ctx) {
1716 LOG_WARNING(Service_AM, "(STUBBED) called");
1717
1718 IPC::ResponseBuilder rb{ctx, 2};
1719 rb.Push(ResultSuccess);
1720 rb.Push<u8>(0);
1721}
1722
1690void ILibraryAppletSelfAccessor::PushInShowAlbum() { 1723void ILibraryAppletSelfAccessor::PushInShowAlbum() {
1691 const Applets::CommonArguments arguments{ 1724 const Applets::CommonArguments arguments{
1692 .arguments_version = Applets::CommonArgumentVersion::Version3, 1725 .arguments_version = Applets::CommonArgumentVersion::Version3,
@@ -1755,6 +1788,61 @@ void ILibraryAppletSelfAccessor::PushInShowMiiEditData() {
1755 queue_data.emplace_back(std::move(argument_data)); 1788 queue_data.emplace_back(std::move(argument_data));
1756} 1789}
1757 1790
1791void ILibraryAppletSelfAccessor::PushInShowSoftwareKeyboard() {
1792 const Applets::CommonArguments arguments{
1793 .arguments_version = Applets::CommonArgumentVersion::Version3,
1794 .size = Applets::CommonArgumentSize::Version3,
1795 .library_version = static_cast<u32>(Applets::SwkbdAppletVersion::Version524301),
1796 .theme_color = Applets::ThemeColor::BasicBlack,
1797 .play_startup_sound = true,
1798 .system_tick = system.CoreTiming().GetClockTicks(),
1799 };
1800
1801 std::vector<char16_t> initial_string(0);
1802
1803 const Applets::SwkbdConfigCommon swkbd_config{
1804 .type = Applets::SwkbdType::Qwerty,
1805 .ok_text{},
1806 .left_optional_symbol_key{},
1807 .right_optional_symbol_key{},
1808 .use_prediction = false,
1809 .key_disable_flags{},
1810 .initial_cursor_position = Applets::SwkbdInitialCursorPosition::Start,
1811 .header_text{},
1812 .sub_text{},
1813 .guide_text{},
1814 .max_text_length = 500,
1815 .min_text_length = 0,
1816 .password_mode = Applets::SwkbdPasswordMode::Disabled,
1817 .text_draw_type = Applets::SwkbdTextDrawType::Box,
1818 .enable_return_button = true,
1819 .use_utf8 = false,
1820 .use_blur_background = true,
1821 .initial_string_offset{},
1822 .initial_string_length = static_cast<u32>(initial_string.size()),
1823 .user_dictionary_offset{},
1824 .user_dictionary_entries{},
1825 .use_text_check = false,
1826 };
1827
1828 Applets::SwkbdConfigNew swkbd_config_new{};
1829
1830 std::vector<u8> argument_data(sizeof(arguments));
1831 std::vector<u8> swkbd_data(sizeof(swkbd_config) + sizeof(swkbd_config_new));
1832 std::vector<u8> work_buffer(swkbd_config.initial_string_length * sizeof(char16_t));
1833
1834 std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
1835 std::memcpy(swkbd_data.data(), &swkbd_config, sizeof(swkbd_config));
1836 std::memcpy(swkbd_data.data() + sizeof(swkbd_config), &swkbd_config_new,
1837 sizeof(Applets::SwkbdConfigNew));
1838 std::memcpy(work_buffer.data(), initial_string.data(),
1839 swkbd_config.initial_string_length * sizeof(char16_t));
1840
1841 queue_data.emplace_back(std::move(argument_data));
1842 queue_data.emplace_back(std::move(swkbd_data));
1843 queue_data.emplace_back(std::move(work_buffer));
1844}
1845
1758IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_) 1846IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_)
1759 : ServiceFramework{system_, "IAppletCommonFunctions"} { 1847 : ServiceFramework{system_, "IAppletCommonFunctions"} {
1760 // clang-format off 1848 // clang-format off
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 64b3f3fe2..8f8cb8a9e 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -347,11 +347,14 @@ private:
347 void GetLibraryAppletInfo(HLERequestContext& ctx); 347 void GetLibraryAppletInfo(HLERequestContext& ctx);
348 void ExitProcessAndReturn(HLERequestContext& ctx); 348 void ExitProcessAndReturn(HLERequestContext& ctx);
349 void GetCallerAppletIdentityInfo(HLERequestContext& ctx); 349 void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
350 void GetDesirableKeyboardLayout(HLERequestContext& ctx);
350 void GetMainAppletAvailableUsers(HLERequestContext& ctx); 351 void GetMainAppletAvailableUsers(HLERequestContext& ctx);
352 void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
351 353
352 void PushInShowAlbum(); 354 void PushInShowAlbum();
353 void PushInShowCabinetData(); 355 void PushInShowCabinetData();
354 void PushInShowMiiEditData(); 356 void PushInShowMiiEditData();
357 void PushInShowSoftwareKeyboard();
355 358
356 std::deque<std::vector<u8>> queue_data; 359 std::deque<std::vector<u8>> queue_data;
357}; 360};
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
index 19ed184e8..b379dadeb 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.cpp
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -25,7 +25,9 @@ Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
25 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); 25 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
26} 26}
27 27
28Cabinet::~Cabinet() = default; 28Cabinet::~Cabinet() {
29 service_context.CloseEvent(availability_change_event);
30};
29 31
30void Cabinet::Initialize() { 32void Cabinet::Initialize() {
31 Applet::Initialize(); 33 Applet::Initialize();
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 1c9a1dc29..b0ea2b381 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -330,8 +330,7 @@ void WebBrowser::ExtractOfflineRomFS() {
330 LOG_DEBUG(Service_AM, "Extracting RomFS to {}", 330 LOG_DEBUG(Service_AM, "Extracting RomFS to {}",
331 Common::FS::PathToUTF8String(offline_cache_dir)); 331 Common::FS::PathToUTF8String(offline_cache_dir));
332 332
333 const auto extracted_romfs_dir = 333 const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs);
334 FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard);
335 334
336 const auto temp_dir = system.GetFilesystem()->CreateDirectory( 335 const auto temp_dir = system.GetFilesystem()->CreateDirectory(
337 Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); 336 Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite);
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index 7d733eb54..96b225d5f 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -228,12 +228,14 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
228 228
229Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, 229Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
230 const ScreenShotAttribute& attribute, 230 const ScreenShotAttribute& attribute,
231 std::span<const u8> image_data, u64 aruid) { 231 AlbumReportOption report_option, std::span<const u8> image_data,
232 return SaveScreenShot(out_entry, attribute, {}, image_data, aruid); 232 u64 aruid) {
233 return SaveScreenShot(out_entry, attribute, report_option, {}, image_data, aruid);
233} 234}
234 235
235Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, 236Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
236 const ScreenShotAttribute& attribute, 237 const ScreenShotAttribute& attribute,
238 AlbumReportOption report_option,
237 const ApplicationData& app_data, std::span<const u8> image_data, 239 const ApplicationData& app_data, std::span<const u8> image_data,
238 u64 aruid) { 240 u64 aruid) {
239 const u64 title_id = system.GetApplicationProcessProgramID(); 241 const u64 title_id = system.GetApplicationProcessProgramID();
@@ -407,10 +409,14 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p
407 return ResultSuccess; 409 return ResultSuccess;
408} 410}
409 411
410static void PNGToMemory(void* context, void* png, int len) { 412void AlbumManager::FlipVerticallyOnWrite(bool flip) {
413 stbi_flip_vertically_on_write(flip);
414}
415
416static void PNGToMemory(void* context, void* data, int len) {
411 std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context); 417 std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context);
412 png_image->reserve(len); 418 unsigned char* png = static_cast<unsigned char*>(data);
413 std::memcpy(png_image->data(), png, len); 419 png_image->insert(png_image->end(), png, png + len);
414} 420}
415 421
416Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image, 422Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image,
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h
index 44d85117f..e20c70c7b 100644
--- a/src/core/hle/service/caps/caps_manager.h
+++ b/src/core/hle/service/caps/caps_manager.h
@@ -59,14 +59,17 @@ public:
59 const ScreenShotDecodeOption& decoder_options) const; 59 const ScreenShotDecodeOption& decoder_options) const;
60 60
61 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, 61 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
62 std::span<const u8> image_data, u64 aruid); 62 AlbumReportOption report_option, std::span<const u8> image_data,
63 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
64 const ApplicationData& app_data, std::span<const u8> image_data,
65 u64 aruid); 63 u64 aruid);
64 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
65 AlbumReportOption report_option, const ApplicationData& app_data,
66 std::span<const u8> image_data, u64 aruid);
66 Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, 67 Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
67 const ScreenShotAttribute& attribute, const AlbumFileId& file_id, 68 const ScreenShotAttribute& attribute, const AlbumFileId& file_id,
68 std::span<const u8> image_data); 69 std::span<const u8> image_data);
69 70
71 void FlipVerticallyOnWrite(bool flip);
72
70private: 73private:
71 static constexpr std::size_t NandAlbumFileLimit = 1000; 74 static constexpr std::size_t NandAlbumFileLimit = 1000;
72 static constexpr std::size_t SdAlbumFileLimit = 10000; 75 static constexpr std::size_t SdAlbumFileLimit = 10000;
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index 1ba2b7972..eab023568 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -34,7 +34,7 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
34 IPC::RequestParser rp{ctx}; 34 IPC::RequestParser rp{ctx};
35 struct Parameters { 35 struct Parameters {
36 ScreenShotAttribute attribute{}; 36 ScreenShotAttribute attribute{};
37 u32 report_option{}; 37 AlbumReportOption report_option{};
38 INSERT_PADDING_BYTES(0x4); 38 INSERT_PADDING_BYTES(0x4);
39 u64 applet_resource_user_id{}; 39 u64 applet_resource_user_id{};
40 }; 40 };
@@ -49,13 +49,16 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
49 parameters.applet_resource_user_id); 49 parameters.applet_resource_user_id);
50 50
51 ApplicationAlbumEntry entry{}; 51 ApplicationAlbumEntry entry{};
52 const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, 52 manager->FlipVerticallyOnWrite(false);
53 parameters.applet_resource_user_id); 53 const auto result =
54 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
55 image_data_buffer, parameters.applet_resource_user_id);
54 56
55 IPC::ResponseBuilder rb{ctx, 10}; 57 IPC::ResponseBuilder rb{ctx, 10};
56 rb.Push(result); 58 rb.Push(result);
57 rb.PushRaw(entry); 59 rb.PushRaw(entry);
58} 60}
61
59void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) { 62void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
60 IPC::RequestParser rp{ctx}; 63 IPC::RequestParser rp{ctx};
61 struct Parameters { 64 struct Parameters {
@@ -83,6 +86,7 @@ void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
83 image_data_buffer.size(), thumbnail_image_data_buffer.size()); 86 image_data_buffer.size(), thumbnail_image_data_buffer.size());
84 87
85 ApplicationAlbumEntry entry{}; 88 ApplicationAlbumEntry entry{};
89 manager->FlipVerticallyOnWrite(false);
86 const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute, 90 const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute,
87 parameters.file_id, image_data_buffer); 91 parameters.file_id, image_data_buffer);
88 92
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index e85625ee4..296b07b00 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -2,10 +2,12 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h"
5#include "core/hle/service/caps/caps_manager.h" 6#include "core/hle/service/caps/caps_manager.h"
6#include "core/hle/service/caps/caps_su.h" 7#include "core/hle/service/caps/caps_su.h"
7#include "core/hle/service/caps/caps_types.h" 8#include "core/hle/service/caps/caps_types.h"
8#include "core/hle/service/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
10#include "video_core/renderer_base.h"
9 11
10namespace Service::Capture { 12namespace Service::Capture {
11 13
@@ -58,8 +60,10 @@ void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) {
58 parameters.applet_resource_user_id); 60 parameters.applet_resource_user_id);
59 61
60 ApplicationAlbumEntry entry{}; 62 ApplicationAlbumEntry entry{};
61 const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, 63 manager->FlipVerticallyOnWrite(false);
62 parameters.applet_resource_user_id); 64 const auto result =
65 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
66 image_data_buffer, parameters.applet_resource_user_id);
63 67
64 IPC::ResponseBuilder rb{ctx, 10}; 68 IPC::ResponseBuilder rb{ctx, 10};
65 rb.Push(result); 69 rb.Push(result);
@@ -88,13 +92,43 @@ void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) {
88 ApplicationAlbumEntry entry{}; 92 ApplicationAlbumEntry entry{};
89 ApplicationData app_data{}; 93 ApplicationData app_data{};
90 std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData)); 94 std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
95 manager->FlipVerticallyOnWrite(false);
91 const auto result = 96 const auto result =
92 manager->SaveScreenShot(entry, parameters.attribute, app_data, image_data_buffer, 97 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data,
93 parameters.applet_resource_user_id); 98 image_data_buffer, parameters.applet_resource_user_id);
94 99
95 IPC::ResponseBuilder rb{ctx, 10}; 100 IPC::ResponseBuilder rb{ctx, 10};
96 rb.Push(result); 101 rb.Push(result);
97 rb.PushRaw(entry); 102 rb.PushRaw(entry);
98} 103}
99 104
105void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
106 auto& renderer = system.Renderer();
107 Layout::FramebufferLayout layout =
108 Layout::DefaultFrameLayout(screenshot_width, screenshot_height);
109
110 const Capture::ScreenShotAttribute attribute{
111 .unknown_0{},
112 .orientation = Capture::AlbumImageOrientation::None,
113 .unknown_1{},
114 .unknown_2{},
115 };
116
117 renderer.RequestScreenshot(
118 image_data.data(),
119 [attribute, report_option, this](bool invert_y) {
120 // Convert from BGRA to RGBA
121 for (std::size_t i = 0; i < image_data.size(); i += bytes_per_pixel) {
122 const u8 temp = image_data[i];
123 image_data[i] = image_data[i + 2];
124 image_data[i + 2] = temp;
125 }
126
127 Capture::ApplicationAlbumEntry entry{};
128 manager->FlipVerticallyOnWrite(invert_y);
129 manager->SaveScreenShot(entry, attribute, report_option, image_data, {});
130 },
131 layout);
132}
133
100} // namespace Service::Capture 134} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index 89e71f506..21912e95f 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -10,6 +10,7 @@ class System;
10} 10}
11 11
12namespace Service::Capture { 12namespace Service::Capture {
13enum class AlbumReportOption : s32;
13class AlbumManager; 14class AlbumManager;
14 15
15class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> { 16class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> {
@@ -18,11 +19,19 @@ public:
18 std::shared_ptr<AlbumManager> album_manager); 19 std::shared_ptr<AlbumManager> album_manager);
19 ~IScreenShotApplicationService() override; 20 ~IScreenShotApplicationService() override;
20 21
22 void CaptureAndSaveScreenshot(AlbumReportOption report_option);
23
21private: 24private:
25 static constexpr std::size_t screenshot_width = 1280;
26 static constexpr std::size_t screenshot_height = 720;
27 static constexpr std::size_t bytes_per_pixel = 4;
28
22 void SetShimLibraryVersion(HLERequestContext& ctx); 29 void SetShimLibraryVersion(HLERequestContext& ctx);
23 void SaveScreenShotEx0(HLERequestContext& ctx); 30 void SaveScreenShotEx0(HLERequestContext& ctx);
24 void SaveScreenShotEx1(HLERequestContext& ctx); 31 void SaveScreenShotEx1(HLERequestContext& ctx);
25 32
33 std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;
34
26 std::shared_ptr<AlbumManager> manager; 35 std::shared_ptr<AlbumManager> manager;
27}; 36};
28 37
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index bc822f19e..21695bda2 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -1108,9 +1108,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
1108 shared_memory->sixaxis_dual_right_properties.raw = 0; 1108 shared_memory->sixaxis_dual_right_properties.raw = 0;
1109 shared_memory->sixaxis_left_properties.raw = 0; 1109 shared_memory->sixaxis_left_properties.raw = 0;
1110 shared_memory->sixaxis_right_properties.raw = 0; 1110 shared_memory->sixaxis_right_properties.raw = 0;
1111 shared_memory->battery_level_dual = 0; 1111 shared_memory->battery_level_dual = Core::HID::NpadBatteryLevel::Empty;
1112 shared_memory->battery_level_left = 0; 1112 shared_memory->battery_level_left = Core::HID::NpadBatteryLevel::Empty;
1113 shared_memory->battery_level_right = 0; 1113 shared_memory->battery_level_right = Core::HID::NpadBatteryLevel::Empty;
1114 shared_memory->fullkey_color = { 1114 shared_memory->fullkey_color = {
1115 .attribute = ColorAttribute::NoController, 1115 .attribute = ColorAttribute::NoController,
1116 .fullkey = {}, 1116 .fullkey = {},
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 14c67e454..73a2a2b91 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -19,7 +19,9 @@ Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared
19 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); 19 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
20} 20}
21 21
22Controller_Palma::~Controller_Palma() = default; 22Controller_Palma::~Controller_Palma() {
23 service_context.CloseEvent(operation_complete_event);
24};
23 25
24void Controller_Palma::OnInit() {} 26void Controller_Palma::OnInit() {}
25 27
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 4d70006c1..1d4101be9 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1353,7 +1353,7 @@ void Hid::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
1353void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) { 1353void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
1354 IPC::RequestParser rp{ctx}; 1354 IPC::RequestParser rp{ctx};
1355 struct Parameters { 1355 struct Parameters {
1356 bool unintended_home_button_input_protection; 1356 bool is_enabled;
1357 INSERT_PADDING_BYTES_NOINIT(3); 1357 INSERT_PADDING_BYTES_NOINIT(3);
1358 Core::HID::NpadIdType npad_id; 1358 Core::HID::NpadIdType npad_id;
1359 u64 applet_resource_user_id; 1359 u64 applet_resource_user_id;
@@ -1364,13 +1364,11 @@ void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
1364 1364
1365 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); 1365 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1366 const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled( 1366 const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled(
1367 parameters.unintended_home_button_input_protection, parameters.npad_id); 1367 parameters.is_enabled, parameters.npad_id);
1368 1368
1369 LOG_WARNING(Service_HID, 1369 LOG_DEBUG(Service_HID,
1370 "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={}," 1370 "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
1371 "applet_resource_user_id={}", 1371 parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
1372 parameters.unintended_home_button_input_protection, parameters.npad_id,
1373 parameters.applet_resource_user_id);
1374 1372
1375 IPC::ResponseBuilder rb{ctx, 2}; 1373 IPC::ResponseBuilder rb{ctx, 2};
1376 rb.Push(result); 1374 rb.Push(result);
@@ -2757,6 +2755,10 @@ public:
2757 joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent"); 2755 joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
2758 } 2756 }
2759 2757
2758 ~HidSys() {
2759 service_context.CloseEvent(joy_detach_event);
2760 };
2761
2760private: 2762private:
2761 void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { 2763 void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
2762 LOG_WARNING(Service_HID, "called"); 2764 LOG_WARNING(Service_HID, "called");
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
index ee522c36e..8c44f93e8 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
@@ -13,7 +13,10 @@ HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& ser
13 : system(system_), service_context(service_context_) { 13 : system(system_), service_context(service_context_) {
14 send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent"); 14 send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent");
15} 15}
16HidbusBase::~HidbusBase() = default; 16
17HidbusBase::~HidbusBase() {
18 service_context.CloseEvent(send_command_async_event);
19};
17 20
18void HidbusBase::ActivateDevice() { 21void HidbusBase::ActivateDevice() {
19 if (is_activated) { 22 if (is_activated) {
diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/core/hle/service/hid/ring_lifo.h
index 65eb7ea02..0816784e0 100644
--- a/src/core/hle/service/hid/ring_lifo.h
+++ b/src/core/hle/service/hid/ring_lifo.h
@@ -32,15 +32,15 @@ struct Lifo {
32 } 32 }
33 33
34 std::size_t GetPreviousEntryIndex() const { 34 std::size_t GetPreviousEntryIndex() const {
35 return static_cast<size_t>((buffer_tail + total_buffer_count - 1) % total_buffer_count); 35 return static_cast<size_t>((buffer_tail + max_buffer_size - 1) % max_buffer_size);
36 } 36 }
37 37
38 std::size_t GetNextEntryIndex() const { 38 std::size_t GetNextEntryIndex() const {
39 return static_cast<size_t>((buffer_tail + 1) % total_buffer_count); 39 return static_cast<size_t>((buffer_tail + 1) % max_buffer_size);
40 } 40 }
41 41
42 void WriteNextEntry(const State& new_state) { 42 void WriteNextEntry(const State& new_state) {
43 if (buffer_count < total_buffer_count - 1) { 43 if (buffer_count < static_cast<s64>(max_buffer_size) - 1) {
44 buffer_count++; 44 buffer_count++;
45 } 45 }
46 buffer_tail = GetNextEntryIndex(); 46 buffer_tail = GetNextEntryIndex();
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 6a313a03b..f51e63564 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -21,10 +21,8 @@ ServiceContext::ServiceContext(Core::System& system_, std::string name_)
21 21
22 // Create the process. 22 // Create the process.
23 process = Kernel::KProcess::Create(kernel); 23 process = Kernel::KProcess::Create(kernel);
24 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_), 24 ASSERT(R_SUCCEEDED(process->Initialize(Kernel::Svc::CreateProcessParameter{},
25 Kernel::KProcess::ProcessType::KernelInternal, 25 kernel.GetSystemResourceLimit(), false)));
26 kernel.GetSystemResourceLimit())
27 .IsSuccess());
28 26
29 // Register the process. 27 // Register the process.
30 Kernel::KProcess::Register(kernel, process); 28 Kernel::KProcess::Register(kernel, process);
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
index 2dbe29616..ed66f6f5b 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
@@ -41,7 +41,7 @@ bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk)
41s32 BufferQueueCore::GetMinUndequeuedBufferCountLocked(bool async) const { 41s32 BufferQueueCore::GetMinUndequeuedBufferCountLocked(bool async) const {
42 // If DequeueBuffer is allowed to error out, we don't have to add an extra buffer. 42 // If DequeueBuffer is allowed to error out, we don't have to add an extra buffer.
43 if (!use_async_buffer) { 43 if (!use_async_buffer) {
44 return max_acquired_buffer_count; 44 return 0;
45 } 45 }
46 46
47 if (dequeue_buffer_cannot_block || async) { 47 if (dequeue_buffer_cannot_block || async) {
@@ -52,7 +52,7 @@ s32 BufferQueueCore::GetMinUndequeuedBufferCountLocked(bool async) const {
52} 52}
53 53
54s32 BufferQueueCore::GetMinMaxBufferCountLocked(bool async) const { 54s32 BufferQueueCore::GetMinMaxBufferCountLocked(bool async) const {
55 return GetMinUndequeuedBufferCountLocked(async) + 1; 55 return GetMinUndequeuedBufferCountLocked(async);
56} 56}
57 57
58s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const { 58s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const {
@@ -61,7 +61,7 @@ s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const {
61 61
62 if (override_max_buffer_count != 0) { 62 if (override_max_buffer_count != 0) {
63 ASSERT(override_max_buffer_count >= min_buffer_count); 63 ASSERT(override_max_buffer_count >= min_buffer_count);
64 max_buffer_count = override_max_buffer_count; 64 return override_max_buffer_count;
65 } 65 }
66 66
67 // Any buffers that are dequeued by the producer or sitting in the queue waiting to be consumed 67 // Any buffers that are dequeued by the producer or sitting in the queue waiting to be consumed
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
index dc6917d5d..6e7a49658 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
@@ -134,7 +134,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
134 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async); 134 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async);
135 if (async && core->override_max_buffer_count) { 135 if (async && core->override_max_buffer_count) {
136 if (core->override_max_buffer_count < max_buffer_count) { 136 if (core->override_max_buffer_count < max_buffer_count) {
137 LOG_ERROR(Service_Nvnflinger, "async mode is invalid with buffer count override"); 137 *found = BufferQueueCore::INVALID_BUFFER_SLOT;
138 return Status::BadValue; 138 return Status::BadValue;
139 } 139 }
140 } 140 }
@@ -142,7 +142,8 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
142 // Free up any buffers that are in slots beyond the max buffer count 142 // Free up any buffers that are in slots beyond the max buffer count
143 for (s32 s = max_buffer_count; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 143 for (s32 s = max_buffer_count; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
144 ASSERT(slots[s].buffer_state == BufferState::Free); 144 ASSERT(slots[s].buffer_state == BufferState::Free);
145 if (slots[s].graphic_buffer != nullptr) { 145 if (slots[s].graphic_buffer != nullptr && slots[s].buffer_state == BufferState::Free &&
146 !slots[s].is_preallocated) {
146 core->FreeBufferLocked(s); 147 core->FreeBufferLocked(s);
147 *return_flags |= Status::ReleaseAllBuffers; 148 *return_flags |= Status::ReleaseAllBuffers;
148 } 149 }
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index a07c621d9..bebb45eae 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -66,7 +66,6 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
66 "ScreenComposition", 66 "ScreenComposition",
67 [this](std::uintptr_t, s64 time, 67 [this](std::uintptr_t, s64 time,
68 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 68 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
69 { const auto lock_guard = Lock(); }
70 vsync_signal.Set(); 69 vsync_signal.Set();
71 return std::chrono::nanoseconds(GetNextTicks()); 70 return std::chrono::nanoseconds(GetNextTicks());
72 }); 71 });
@@ -99,6 +98,7 @@ Nvnflinger::~Nvnflinger() {
99 } 98 }
100 99
101 ShutdownLayers(); 100 ShutdownLayers();
101 vsync_thread = {};
102 102
103 if (nvdrv) { 103 if (nvdrv) {
104 nvdrv->Close(disp_fd); 104 nvdrv->Close(disp_fd);
@@ -106,6 +106,7 @@ Nvnflinger::~Nvnflinger() {
106} 106}
107 107
108void Nvnflinger::ShutdownLayers() { 108void Nvnflinger::ShutdownLayers() {
109 const auto lock_guard = Lock();
109 for (auto& display : displays) { 110 for (auto& display : displays) {
110 for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { 111 for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
111 display.GetLayer(layer).Core().NotifyShutdown(); 112 display.GetLayer(layer).Core().NotifyShutdown();
@@ -229,16 +230,6 @@ VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) {
229 return display->FindLayer(layer_id); 230 return display->FindLayer(layer_id);
230} 231}
231 232
232const VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) const {
233 const auto* const display = FindDisplay(display_id);
234
235 if (display == nullptr) {
236 return nullptr;
237 }
238
239 return display->FindLayer(layer_id);
240}
241
242VI::Layer* Nvnflinger::FindOrCreateLayer(u64 display_id, u64 layer_id) { 233VI::Layer* Nvnflinger::FindOrCreateLayer(u64 display_id, u64 layer_id) {
243 auto* const display = FindDisplay(display_id); 234 auto* const display = FindDisplay(display_id);
244 235
@@ -288,7 +279,6 @@ void Nvnflinger::Compose() {
288 auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd); 279 auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd);
289 ASSERT(nvdisp); 280 ASSERT(nvdisp);
290 281
291 guard->unlock();
292 Common::Rectangle<int> crop_rect{ 282 Common::Rectangle<int> crop_rect{
293 static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()), 283 static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()),
294 static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())}; 284 static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())};
@@ -299,7 +289,6 @@ void Nvnflinger::Compose() {
299 buffer.fence.fences, buffer.fence.num_fences); 289 buffer.fence.fences, buffer.fence.num_fences);
300 290
301 MicroProfileFlip(); 291 MicroProfileFlip();
302 guard->lock();
303 292
304 swap_interval = buffer.swap_interval; 293 swap_interval = buffer.swap_interval;
305 294
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h
index 14c783582..959d8b46b 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.h
+++ b/src/core/hle/service/nvnflinger/nvnflinger.h
@@ -117,9 +117,6 @@ private:
117 /// Finds the layer identified by the specified ID in the desired display. 117 /// Finds the layer identified by the specified ID in the desired display.
118 [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id); 118 [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id);
119 119
120 /// Finds the layer identified by the specified ID in the desired display.
121 [[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
122
123 /// Finds the layer identified by the specified ID in the desired display, 120 /// Finds the layer identified by the specified ID in the desired display,
124 /// or creates the layer if it is not found. 121 /// or creates the layer if it is not found.
125 /// To be used when the system expects the specified ID to already exist. 122 /// To be used when the system expects the specified ID to already exist.
diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp
index 938330dd0..6a7fd72bc 100644
--- a/src/core/hle/service/pctl/pctl_module.cpp
+++ b/src/core/hle/service/pctl/pctl_module.cpp
@@ -141,6 +141,12 @@ public:
141 service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent"); 141 service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent");
142 } 142 }
143 143
144 ~IParentalControlService() {
145 service_context.CloseEvent(synchronization_event);
146 service_context.CloseEvent(unlinked_event);
147 service_context.CloseEvent(request_suspension_event);
148 };
149
144private: 150private:
145 bool CheckFreeCommunicationPermissionImpl() const { 151 bool CheckFreeCommunicationPermissionImpl() const {
146 if (states.temporary_unlocked) { 152 if (states.temporary_unlocked) {
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp
index f9cf2dda3..d92499f05 100644
--- a/src/core/hle/service/pm/pm.cpp
+++ b/src/core/hle/service/pm/pm.cpp
@@ -37,7 +37,7 @@ std::optional<Kernel::KProcess*> SearchProcessList(
37void GetApplicationPidGeneric(HLERequestContext& ctx, 37void GetApplicationPidGeneric(HLERequestContext& ctx,
38 const std::vector<Kernel::KProcess*>& process_list) { 38 const std::vector<Kernel::KProcess*>& process_list) {
39 const auto process = SearchProcessList(process_list, [](const auto& proc) { 39 const auto process = SearchProcessList(process_list, [](const auto& proc) {
40 return proc->GetProcessId() == Kernel::KProcess::ProcessIDMin; 40 return proc->GetProcessId() == Kernel::KProcess::ProcessIdMin;
41 }); 41 });
42 42
43 IPC::ResponseBuilder rb{ctx, 4}; 43 IPC::ResponseBuilder rb{ctx, 4};
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 85849d5f3..dd652ca42 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -39,6 +39,18 @@ bool IsConnectionBased(Type type) {
39 } 39 }
40} 40}
41 41
42template <typename T>
43T GetValue(std::span<const u8> buffer) {
44 T t{};
45 std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size()));
46 return t;
47}
48
49template <typename T>
50void PutValue(std::span<u8> buffer, const T& t) {
51 std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size()));
52}
53
42} // Anonymous namespace 54} // Anonymous namespace
43 55
44void BSD::PollWork::Execute(BSD* bsd) { 56void BSD::PollWork::Execute(BSD* bsd) {
@@ -316,22 +328,12 @@ void BSD::SetSockOpt(HLERequestContext& ctx) {
316 const s32 fd = rp.Pop<s32>(); 328 const s32 fd = rp.Pop<s32>();
317 const u32 level = rp.Pop<u32>(); 329 const u32 level = rp.Pop<u32>();
318 const OptName optname = static_cast<OptName>(rp.Pop<u32>()); 330 const OptName optname = static_cast<OptName>(rp.Pop<u32>());
319 331 const auto optval = ctx.ReadBuffer();
320 const auto buffer = ctx.ReadBuffer();
321 const u8* optval = buffer.empty() ? nullptr : buffer.data();
322 size_t optlen = buffer.size();
323
324 std::array<u64, 2> values;
325 if ((optname == OptName::SNDTIMEO || optname == OptName::RCVTIMEO) && buffer.size() == 8) {
326 std::memcpy(values.data(), buffer.data(), sizeof(values));
327 optlen = sizeof(values);
328 optval = reinterpret_cast<const u8*>(values.data());
329 }
330 332
331 LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level, 333 LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level,
332 static_cast<u32>(optname), optlen); 334 static_cast<u32>(optname), optval.size());
333 335
334 BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval)); 336 BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
335} 337}
336 338
337void BSD::Shutdown(HLERequestContext& ctx) { 339void BSD::Shutdown(HLERequestContext& ctx) {
@@ -521,18 +523,19 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
521 523
522std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, 524std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
523 s32 nfds, s32 timeout) { 525 s32 nfds, s32 timeout) {
524 if (write_buffer.size() < nfds * sizeof(PollFD)) { 526 if (nfds <= 0) {
525 return {-1, Errno::INVAL};
526 }
527
528 if (nfds == 0) {
529 // When no entries are provided, -1 is returned with errno zero 527 // When no entries are provided, -1 is returned with errno zero
530 return {-1, Errno::SUCCESS}; 528 return {-1, Errno::SUCCESS};
531 } 529 }
530 if (read_buffer.size() < nfds * sizeof(PollFD)) {
531 return {-1, Errno::INVAL};
532 }
533 if (write_buffer.size() < nfds * sizeof(PollFD)) {
534 return {-1, Errno::INVAL};
535 }
532 536
533 const size_t length = std::min(read_buffer.size(), write_buffer.size());
534 std::vector<PollFD> fds(nfds); 537 std::vector<PollFD> fds(nfds);
535 std::memcpy(fds.data(), read_buffer.data(), length); 538 std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD));
536 539
537 if (timeout >= 0) { 540 if (timeout >= 0) {
538 const s64 seconds = timeout / 1000; 541 const s64 seconds = timeout / 1000;
@@ -580,7 +583,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
580 for (size_t i = 0; i < num; ++i) { 583 for (size_t i = 0; i < num; ++i) {
581 fds[i].revents = Translate(host_pollfds[i].revents); 584 fds[i].revents = Translate(host_pollfds[i].revents);
582 } 585 }
583 std::memcpy(write_buffer.data(), fds.data(), length); 586 std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD));
584 587
585 return Translate(result); 588 return Translate(result);
586} 589}
@@ -608,8 +611,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
608 new_descriptor.is_connection_based = descriptor.is_connection_based; 611 new_descriptor.is_connection_based = descriptor.is_connection_based;
609 612
610 const SockAddrIn guest_addr_in = Translate(result.sockaddr_in); 613 const SockAddrIn guest_addr_in = Translate(result.sockaddr_in);
611 const size_t length = std::min(sizeof(guest_addr_in), write_buffer.size()); 614 PutValue(write_buffer, guest_addr_in);
612 std::memcpy(write_buffer.data(), &guest_addr_in, length);
613 615
614 return {new_fd, Errno::SUCCESS}; 616 return {new_fd, Errno::SUCCESS};
615} 617}
@@ -619,8 +621,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
619 return Errno::BADF; 621 return Errno::BADF;
620 } 622 }
621 ASSERT(addr.size() == sizeof(SockAddrIn)); 623 ASSERT(addr.size() == sizeof(SockAddrIn));
622 SockAddrIn addr_in; 624 auto addr_in = GetValue<SockAddrIn>(addr);
623 std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
624 625
625 return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); 626 return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
626} 627}
@@ -631,8 +632,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
631 } 632 }
632 633
633 UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); 634 UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn));
634 SockAddrIn addr_in; 635 auto addr_in = GetValue<SockAddrIn>(addr);
635 std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
636 636
637 return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); 637 return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
638} 638}
@@ -650,7 +650,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
650 650
651 ASSERT(write_buffer.size() >= sizeof(guest_addrin)); 651 ASSERT(write_buffer.size() >= sizeof(guest_addrin));
652 write_buffer.resize(sizeof(guest_addrin)); 652 write_buffer.resize(sizeof(guest_addrin));
653 std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); 653 PutValue(write_buffer, guest_addrin);
654 return Translate(bsd_errno); 654 return Translate(bsd_errno);
655} 655}
656 656
@@ -667,7 +667,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
667 667
668 ASSERT(write_buffer.size() >= sizeof(guest_addrin)); 668 ASSERT(write_buffer.size() >= sizeof(guest_addrin));
669 write_buffer.resize(sizeof(guest_addrin)); 669 write_buffer.resize(sizeof(guest_addrin));
670 std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin)); 670 PutValue(write_buffer, guest_addrin);
671 return Translate(bsd_errno); 671 return Translate(bsd_errno);
672} 672}
673 673
@@ -725,7 +725,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
725 optval.size() == sizeof(Errno), { return Errno::INVAL; }, 725 optval.size() == sizeof(Errno), { return Errno::INVAL; },
726 "Incorrect getsockopt option size"); 726 "Incorrect getsockopt option size");
727 optval.resize(sizeof(Errno)); 727 optval.resize(sizeof(Errno));
728 memcpy(optval.data(), &translated_pending_err, sizeof(Errno)); 728 PutValue(optval, translated_pending_err);
729 } 729 }
730 return Translate(getsockopt_err); 730 return Translate(getsockopt_err);
731 } 731 }
@@ -735,7 +735,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
735 } 735 }
736} 736}
737 737
738Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval) { 738Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
739 if (!IsFileDescriptorValid(fd)) { 739 if (!IsFileDescriptorValid(fd)) {
740 return Errno::BADF; 740 return Errno::BADF;
741 } 741 }
@@ -748,17 +748,15 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con
748 Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); 748 Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
749 749
750 if (optname == OptName::LINGER) { 750 if (optname == OptName::LINGER) {
751 ASSERT(optlen == sizeof(Linger)); 751 ASSERT(optval.size() == sizeof(Linger));
752 Linger linger; 752 auto linger = GetValue<Linger>(optval);
753 std::memcpy(&linger, optval, sizeof(linger));
754 ASSERT(linger.onoff == 0 || linger.onoff == 1); 753 ASSERT(linger.onoff == 0 || linger.onoff == 1);
755 754
756 return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); 755 return Translate(socket->SetLinger(linger.onoff != 0, linger.linger));
757 } 756 }
758 757
759 ASSERT(optlen == sizeof(u32)); 758 ASSERT(optval.size() == sizeof(u32));
760 u32 value; 759 auto value = GetValue<u32>(optval);
761 std::memcpy(&value, optval, sizeof(value));
762 760
763 switch (optname) { 761 switch (optname) {
764 case OptName::REUSEADDR: 762 case OptName::REUSEADDR:
@@ -862,7 +860,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess
862 } else { 860 } else {
863 ASSERT(addr.size() == sizeof(SockAddrIn)); 861 ASSERT(addr.size() == sizeof(SockAddrIn));
864 const SockAddrIn result = Translate(addr_in); 862 const SockAddrIn result = Translate(addr_in);
865 std::memcpy(addr.data(), &result, sizeof(result)); 863 PutValue(addr, result);
866 } 864 }
867 } 865 }
868 866
@@ -886,8 +884,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes
886 Network::SockAddrIn* p_addr_in = nullptr; 884 Network::SockAddrIn* p_addr_in = nullptr;
887 if (!addr.empty()) { 885 if (!addr.empty()) {
888 ASSERT(addr.size() == sizeof(SockAddrIn)); 886 ASSERT(addr.size() == sizeof(SockAddrIn));
889 SockAddrIn guest_addr_in; 887 auto guest_addr_in = GetValue<SockAddrIn>(addr);
890 std::memcpy(&guest_addr_in, addr.data(), sizeof(guest_addr_in));
891 addr_in = Translate(guest_addr_in); 888 addr_in = Translate(guest_addr_in);
892 p_addr_in = &addr_in; 889 p_addr_in = &addr_in;
893 } 890 }
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 161f22b9b..4f69d382c 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -163,7 +163,7 @@ private:
163 Errno ListenImpl(s32 fd, s32 backlog); 163 Errno ListenImpl(s32 fd, s32 backlog);
164 std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); 164 std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg);
165 Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval); 165 Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval);
166 Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval); 166 Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval);
167 Errno ShutdownImpl(s32 fd, s32 how); 167 Errno ShutdownImpl(s32 fd, s32 how);
168 std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); 168 std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
169 std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, 169 std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index ed875d444..5d168cbc1 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -116,7 +116,7 @@ json GetProcessorStateDataAuto(Core::System& system) {
116 Core::ARM_Interface::ThreadContext64 context{}; 116 Core::ARM_Interface::ThreadContext64 context{};
117 arm.SaveContext(context); 117 arm.SaveContext(context);
118 118
119 return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", 119 return GetProcessorStateData(process->Is64Bit() ? "AArch64" : "AArch32",
120 GetInteger(process->GetEntryPoint()), context.sp, context.pc, 120 GetInteger(process->GetEntryPoint()), context.sp, context.pc,
121 context.pstate, context.cpu_registers); 121 context.pstate, context.cpu_registers);
122} 122}
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp
index cf51f3481..c9f903213 100644
--- a/src/input_common/helpers/joycon_driver.cpp
+++ b/src/input_common/helpers/joycon_driver.cpp
@@ -139,7 +139,7 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
139 input_thread_running = true; 139 input_thread_running = true;
140 140
141 // Max update rate is 5ms, ensure we are always able to read a bit faster 141 // Max update rate is 5ms, ensure we are always able to read a bit faster
142 constexpr int ThreadDelay = 2; 142 constexpr int ThreadDelay = 3;
143 std::vector<u8> buffer(MaxBufferSize); 143 std::vector<u8> buffer(MaxBufferSize);
144 144
145 while (!stop_token.stop_requested()) { 145 while (!stop_token.stop_requested()) {
@@ -163,6 +163,17 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
163 OnNewData(buffer); 163 OnNewData(buffer);
164 } 164 }
165 165
166 if (!vibration_queue.Empty()) {
167 VibrationValue vibration_value;
168 vibration_queue.Pop(vibration_value);
169 last_vibration_result = rumble_protocol->SendVibration(vibration_value);
170 }
171
172 // We can't keep up with vibrations. Start skipping.
173 while (vibration_queue.Size() > 6) {
174 vibration_queue.Pop();
175 }
176
166 std::this_thread::yield(); 177 std::this_thread::yield();
167 } 178 }
168 179
@@ -402,7 +413,8 @@ Common::Input::DriverResult JoyconDriver::SetVibration(const VibrationValue& vib
402 if (disable_input_thread) { 413 if (disable_input_thread) {
403 return Common::Input::DriverResult::HandleInUse; 414 return Common::Input::DriverResult::HandleInUse;
404 } 415 }
405 return rumble_protocol->SendVibration(vibration); 416 vibration_queue.Push(vibration);
417 return last_vibration_result;
406} 418}
407 419
408Common::Input::DriverResult JoyconDriver::SetLedConfig(u8 led_pattern) { 420Common::Input::DriverResult JoyconDriver::SetLedConfig(u8 led_pattern) {
diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h
index 335e12cc3..5355780fb 100644
--- a/src/input_common/helpers/joycon_driver.h
+++ b/src/input_common/helpers/joycon_driver.h
@@ -9,6 +9,7 @@
9#include <span> 9#include <span>
10#include <thread> 10#include <thread>
11 11
12#include "common/threadsafe_queue.h"
12#include "input_common/helpers/joycon_protocol/joycon_types.h" 13#include "input_common/helpers/joycon_protocol/joycon_types.h"
13 14
14namespace Common::Input { 15namespace Common::Input {
@@ -152,6 +153,10 @@ private:
152 SerialNumber handle_serial_number{}; // Serial number type reported by hidapi 153 SerialNumber handle_serial_number{}; // Serial number type reported by hidapi
153 SupportedFeatures supported_features{}; 154 SupportedFeatures supported_features{};
154 155
156 /// Queue of vibration request to controllers
157 Common::Input::DriverResult last_vibration_result{Common::Input::DriverResult::Success};
158 Common::SPSCQueue<VibrationValue> vibration_queue;
159
155 // Thread related 160 // Thread related
156 mutable std::mutex mutex; 161 mutable std::mutex mutex;
157 std::jthread input_thread; 162 std::jthread input_thread;
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 9b2698fad..081a574e8 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -1067,8 +1067,7 @@ void BufferCache<P>::BindHostComputeTextureBuffers() {
1067 1067
1068template <class P> 1068template <class P>
1069void BufferCache<P>::DoUpdateGraphicsBuffers(bool is_indexed) { 1069void BufferCache<P>::DoUpdateGraphicsBuffers(bool is_indexed) {
1070 do { 1070 BufferOperations([&]() {
1071 channel_state->has_deleted_buffers = false;
1072 if (is_indexed) { 1071 if (is_indexed) {
1073 UpdateIndexBuffer(); 1072 UpdateIndexBuffer();
1074 } 1073 }
@@ -1082,14 +1081,16 @@ void BufferCache<P>::DoUpdateGraphicsBuffers(bool is_indexed) {
1082 if (current_draw_indirect) { 1081 if (current_draw_indirect) {
1083 UpdateDrawIndirect(); 1082 UpdateDrawIndirect();
1084 } 1083 }
1085 } while (channel_state->has_deleted_buffers); 1084 });
1086} 1085}
1087 1086
1088template <class P> 1087template <class P>
1089void BufferCache<P>::DoUpdateComputeBuffers() { 1088void BufferCache<P>::DoUpdateComputeBuffers() {
1090 UpdateComputeUniformBuffers(); 1089 BufferOperations([&]() {
1091 UpdateComputeStorageBuffers(); 1090 UpdateComputeUniformBuffers();
1092 UpdateComputeTextureBuffers(); 1091 UpdateComputeStorageBuffers();
1092 UpdateComputeTextureBuffers();
1093 });
1093} 1094}
1094 1095
1095template <class P> 1096template <class P>
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 804b95989..22bf8cc77 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -358,7 +358,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
358 .has_broken_spirv_subgroup_mask_vector_extract_dynamic = 358 .has_broken_spirv_subgroup_mask_vector_extract_dynamic =
359 driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY, 359 driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
360 .has_broken_robust = 360 .has_broken_robust =
361 device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Maxwell, 361 device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Pascal,
362 }; 362 };
363 363
364 host_info = Shader::HostTranslateInfo{ 364 host_info = Shader::HostTranslateInfo{
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 465eac37e..3983b2eb7 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -13,6 +13,7 @@
13#include "common/microprofile.h" 13#include "common/microprofile.h"
14#include "common/scope_exit.h" 14#include "common/scope_exit.h"
15#include "common/settings.h" 15#include "common/settings.h"
16#include "video_core/buffer_cache/buffer_cache.h"
16#include "video_core/control/channel_state.h" 17#include "video_core/control/channel_state.h"
17#include "video_core/engines/draw_manager.h" 18#include "video_core/engines/draw_manager.h"
18#include "video_core/engines/kepler_compute.h" 19#include "video_core/engines/kepler_compute.h"
@@ -285,6 +286,7 @@ void RasterizerVulkan::DrawTexture() {
285 286
286 query_cache.NotifySegment(true); 287 query_cache.NotifySegment(true);
287 288
289 std::scoped_lock l{texture_cache.mutex};
288 texture_cache.SynchronizeGraphicsDescriptors(); 290 texture_cache.SynchronizeGraphicsDescriptors();
289 texture_cache.UpdateRenderTargets(false); 291 texture_cache.UpdateRenderTargets(false);
290 292
@@ -921,9 +923,13 @@ void RasterizerVulkan::UpdateDynamicStates() {
921} 923}
922 924
923void RasterizerVulkan::HandleTransformFeedback() { 925void RasterizerVulkan::HandleTransformFeedback() {
926 static std::once_flag warn_unsupported;
927
924 const auto& regs = maxwell3d->regs; 928 const auto& regs = maxwell3d->regs;
925 if (!device.IsExtTransformFeedbackSupported()) { 929 if (!device.IsExtTransformFeedbackSupported()) {
926 LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported"); 930 std::call_once(warn_unsupported, [&] {
931 LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported");
932 });
927 return; 933 return;
928 } 934 }
929 query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, 935 query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount,
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index d56558a83..daaea2979 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -190,7 +190,7 @@ void SetupDirtySpecialOps(Tables& tables) {
190void SetupDirtyViewportSwizzles(Tables& tables) { 190void SetupDirtyViewportSwizzles(Tables& tables) {
191 static constexpr size_t swizzle_offset = 6; 191 static constexpr size_t swizzle_offset = 6;
192 for (size_t index = 0; index < Regs::NumViewports; ++index) { 192 for (size_t index = 0; index < Regs::NumViewports; ++index) {
193 tables[0][OFF(viewport_transform) + index * NUM(viewport_transform[0]) + swizzle_offset] = 193 tables[1][OFF(viewport_transform) + index * NUM(viewport_transform[0]) + swizzle_offset] =
194 ViewportSwizzles; 194 ViewportSwizzles;
195 } 195 }
196} 196}
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index 81ef98f61..821f44f1a 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -147,6 +147,9 @@ bool Swapchain::AcquireNextImage() {
147 case VK_ERROR_OUT_OF_DATE_KHR: 147 case VK_ERROR_OUT_OF_DATE_KHR:
148 is_outdated = true; 148 is_outdated = true;
149 break; 149 break;
150 case VK_ERROR_SURFACE_LOST_KHR:
151 vk::Check(result);
152 break;
150 default: 153 default:
151 LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result)); 154 LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result));
152 break; 155 break;
@@ -180,6 +183,9 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
180 case VK_ERROR_OUT_OF_DATE_KHR: 183 case VK_ERROR_OUT_OF_DATE_KHR:
181 is_outdated = true; 184 is_outdated = true;
182 break; 185 break;
186 case VK_ERROR_SURFACE_LOST_KHR:
187 vk::Check(result);
188 break;
183 default: 189 default:
184 LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result)); 190 LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result));
185 break; 191 break;
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 34208ed74..33e1fb663 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -227,14 +227,14 @@ add_executable(yuzu
227 yuzu.rc 227 yuzu.rc
228) 228)
229 229
230if (WIN32 AND YUZU_CRASH_DUMPS) 230if (YUZU_CRASH_DUMPS)
231 target_sources(yuzu PRIVATE 231 target_sources(yuzu PRIVATE
232 mini_dump.cpp 232 breakpad.cpp
233 mini_dump.h 233 breakpad.h
234 ) 234 )
235 235
236 target_link_libraries(yuzu PRIVATE ${DBGHELP_LIBRARY}) 236 target_link_libraries(yuzu PRIVATE libbreakpad_client)
237 target_compile_definitions(yuzu PRIVATE -DYUZU_DBGHELP) 237 target_compile_definitions(yuzu PRIVATE YUZU_CRASH_DUMPS)
238endif() 238endif()
239 239
240if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 240if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index ca0e14fad..515cb7ce6 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -155,18 +155,27 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
155 UpdateBorderColor(i); 155 UpdateBorderColor(i);
156 156
157 connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) { 157 connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) {
158 if (checked) { 158 // Reconnect current controller if it was the last one checked
159 // Hide eventual error message about number of controllers 159 // (player number was reduced by more than one)
160 ui->labelError->setVisible(false); 160 const bool reconnect_first = !checked && i < player_groupboxes.size() - 1 &&
161 for (std::size_t index = 0; index <= i; ++index) { 161 player_groupboxes[i + 1]->isChecked();
162 connected_controller_checkboxes[index]->setChecked(checked); 162
163 } 163 // Ensures that connecting a controller changes the number of players
164 } else { 164 if (connected_controller_checkboxes[i]->isChecked() != checked) {
165 for (std::size_t index = i; index < NUM_PLAYERS; ++index) { 165 // Ensures that the players are always connected in sequential order
166 connected_controller_checkboxes[index]->setChecked(checked); 166 PropagatePlayerNumberChanged(i, checked, reconnect_first);
167 }
168 } 167 }
169 }); 168 });
169 connect(connected_controller_checkboxes[i], &QCheckBox::clicked, [this, i](bool checked) {
170 // Reconnect current controller if it was the last one checked
171 // (player number was reduced by more than one)
172 const bool reconnect_first = !checked &&
173 i < connected_controller_checkboxes.size() - 1 &&
174 connected_controller_checkboxes[i + 1]->isChecked();
175
176 // Ensures that the players are always connected in sequential order
177 PropagatePlayerNumberChanged(i, checked, reconnect_first);
178 });
170 179
171 connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged), 180 connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged),
172 [this, i](int) { 181 [this, i](int) {
@@ -668,6 +677,29 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) {
668 } 677 }
669} 678}
670 679
680void QtControllerSelectorDialog::PropagatePlayerNumberChanged(size_t player_index, bool checked,
681 bool reconnect_current) {
682 connected_controller_checkboxes[player_index]->setChecked(checked);
683 // Hide eventual error message about number of controllers
684 ui->labelError->setVisible(false);
685
686 if (checked) {
687 // Check all previous buttons when checked
688 if (player_index > 0) {
689 PropagatePlayerNumberChanged(player_index - 1, checked);
690 }
691 } else {
692 // Unchecked all following buttons when unchecked
693 if (player_index < connected_controller_checkboxes.size() - 1) {
694 PropagatePlayerNumberChanged(player_index + 1, checked);
695 }
696 }
697
698 if (reconnect_current) {
699 connected_controller_checkboxes[player_index]->setCheckState(Qt::Checked);
700 }
701}
702
671void QtControllerSelectorDialog::DisableUnsupportedPlayers() { 703void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
672 const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players; 704 const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
673 705
diff --git a/src/yuzu/applets/qt_controller.h b/src/yuzu/applets/qt_controller.h
index 7f0673d06..e5372495d 100644
--- a/src/yuzu/applets/qt_controller.h
+++ b/src/yuzu/applets/qt_controller.h
@@ -100,6 +100,10 @@ private:
100 // Updates the console mode. 100 // Updates the console mode.
101 void UpdateDockedState(bool is_handheld); 101 void UpdateDockedState(bool is_handheld);
102 102
103 // Enable preceding controllers or disable following ones
104 void PropagatePlayerNumberChanged(size_t player_index, bool checked,
105 bool reconnect_current = false);
106
103 // Disables and disconnects unsupported players based on the given parameters. 107 // Disables and disconnects unsupported players based on the given parameters.
104 void DisableUnsupportedPlayers(); 108 void DisableUnsupportedPlayers();
105 109
diff --git a/src/yuzu/breakpad.cpp b/src/yuzu/breakpad.cpp
new file mode 100644
index 000000000..0f6a71ab0
--- /dev/null
+++ b/src/yuzu/breakpad.cpp
@@ -0,0 +1,77 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <algorithm>
5#include <ranges>
6
7#if defined(_WIN32)
8#include <client/windows/handler/exception_handler.h>
9#elif defined(__linux__)
10#include <client/linux/handler/exception_handler.h>
11#else
12#error Minidump creation not supported on this platform
13#endif
14
15#include "common/fs/fs_paths.h"
16#include "common/fs/path_util.h"
17#include "yuzu/breakpad.h"
18
19namespace Breakpad {
20
21static void PruneDumpDirectory(const std::filesystem::path& dump_path) {
22 // Code in this function should be exception-safe.
23 struct Entry {
24 std::filesystem::path path;
25 std::filesystem::file_time_type last_write_time;
26 };
27 std::vector<Entry> existing_dumps;
28
29 // Get existing entries.
30 std::error_code ec;
31 std::filesystem::directory_iterator dir(dump_path, ec);
32 for (auto& entry : dir) {
33 if (entry.is_regular_file()) {
34 existing_dumps.push_back(Entry{
35 .path = entry.path(),
36 .last_write_time = entry.last_write_time(ec),
37 });
38 }
39 }
40
41 // Sort descending by creation date.
42 std::ranges::stable_sort(existing_dumps, [](const auto& a, const auto& b) {
43 return a.last_write_time > b.last_write_time;
44 });
45
46 // Delete older dumps.
47 for (size_t i = 5; i < existing_dumps.size(); i++) {
48 std::filesystem::remove(existing_dumps[i].path, ec);
49 }
50}
51
52#if defined(__linux__)
53[[noreturn]] bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context,
54 bool succeeded) {
55 // Prevent time- and space-consuming core dumps from being generated, as we have
56 // already generated a minidump and a core file will not be useful anyway.
57 _exit(1);
58}
59#endif
60
61void InstallCrashHandler() {
62 // Write crash dumps to profile directory.
63 const auto dump_path = GetYuzuPath(Common::FS::YuzuPath::CrashDumpsDir);
64 PruneDumpDirectory(dump_path);
65
66#if defined(_WIN32)
67 // TODO: If we switch to MinGW builds for Windows, this needs to be wrapped in a C API.
68 static google_breakpad::ExceptionHandler eh{dump_path, nullptr, nullptr, nullptr,
69 google_breakpad::ExceptionHandler::HANDLER_ALL};
70#elif defined(__linux__)
71 static google_breakpad::MinidumpDescriptor descriptor{dump_path};
72 static google_breakpad::ExceptionHandler eh{descriptor, nullptr, DumpCallback,
73 nullptr, true, -1};
74#endif
75}
76
77} // namespace Breakpad
diff --git a/src/yuzu/breakpad.h b/src/yuzu/breakpad.h
new file mode 100644
index 000000000..0f911aa9c
--- /dev/null
+++ b/src/yuzu/breakpad.h
@@ -0,0 +1,10 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6namespace Breakpad {
7
8void InstallCrashHandler();
9
10}
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index b22fda746..ef421c754 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -27,16 +27,6 @@ ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent)
27 27
28 connect(ui->toggle_gdbstub, &QCheckBox::toggled, 28 connect(ui->toggle_gdbstub, &QCheckBox::toggled,
29 [&]() { ui->gdbport_spinbox->setEnabled(ui->toggle_gdbstub->isChecked()); }); 29 [&]() { ui->gdbport_spinbox->setEnabled(ui->toggle_gdbstub->isChecked()); });
30
31 connect(ui->create_crash_dumps, &QCheckBox::stateChanged, [&](int) {
32 if (crash_dump_warning_shown) {
33 return;
34 }
35 QMessageBox::warning(this, tr("Restart Required"),
36 tr("yuzu is required to restart in order to apply this setting."),
37 QMessageBox::Ok, QMessageBox::Ok);
38 crash_dump_warning_shown = true;
39 });
40} 30}
41 31
42ConfigureDebug::~ConfigureDebug() = default; 32ConfigureDebug::~ConfigureDebug() = default;
@@ -89,13 +79,6 @@ void ConfigureDebug::SetConfiguration() {
89 ui->disable_web_applet->setEnabled(false); 79 ui->disable_web_applet->setEnabled(false);
90 ui->disable_web_applet->setText(tr("Web applet not compiled")); 80 ui->disable_web_applet->setText(tr("Web applet not compiled"));
91#endif 81#endif
92
93#ifdef YUZU_DBGHELP
94 ui->create_crash_dumps->setChecked(Settings::values.create_crash_dumps.GetValue());
95#else
96 ui->create_crash_dumps->setEnabled(false);
97 ui->create_crash_dumps->setText(tr("MiniDump creation not compiled"));
98#endif
99} 82}
100 83
101void ConfigureDebug::ApplyConfiguration() { 84void ConfigureDebug::ApplyConfiguration() {
@@ -107,7 +90,6 @@ void ConfigureDebug::ApplyConfiguration() {
107 Settings::values.enable_fs_access_log = ui->fs_access_log->isChecked(); 90 Settings::values.enable_fs_access_log = ui->fs_access_log->isChecked();
108 Settings::values.reporting_services = ui->reporting_services->isChecked(); 91 Settings::values.reporting_services = ui->reporting_services->isChecked();
109 Settings::values.dump_audio_commands = ui->dump_audio_commands->isChecked(); 92 Settings::values.dump_audio_commands = ui->dump_audio_commands->isChecked();
110 Settings::values.create_crash_dumps = ui->create_crash_dumps->isChecked();
111 Settings::values.quest_flag = ui->quest_flag->isChecked(); 93 Settings::values.quest_flag = ui->quest_flag->isChecked();
112 Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked(); 94 Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
113 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked(); 95 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 66b8b7459..76fe98924 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -471,13 +471,6 @@
471 </property> 471 </property>
472 </widget> 472 </widget>
473 </item> 473 </item>
474 <item row="4" column="0">
475 <widget class="QCheckBox" name="create_crash_dumps">
476 <property name="text">
477 <string>Create Minidump After Crash</string>
478 </property>
479 </widget>
480 </item>
481 <item row="3" column="0"> 474 <item row="3" column="0">
482 <widget class="QCheckBox" name="dump_audio_commands"> 475 <widget class="QCheckBox" name="dump_audio_commands">
483 <property name="toolTip"> 476 <property name="toolTip">
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 5a48e388b..3dcad2701 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -101,13 +101,13 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
101 ui->tabPlayer5, ui->tabPlayer6, ui->tabPlayer7, ui->tabPlayer8, 101 ui->tabPlayer5, ui->tabPlayer6, ui->tabPlayer7, ui->tabPlayer8,
102 }; 102 };
103 103
104 player_connected = { 104 connected_controller_checkboxes = {
105 ui->checkboxPlayer1Connected, ui->checkboxPlayer2Connected, ui->checkboxPlayer3Connected, 105 ui->checkboxPlayer1Connected, ui->checkboxPlayer2Connected, ui->checkboxPlayer3Connected,
106 ui->checkboxPlayer4Connected, ui->checkboxPlayer5Connected, ui->checkboxPlayer6Connected, 106 ui->checkboxPlayer4Connected, ui->checkboxPlayer5Connected, ui->checkboxPlayer6Connected,
107 ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected, 107 ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected,
108 }; 108 };
109 109
110 std::array<QLabel*, 8> player_connected_labels = { 110 std::array<QLabel*, 8> connected_controller_labels = {
111 ui->label, ui->label_3, ui->label_4, ui->label_5, 111 ui->label, ui->label_3, ui->label_4, ui->label_5,
112 ui->label_6, ui->label_7, ui->label_8, ui->label_9, 112 ui->label_6, ui->label_7, ui->label_8, ui->label_9,
113 }; 113 };
@@ -115,23 +115,37 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
115 for (std::size_t i = 0; i < player_tabs.size(); ++i) { 115 for (std::size_t i = 0; i < player_tabs.size(); ++i) {
116 player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); 116 player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i]));
117 player_tabs[i]->layout()->addWidget(player_controllers[i]); 117 player_tabs[i]->layout()->addWidget(player_controllers[i]);
118 connect(player_connected[i], &QCheckBox::clicked, [this, i](int checked) { 118 connect(player_controllers[i], &ConfigureInputPlayer::Connected, [this, i](bool checked) {
119 // Ensures that the controllers are always connected in sequential order 119 // Ensures that connecting a controller changes the number of players
120 this->propagateMouseClickOnPlayers(i, checked, true); 120 if (connected_controller_checkboxes[i]->isChecked() != checked) {
121 // Ensures that the players are always connected in sequential order
122 PropagatePlayerNumberChanged(i, checked);
123 }
124 });
125 connect(connected_controller_checkboxes[i], &QCheckBox::clicked, [this, i](bool checked) {
126 // Reconnect current controller if it was the last one checked
127 // (player number was reduced by more than one)
128 const bool reconnect_first = !checked &&
129 i < connected_controller_checkboxes.size() - 1 &&
130 connected_controller_checkboxes[i + 1]->isChecked();
131
132 // Ensures that the players are always connected in sequential order
133 PropagatePlayerNumberChanged(i, checked, reconnect_first);
121 }); 134 });
122 connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices, this, 135 connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices, this,
123 &ConfigureInput::UpdateAllInputDevices); 136 &ConfigureInput::UpdateAllInputDevices);
124 connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this, 137 connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this,
125 &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection); 138 &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection);
126 connect(player_connected[i], &QCheckBox::stateChanged, [this, i](int state) { 139 connect(connected_controller_checkboxes[i], &QCheckBox::stateChanged, [this, i](int state) {
140 // Keep activated controllers synced with the "Connected Controllers" checkboxes
127 player_controllers[i]->ConnectPlayer(state == Qt::Checked); 141 player_controllers[i]->ConnectPlayer(state == Qt::Checked);
128 }); 142 });
129 143
130 // Remove/hide all the elements that exceed max_players, if applicable. 144 // Remove/hide all the elements that exceed max_players, if applicable.
131 if (i >= max_players) { 145 if (i >= max_players) {
132 ui->tabWidget->removeTab(static_cast<int>(max_players)); 146 ui->tabWidget->removeTab(static_cast<int>(max_players));
133 player_connected[i]->hide(); 147 connected_controller_checkboxes[i]->hide();
134 player_connected_labels[i]->hide(); 148 connected_controller_labels[i]->hide();
135 } 149 }
136 } 150 }
137 // Only the first player can choose handheld mode so connect the signal just to player 1 151 // Only the first player can choose handheld mode so connect the signal just to player 1
@@ -175,28 +189,25 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
175 LoadConfiguration(); 189 LoadConfiguration();
176} 190}
177 191
178void ConfigureInput::propagateMouseClickOnPlayers(size_t player_index, bool checked, bool origin) { 192void ConfigureInput::PropagatePlayerNumberChanged(size_t player_index, bool checked,
179 // Origin has already been toggled 193 bool reconnect_current) {
180 if (!origin) { 194 connected_controller_checkboxes[player_index]->setChecked(checked);
181 player_connected[player_index]->setChecked(checked);
182 }
183 195
184 if (checked) { 196 if (checked) {
185 // Check all previous buttons when checked 197 // Check all previous buttons when checked
186 if (player_index > 0) { 198 if (player_index > 0) {
187 propagateMouseClickOnPlayers(player_index - 1, checked, false); 199 PropagatePlayerNumberChanged(player_index - 1, checked);
188 } 200 }
189 } else { 201 } else {
190 // Unchecked all following buttons when unchecked 202 // Unchecked all following buttons when unchecked
191 if (player_index < player_tabs.size() - 1) { 203 if (player_index < connected_controller_checkboxes.size() - 1) {
192 // Reconnect current player if it was the last one checked 204 PropagatePlayerNumberChanged(player_index + 1, checked);
193 // (player number was reduced by more than one)
194 if (origin && player_connected[player_index + 1]->checkState() == Qt::Checked) {
195 player_connected[player_index]->setCheckState(Qt::Checked);
196 }
197 propagateMouseClickOnPlayers(player_index + 1, checked, false);
198 } 205 }
199 } 206 }
207
208 if (reconnect_current) {
209 connected_controller_checkboxes[player_index]->setCheckState(Qt::Checked);
210 }
200} 211}
201 212
202QList<QWidget*> ConfigureInput::GetSubTabs() const { 213QList<QWidget*> ConfigureInput::GetSubTabs() const {
@@ -249,17 +260,17 @@ void ConfigureInput::LoadConfiguration() {
249} 260}
250 261
251void ConfigureInput::LoadPlayerControllerIndices() { 262void ConfigureInput::LoadPlayerControllerIndices() {
252 for (std::size_t i = 0; i < player_connected.size(); ++i) { 263 for (std::size_t i = 0; i < connected_controller_checkboxes.size(); ++i) {
253 if (i == 0) { 264 if (i == 0) {
254 auto* handheld = 265 auto* handheld =
255 system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); 266 system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
256 if (handheld->IsConnected()) { 267 if (handheld->IsConnected()) {
257 player_connected[i]->setChecked(true); 268 connected_controller_checkboxes[i]->setChecked(true);
258 continue; 269 continue;
259 } 270 }
260 } 271 }
261 const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(i); 272 const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(i);
262 player_connected[i]->setChecked(controller->IsConnected()); 273 connected_controller_checkboxes[i]->setChecked(controller->IsConnected());
263 } 274 }
264} 275}
265 276
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index abb7f7089..136cd3a0a 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -56,7 +56,9 @@ private:
56 void UpdateDockedState(bool is_handheld); 56 void UpdateDockedState(bool is_handheld);
57 void UpdateAllInputDevices(); 57 void UpdateAllInputDevices();
58 void UpdateAllInputProfiles(std::size_t player_index); 58 void UpdateAllInputProfiles(std::size_t player_index);
59 void propagateMouseClickOnPlayers(size_t player_index, bool origin, bool checked); 59 // Enable preceding controllers or disable following ones
60 void PropagatePlayerNumberChanged(size_t player_index, bool checked,
61 bool reconnect_current = false);
60 62
61 /// Load configuration settings. 63 /// Load configuration settings.
62 void LoadConfiguration(); 64 void LoadConfiguration();
@@ -71,7 +73,8 @@ private:
71 73
72 std::array<ConfigureInputPlayer*, 8> player_controllers; 74 std::array<ConfigureInputPlayer*, 8> player_controllers;
73 std::array<QWidget*, 8> player_tabs; 75 std::array<QWidget*, 8> player_tabs;
74 std::array<QCheckBox*, 8> player_connected; 76 // Checkboxes representing the "Connected Controllers".
77 std::array<QCheckBox*, 8> connected_controller_checkboxes;
75 ConfigureInputAdvanced* advanced; 78 ConfigureInputAdvanced* advanced;
76 79
77 Core::System& system; 80 Core::System& system;
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index d4df43d73..d3255d2b4 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -75,7 +75,7 @@ public:
75 void ClearAll(); 75 void ClearAll();
76 76
77signals: 77signals:
78 /// Emitted when this controller is connected by the user. 78 /// Emitted when this controller is (dis)connected by the user.
79 void Connected(bool connected); 79 void Connected(bool connected);
80 /// Emitted when the Handheld mode is selected (undocked with dual joycons attached). 80 /// Emitted when the Handheld mode is selected (undocked with dual joycons attached).
81 void HandheldStateChanged(bool is_handheld); 81 void HandheldStateChanged(bool is_handheld);
@@ -183,9 +183,6 @@ private:
183 /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum. 183 /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum.
184 std::vector<std::pair<int, Core::HID::NpadStyleIndex>> index_controller_type_pairs; 184 std::vector<std::pair<int, Core::HID::NpadStyleIndex>> index_controller_type_pairs;
185 185
186 static constexpr int PLAYER_COUNT = 8;
187 std::array<QCheckBox*, PLAYER_COUNT> player_connected_checkbox;
188
189 /// This will be the the setting function when an input is awaiting configuration. 186 /// This will be the the setting function when an input is awaiting configuration.
190 std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; 187 std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
191 188
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 3fe448f27..1434b1a56 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -156,7 +156,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
156 // Ui General 156 // Ui General
157 INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); 157 INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", "");
158 INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); 158 INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", "");
159 INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", "");
160 INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", ""); 159 INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", "");
161 INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); 160 INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", "");
162 INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); 161 INSERT(UISettings, controller_applet_disabled, "Disable controller applet", "");
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 0783a2430..7049c57b6 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -127,7 +127,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons
127 return list; 127 return list;
128 } 128 }
129 129
130 if (thread.GetOwnerProcess() == nullptr || !thread.GetOwnerProcess()->Is64BitProcess()) { 130 if (thread.GetOwnerProcess() == nullptr || !thread.GetOwnerProcess()->Is64Bit()) {
131 return list; 131 return list;
132 } 132 }
133 133
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 90433e245..f294dc23d 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -380,7 +380,6 @@ void GameList::UnloadController() {
380 380
381GameList::~GameList() { 381GameList::~GameList() {
382 UnloadController(); 382 UnloadController();
383 emit ShouldCancelWorker();
384} 383}
385 384
386void GameList::SetFilterFocus() { 385void GameList::SetFilterFocus() {
@@ -397,6 +396,10 @@ void GameList::ClearFilter() {
397 search_field->clear(); 396 search_field->clear();
398} 397}
399 398
399void GameList::WorkerEvent() {
400 current_worker->ProcessEvents(this);
401}
402
400void GameList::AddDirEntry(GameListDir* entry_items) { 403void GameList::AddDirEntry(GameListDir* entry_items) {
401 item_model->invisibleRootItem()->appendRow(entry_items); 404 item_model->invisibleRootItem()->appendRow(entry_items);
402 tree_view->setExpanded( 405 tree_view->setExpanded(
@@ -828,28 +831,21 @@ void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
828 tree_view->setColumnHidden(COLUMN_SIZE, !UISettings::values.show_size); 831 tree_view->setColumnHidden(COLUMN_SIZE, !UISettings::values.show_size);
829 tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time); 832 tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time);
830 833
831 // Before deleting rows, cancel the worker so that it is not using them 834 // Cancel any existing worker.
832 emit ShouldCancelWorker(); 835 current_worker.reset();
833 836
834 // Delete any rows that might already exist if we're repopulating 837 // Delete any rows that might already exist if we're repopulating
835 item_model->removeRows(0, item_model->rowCount()); 838 item_model->removeRows(0, item_model->rowCount());
836 search_field->clear(); 839 search_field->clear();
837 840
838 GameListWorker* worker = 841 current_worker = std::make_unique<GameListWorker>(vfs, provider, game_dirs, compatibility_list,
839 new GameListWorker(vfs, provider, game_dirs, compatibility_list, play_time_manager, system); 842 play_time_manager, system);
840 843
841 connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); 844 // Get events from the worker as data becomes available
842 connect(worker, &GameListWorker::DirEntryReady, this, &GameList::AddDirEntry, 845 connect(current_worker.get(), &GameListWorker::DataAvailable, this, &GameList::WorkerEvent,
843 Qt::QueuedConnection);
844 connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
845 Qt::QueuedConnection); 846 Qt::QueuedConnection);
846 // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to
847 // cancel without delay.
848 connect(this, &GameList::ShouldCancelWorker, worker, &GameListWorker::Cancel,
849 Qt::DirectConnection);
850 847
851 QThreadPool::globalInstance()->start(worker); 848 QThreadPool::globalInstance()->start(current_worker.get());
852 current_worker = std::move(worker);
853} 849}
854 850
855void GameList::SaveInterfaceLayout() { 851void GameList::SaveInterfaceLayout() {
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 712570cea..563a3a35b 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -109,7 +109,6 @@ signals:
109 void BootGame(const QString& game_path, u64 program_id, std::size_t program_index, 109 void BootGame(const QString& game_path, u64 program_id, std::size_t program_index,
110 StartGameType type, AmLaunchType launch_type); 110 StartGameType type, AmLaunchType launch_type);
111 void GameChosen(const QString& game_path, const u64 title_id = 0); 111 void GameChosen(const QString& game_path, const u64 title_id = 0);
112 void ShouldCancelWorker();
113 void OpenFolderRequested(u64 program_id, GameListOpenTarget target, 112 void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
114 const std::string& game_path); 113 const std::string& game_path);
115 void OpenTransferableShaderCacheRequested(u64 program_id); 114 void OpenTransferableShaderCacheRequested(u64 program_id);
@@ -138,11 +137,16 @@ private slots:
138 void OnUpdateThemedIcons(); 137 void OnUpdateThemedIcons();
139 138
140private: 139private:
140 friend class GameListWorker;
141 void WorkerEvent();
142
141 void AddDirEntry(GameListDir* entry_items); 143 void AddDirEntry(GameListDir* entry_items);
142 void AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent); 144 void AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent);
143 void ValidateEntry(const QModelIndex& item);
144 void DonePopulating(const QStringList& watch_list); 145 void DonePopulating(const QStringList& watch_list);
145 146
147private:
148 void ValidateEntry(const QModelIndex& item);
149
146 void RefreshGameDirectory(); 150 void RefreshGameDirectory();
147 151
148 void ToggleFavorite(u64 program_id); 152 void ToggleFavorite(u64 program_id);
@@ -165,7 +169,7 @@ private:
165 QVBoxLayout* layout = nullptr; 169 QVBoxLayout* layout = nullptr;
166 QTreeView* tree_view = nullptr; 170 QTreeView* tree_view = nullptr;
167 QStandardItemModel* item_model = nullptr; 171 QStandardItemModel* item_model = nullptr;
168 GameListWorker* current_worker = nullptr; 172 std::unique_ptr<GameListWorker> current_worker;
169 QFileSystemWatcher* watcher = nullptr; 173 QFileSystemWatcher* watcher = nullptr;
170 ControllerNavigation* controller_navigation = nullptr; 174 ControllerNavigation* controller_navigation = nullptr;
171 CompatibilityList compatibility_list; 175 CompatibilityList compatibility_list;
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 077ced12b..69be21027 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -233,10 +233,53 @@ GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_,
233 const PlayTime::PlayTimeManager& play_time_manager_, 233 const PlayTime::PlayTimeManager& play_time_manager_,
234 Core::System& system_) 234 Core::System& system_)
235 : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_}, 235 : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_},
236 compatibility_list{compatibility_list_}, 236 compatibility_list{compatibility_list_}, play_time_manager{play_time_manager_}, system{
237 play_time_manager{play_time_manager_}, system{system_} {} 237 system_} {
238 // We want the game list to manage our lifetime.
239 setAutoDelete(false);
240}
241
242GameListWorker::~GameListWorker() {
243 this->disconnect();
244 stop_requested.store(true);
245 processing_completed.Wait();
246}
247
248void GameListWorker::ProcessEvents(GameList* game_list) {
249 while (true) {
250 std::function<void(GameList*)> func;
251 {
252 // Lock queue to protect concurrent modification.
253 std::scoped_lock lk(lock);
254
255 // If we can't pop a function, return.
256 if (queued_events.empty()) {
257 return;
258 }
259
260 // Pop a function.
261 func = std::move(queued_events.back());
262 queued_events.pop_back();
263 }
264
265 // Run the function.
266 func(game_list);
267 }
268}
269
270template <typename F>
271void GameListWorker::RecordEvent(F&& func) {
272 {
273 // Lock queue to protect concurrent modification.
274 std::scoped_lock lk(lock);
238 275
239GameListWorker::~GameListWorker() = default; 276 // Add the function into the front of the queue.
277 queued_events.emplace_front(std::move(func));
278 }
279
280 // Data now available.
281 emit DataAvailable();
282}
240 283
241void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { 284void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
242 using namespace FileSys; 285 using namespace FileSys;
@@ -284,9 +327,9 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
284 GetMetadataFromControlNCA(patch, *control, icon, name); 327 GetMetadataFromControlNCA(patch, *control, icon, name);
285 } 328 }
286 329
287 emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, file->GetSize(), icon, *loader, 330 auto entry = MakeGameListEntry(file->GetFullPath(), name, file->GetSize(), icon, *loader,
288 program_id, compatibility_list, play_time_manager, patch), 331 program_id, compatibility_list, play_time_manager, patch);
289 parent_dir); 332 RecordEvent([=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
290 } 333 }
291} 334}
292 335
@@ -360,11 +403,12 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
360 const FileSys::PatchManager patch{id, system.GetFileSystemController(), 403 const FileSys::PatchManager patch{id, system.GetFileSystemController(),
361 system.GetContentProvider()}; 404 system.GetContentProvider()};
362 405
363 emit EntryReady(MakeGameListEntry(physical_name, name, 406 auto entry = MakeGameListEntry(
364 Common::FS::GetSize(physical_name), icon, 407 physical_name, name, Common::FS::GetSize(physical_name), icon, *loader,
365 *loader, id, compatibility_list, 408 id, compatibility_list, play_time_manager, patch);
366 play_time_manager, patch), 409
367 parent_dir); 410 RecordEvent(
411 [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
368 } 412 }
369 } else { 413 } else {
370 std::vector<u8> icon; 414 std::vector<u8> icon;
@@ -376,11 +420,12 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
376 const FileSys::PatchManager patch{program_id, system.GetFileSystemController(), 420 const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
377 system.GetContentProvider()}; 421 system.GetContentProvider()};
378 422
379 emit EntryReady(MakeGameListEntry(physical_name, name, 423 auto entry = MakeGameListEntry(
380 Common::FS::GetSize(physical_name), icon, 424 physical_name, name, Common::FS::GetSize(physical_name), icon, *loader,
381 *loader, program_id, compatibility_list, 425 program_id, compatibility_list, play_time_manager, patch);
382 play_time_manager, patch), 426
383 parent_dir); 427 RecordEvent(
428 [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
384 } 429 }
385 } 430 }
386 } else if (is_dir) { 431 } else if (is_dir) {
@@ -399,25 +444,34 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
399} 444}
400 445
401void GameListWorker::run() { 446void GameListWorker::run() {
447 watch_list.clear();
402 provider->ClearAllEntries(); 448 provider->ClearAllEntries();
403 449
450 const auto DirEntryReady = [&](GameListDir* game_list_dir) {
451 RecordEvent([=](GameList* game_list) { game_list->AddDirEntry(game_list_dir); });
452 };
453
404 for (UISettings::GameDir& game_dir : game_dirs) { 454 for (UISettings::GameDir& game_dir : game_dirs) {
455 if (stop_requested) {
456 break;
457 }
458
405 if (game_dir.path == QStringLiteral("SDMC")) { 459 if (game_dir.path == QStringLiteral("SDMC")) {
406 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SdmcDir); 460 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SdmcDir);
407 emit DirEntryReady(game_list_dir); 461 DirEntryReady(game_list_dir);
408 AddTitlesToGameList(game_list_dir); 462 AddTitlesToGameList(game_list_dir);
409 } else if (game_dir.path == QStringLiteral("UserNAND")) { 463 } else if (game_dir.path == QStringLiteral("UserNAND")) {
410 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::UserNandDir); 464 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::UserNandDir);
411 emit DirEntryReady(game_list_dir); 465 DirEntryReady(game_list_dir);
412 AddTitlesToGameList(game_list_dir); 466 AddTitlesToGameList(game_list_dir);
413 } else if (game_dir.path == QStringLiteral("SysNAND")) { 467 } else if (game_dir.path == QStringLiteral("SysNAND")) {
414 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SysNandDir); 468 auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SysNandDir);
415 emit DirEntryReady(game_list_dir); 469 DirEntryReady(game_list_dir);
416 AddTitlesToGameList(game_list_dir); 470 AddTitlesToGameList(game_list_dir);
417 } else { 471 } else {
418 watch_list.append(game_dir.path); 472 watch_list.append(game_dir.path);
419 auto* const game_list_dir = new GameListDir(game_dir); 473 auto* const game_list_dir = new GameListDir(game_dir);
420 emit DirEntryReady(game_list_dir); 474 DirEntryReady(game_list_dir);
421 ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path.toStdString(), 475 ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path.toStdString(),
422 game_dir.deep_scan, game_list_dir); 476 game_dir.deep_scan, game_list_dir);
423 ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path.toStdString(), 477 ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path.toStdString(),
@@ -425,12 +479,6 @@ void GameListWorker::run() {
425 } 479 }
426 } 480 }
427 481
428 emit Finished(watch_list); 482 RecordEvent([=](GameList* game_list) { game_list->DonePopulating(watch_list); });
429 processing_completed.Set(); 483 processing_completed.Set();
430} 484}
431
432void GameListWorker::Cancel() {
433 this->disconnect();
434 stop_requested.store(true);
435 processing_completed.Wait();
436}
diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h
index 54dc05e30..d5990fcde 100644
--- a/src/yuzu/game_list_worker.h
+++ b/src/yuzu/game_list_worker.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <atomic> 6#include <atomic>
7#include <deque>
7#include <memory> 8#include <memory>
8#include <string> 9#include <string>
9 10
@@ -20,6 +21,7 @@ namespace Core {
20class System; 21class System;
21} 22}
22 23
24class GameList;
23class QStandardItem; 25class QStandardItem;
24 26
25namespace FileSys { 27namespace FileSys {
@@ -46,24 +48,22 @@ public:
46 /// Starts the processing of directory tree information. 48 /// Starts the processing of directory tree information.
47 void run() override; 49 void run() override;
48 50
49 /// Tells the worker that it should no longer continue processing. Thread-safe. 51public:
50 void Cancel();
51
52signals:
53 /** 52 /**
54 * The `EntryReady` signal is emitted once an entry has been prepared and is ready 53 * Synchronously processes any events queued by the worker.
55 * to be added to the game list. 54 *
56 * @param entry_items a list with `QStandardItem`s that make up the columns of the new 55 * AddDirEntry is called on the game list for every discovered directory.
57 * entry. 56 * AddEntry is called on the game list for every discovered program.
57 * DonePopulating is called on the game list when processing completes.
58 */ 58 */
59 void DirEntryReady(GameListDir* entry_items); 59 void ProcessEvents(GameList* game_list);
60 void EntryReady(QList<QStandardItem*> entry_items, GameListDir* parent_dir);
61 60
62 /** 61signals:
63 * After the worker has traversed the game directory looking for entries, this signal is 62 void DataAvailable();
64 * emitted with a list of folders that should be watched for changes as well. 63
65 */ 64private:
66 void Finished(QStringList watch_list); 65 template <typename F>
66 void RecordEvent(F&& func);
67 67
68private: 68private:
69 void AddTitlesToGameList(GameListDir* parent_dir); 69 void AddTitlesToGameList(GameListDir* parent_dir);
@@ -84,8 +84,11 @@ private:
84 84
85 QStringList watch_list; 85 QStringList watch_list;
86 86
87 Common::Event processing_completed; 87 std::mutex lock;
88 std::condition_variable cv;
89 std::deque<std::function<void(GameList*)>> queued_events;
88 std::atomic_bool stop_requested = false; 90 std::atomic_bool stop_requested = false;
91 Common::Event processing_completed;
89 92
90 Core::System& system; 93 Core::System& system;
91}; 94};
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 73cd06478..c8efd1917 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -159,8 +159,8 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
159#include "yuzu/util/clickable_label.h" 159#include "yuzu/util/clickable_label.h"
160#include "yuzu/vk_device_info.h" 160#include "yuzu/vk_device_info.h"
161 161
162#ifdef YUZU_DBGHELP 162#ifdef YUZU_CRASH_DUMPS
163#include "yuzu/mini_dump.h" 163#include "yuzu/breakpad.h"
164#endif 164#endif
165 165
166using namespace Common::Literals; 166using namespace Common::Literals;
@@ -1072,7 +1072,7 @@ void GMainWindow::InitializeWidgets() {
1072 }); 1072 });
1073 volume_popup->layout()->addWidget(volume_slider); 1073 volume_popup->layout()->addWidget(volume_slider);
1074 1074
1075 volume_button = new QPushButton(); 1075 volume_button = new VolumeButton();
1076 volume_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); 1076 volume_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
1077 volume_button->setFocusPolicy(Qt::NoFocus); 1077 volume_button->setFocusPolicy(Qt::NoFocus);
1078 volume_button->setCheckable(true); 1078 volume_button->setCheckable(true);
@@ -1103,6 +1103,8 @@ void GMainWindow::InitializeWidgets() {
1103 context_menu.exec(volume_button->mapToGlobal(menu_location)); 1103 context_menu.exec(volume_button->mapToGlobal(menu_location));
1104 volume_button->repaint(); 1104 volume_button->repaint();
1105 }); 1105 });
1106 connect(volume_button, &VolumeButton::VolumeChanged, this, &GMainWindow::UpdateVolumeUI);
1107
1106 statusBar()->insertPermanentWidget(0, volume_button); 1108 statusBar()->insertPermanentWidget(0, volume_button);
1107 1109
1108 // setup AA button 1110 // setup AA button
@@ -2019,7 +2021,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
2019 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())} 2021 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}
2020 .filename()); 2022 .filename());
2021 } 2023 }
2022 const bool is_64bit = system->Kernel().ApplicationProcess()->Is64BitProcess(); 2024 const bool is_64bit = system->Kernel().ApplicationProcess()->Is64Bit();
2023 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)"); 2025 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
2024 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit") 2026 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
2025 .arg(QString::fromStdString(title_name), instruction_set_suffix) 2027 .arg(QString::fromStdString(title_name), instruction_set_suffix)
@@ -2172,6 +2174,7 @@ void GMainWindow::ShutdownGame() {
2172 return; 2174 return;
2173 } 2175 }
2174 2176
2177 play_time_manager->Stop();
2175 OnShutdownBegin(); 2178 OnShutdownBegin();
2176 OnEmulationStopTimeExpired(); 2179 OnEmulationStopTimeExpired();
2177 OnEmulationStopped(); 2180 OnEmulationStopped();
@@ -2735,7 +2738,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2735 return; 2738 return;
2736 } 2739 }
2737 2740
2738 const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full); 2741 const auto extracted = FileSys::ExtractRomFS(romfs);
2739 if (extracted == nullptr) { 2742 if (extracted == nullptr) {
2740 failed(); 2743 failed();
2741 return; 2744 return;
@@ -2980,7 +2983,7 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi
2980#elif defined(__linux__) || defined(__FreeBSD__) 2983#elif defined(__linux__) || defined(__FreeBSD__)
2981 out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256"; 2984 out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256";
2982#endif 2985#endif
2983 2986
2984 // Create icons directory if it doesn't exist 2987 // Create icons directory if it doesn't exist
2985 if (!Common::FS::CreateDirs(out_icon_path)) { 2988 if (!Common::FS::CreateDirs(out_icon_path)) {
2986 QMessageBox::critical( 2989 QMessageBox::critical(
@@ -3571,7 +3574,7 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) {
3571} 3574}
3572 3575
3573void GMainWindow::OnExit() { 3576void GMainWindow::OnExit() {
3574 OnStopGame(); 3577 ShutdownGame();
3575} 3578}
3576 3579
3577void GMainWindow::OnSaveConfig() { 3580void GMainWindow::OnSaveConfig() {
@@ -4087,6 +4090,66 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
4087 } 4090 }
4088} 4091}
4089 4092
4093bool GMainWindow::CreateShortcut(const std::string& shortcut_path, const std::string& title,
4094 const std::string& comment, const std::string& icon_path,
4095 const std::string& command, const std::string& arguments,
4096 const std::string& categories, const std::string& keywords) {
4097#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
4098 // This desktop file template was writing referencing
4099 // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html
4100 std::string shortcut_contents{};
4101 shortcut_contents.append("[Desktop Entry]\n");
4102 shortcut_contents.append("Type=Application\n");
4103 shortcut_contents.append("Version=1.0\n");
4104 shortcut_contents.append(fmt::format("Name={:s}\n", title));
4105 shortcut_contents.append(fmt::format("Comment={:s}\n", comment));
4106 shortcut_contents.append(fmt::format("Icon={:s}\n", icon_path));
4107 shortcut_contents.append(fmt::format("TryExec={:s}\n", command));
4108 shortcut_contents.append(fmt::format("Exec={:s} {:s}\n", command, arguments));
4109 shortcut_contents.append(fmt::format("Categories={:s}\n", categories));
4110 shortcut_contents.append(fmt::format("Keywords={:s}\n", keywords));
4111
4112 std::ofstream shortcut_stream(shortcut_path);
4113 if (!shortcut_stream.is_open()) {
4114 LOG_WARNING(Common, "Failed to create file {:s}", shortcut_path);
4115 return false;
4116 }
4117 shortcut_stream << shortcut_contents;
4118 shortcut_stream.close();
4119
4120 return true;
4121#elif defined(WIN32)
4122 IShellLinkW* shell_link;
4123 auto hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
4124 (void**)&shell_link);
4125 if (FAILED(hres)) {
4126 return false;
4127 }
4128 shell_link->SetPath(
4129 Common::UTF8ToUTF16W(command).data()); // Path to the object we are referring to
4130 shell_link->SetArguments(Common::UTF8ToUTF16W(arguments).data());
4131 shell_link->SetDescription(Common::UTF8ToUTF16W(comment).data());
4132 shell_link->SetIconLocation(Common::UTF8ToUTF16W(icon_path).data(), 0);
4133
4134 IPersistFile* persist_file;
4135 hres = shell_link->QueryInterface(IID_IPersistFile, (void**)&persist_file);
4136 if (FAILED(hres)) {
4137 return false;
4138 }
4139
4140 hres = persist_file->Save(Common::UTF8ToUTF16W(shortcut_path).data(), TRUE);
4141 if (FAILED(hres)) {
4142 return false;
4143 }
4144
4145 persist_file->Release();
4146 shell_link->Release();
4147
4148 return true;
4149#endif
4150 return false;
4151}
4152
4090void GMainWindow::OnLoadAmiibo() { 4153void GMainWindow::OnLoadAmiibo() {
4091 if (emu_thread == nullptr || !emu_thread->IsRunning()) { 4154 if (emu_thread == nullptr || !emu_thread->IsRunning()) {
4092 return; 4155 return;
@@ -4873,7 +4936,12 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe
4873} 4936}
4874 4937
4875bool GMainWindow::ConfirmClose() { 4938bool GMainWindow::ConfirmClose() {
4876 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) { 4939 if (emu_thread == nullptr ||
4940 UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) {
4941 return true;
4942 }
4943 if (!system->GetExitLocked() &&
4944 UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) {
4877 return true; 4945 return true;
4878 } 4946 }
4879 const auto text = tr("Are you sure you want to close yuzu?"); 4947 const auto text = tr("Are you sure you want to close yuzu?");
@@ -4978,7 +5046,7 @@ bool GMainWindow::ConfirmChangeGame() {
4978} 5046}
4979 5047
4980bool GMainWindow::ConfirmForceLockedExit() { 5048bool GMainWindow::ConfirmForceLockedExit() {
4981 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) { 5049 if (emu_thread == nullptr) {
4982 return true; 5050 return true;
4983 } 5051 }
4984 const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" 5052 const auto text = tr("The currently running application has requested yuzu to not exit.\n\n"
@@ -5154,6 +5222,32 @@ void GMainWindow::changeEvent(QEvent* event) {
5154 QWidget::changeEvent(event); 5222 QWidget::changeEvent(event);
5155} 5223}
5156 5224
5225void VolumeButton::wheelEvent(QWheelEvent* event) {
5226
5227 int num_degrees = event->angleDelta().y() / 8;
5228 int num_steps = (num_degrees / 15) * scroll_multiplier;
5229 // Stated in QT docs: Most mouse types work in steps of 15 degrees, in which case the delta
5230 // value is a multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
5231
5232 if (num_steps > 0) {
5233 Settings::values.volume.SetValue(
5234 std::min(200, Settings::values.volume.GetValue() + num_steps));
5235 } else {
5236 Settings::values.volume.SetValue(
5237 std::max(0, Settings::values.volume.GetValue() + num_steps));
5238 }
5239
5240 scroll_multiplier = std::min(MaxMultiplier, scroll_multiplier * 2);
5241 scroll_timer.start(100); // reset the multiplier if no scroll event occurs within 100 ms
5242
5243 emit VolumeChanged();
5244 event->accept();
5245}
5246
5247void VolumeButton::ResetMultiplier() {
5248 scroll_multiplier = 1;
5249}
5250
5157#ifdef main 5251#ifdef main
5158#undef main 5252#undef main
5159#endif 5253#endif
@@ -5215,22 +5309,15 @@ int main(int argc, char* argv[]) {
5215 return 0; 5309 return 0;
5216 } 5310 }
5217 5311
5218#ifdef YUZU_DBGHELP
5219 PROCESS_INFORMATION pi;
5220 if (!is_child && Settings::values.create_crash_dumps.GetValue() &&
5221 MiniDump::SpawnDebuggee(argv[0], pi)) {
5222 // Delete the config object so that it doesn't save when the program exits
5223 config.reset(nullptr);
5224 MiniDump::DebugDebuggee(pi);
5225 return 0;
5226 }
5227#endif
5228
5229 if (StartupChecks(argv[0], &has_broken_vulkan, 5312 if (StartupChecks(argv[0], &has_broken_vulkan,
5230 Settings::values.perform_vulkan_check.GetValue())) { 5313 Settings::values.perform_vulkan_check.GetValue())) {
5231 return 0; 5314 return 0;
5232 } 5315 }
5233 5316
5317#ifdef YUZU_CRASH_DUMPS
5318 Breakpad::InstallCrashHandler();
5319#endif
5320
5234 Common::DetachedTasks detached_tasks; 5321 Common::DetachedTasks detached_tasks;
5235 MicroProfileOnThreadCreate("Frontend"); 5322 MicroProfileOnThreadCreate("Frontend");
5236 SCOPE_EXIT({ MicroProfileShutdown(); }); 5323 SCOPE_EXIT({ MicroProfileShutdown(); });
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index d203e5301..f67c4cfda 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -9,6 +9,7 @@
9#include <filesystem> 9#include <filesystem>
10#include <QMainWindow> 10#include <QMainWindow>
11#include <QMessageBox> 11#include <QMessageBox>
12#include <QPushButton>
12#include <QTimer> 13#include <QTimer>
13#include <QTranslator> 14#include <QTranslator>
14 15
@@ -138,6 +139,28 @@ namespace VkDeviceInfo {
138class Record; 139class Record;
139} 140}
140 141
142class VolumeButton : public QPushButton {
143 Q_OBJECT
144public:
145 explicit VolumeButton(QWidget* parent = nullptr) : QPushButton(parent), scroll_multiplier(1) {
146 connect(&scroll_timer, &QTimer::timeout, this, &VolumeButton::ResetMultiplier);
147 }
148
149signals:
150 void VolumeChanged();
151
152protected:
153 void wheelEvent(QWheelEvent* event) override;
154
155private slots:
156 void ResetMultiplier();
157
158private:
159 int scroll_multiplier;
160 QTimer scroll_timer;
161 constexpr static int MaxMultiplier = 8;
162};
163
141class GMainWindow : public QMainWindow { 164class GMainWindow : public QMainWindow {
142 Q_OBJECT 165 Q_OBJECT
143 166
@@ -492,7 +515,7 @@ private:
492 QPushButton* dock_status_button = nullptr; 515 QPushButton* dock_status_button = nullptr;
493 QPushButton* filter_status_button = nullptr; 516 QPushButton* filter_status_button = nullptr;
494 QPushButton* aa_status_button = nullptr; 517 QPushButton* aa_status_button = nullptr;
495 QPushButton* volume_button = nullptr; 518 VolumeButton* volume_button = nullptr;
496 QWidget* volume_popup = nullptr; 519 QWidget* volume_popup = nullptr;
497 QSlider* volume_slider = nullptr; 520 QSlider* volume_slider = nullptr;
498 QTimer status_bar_update_timer; 521 QTimer status_bar_update_timer;
diff --git a/src/yuzu/mini_dump.cpp b/src/yuzu/mini_dump.cpp
deleted file mode 100644
index a34dc6a9c..000000000
--- a/src/yuzu/mini_dump.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <cstdio>
5#include <cstring>
6#include <ctime>
7#include <filesystem>
8#include <fmt/format.h>
9#include <windows.h>
10#include "yuzu/mini_dump.h"
11#include "yuzu/startup_checks.h"
12
13// dbghelp.h must be included after windows.h
14#include <dbghelp.h>
15
16namespace MiniDump {
17
18void CreateMiniDump(HANDLE process_handle, DWORD process_id, MINIDUMP_EXCEPTION_INFORMATION* info,
19 EXCEPTION_POINTERS* pep) {
20 char file_name[255];
21 const std::time_t the_time = std::time(nullptr);
22 std::strftime(file_name, 255, "yuzu-crash-%Y%m%d%H%M%S.dmp", std::localtime(&the_time));
23
24 // Open the file
25 HANDLE file_handle = CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE, 0, nullptr,
26 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
27
28 if (file_handle == nullptr || file_handle == INVALID_HANDLE_VALUE) {
29 fmt::print(stderr, "CreateFileA failed. Error: {}", GetLastError());
30 return;
31 }
32
33 // Create the minidump
34 const MINIDUMP_TYPE dump_type = MiniDumpNormal;
35
36 const bool write_dump_status = MiniDumpWriteDump(process_handle, process_id, file_handle,
37 dump_type, (pep != 0) ? info : 0, 0, 0);
38
39 if (write_dump_status) {
40 fmt::print(stderr, "MiniDump created: {}", file_name);
41 } else {
42 fmt::print(stderr, "MiniDumpWriteDump failed. Error: {}", GetLastError());
43 }
44
45 // Close the file
46 CloseHandle(file_handle);
47}
48
49void DumpFromDebugEvent(DEBUG_EVENT& deb_ev, PROCESS_INFORMATION& pi) {
50 EXCEPTION_RECORD& record = deb_ev.u.Exception.ExceptionRecord;
51
52 HANDLE thread_handle = OpenThread(THREAD_GET_CONTEXT, false, deb_ev.dwThreadId);
53 if (thread_handle == nullptr) {
54 fmt::print(stderr, "OpenThread failed ({})", GetLastError());
55 return;
56 }
57
58 // Get child process context
59 CONTEXT context = {};
60 context.ContextFlags = CONTEXT_ALL;
61 if (!GetThreadContext(thread_handle, &context)) {
62 fmt::print(stderr, "GetThreadContext failed ({})", GetLastError());
63 return;
64 }
65
66 // Create exception pointers for minidump
67 EXCEPTION_POINTERS ep;
68 ep.ExceptionRecord = &record;
69 ep.ContextRecord = &context;
70
71 MINIDUMP_EXCEPTION_INFORMATION info;
72 info.ThreadId = deb_ev.dwThreadId;
73 info.ExceptionPointers = &ep;
74 info.ClientPointers = false;
75
76 CreateMiniDump(pi.hProcess, pi.dwProcessId, &info, &ep);
77
78 if (CloseHandle(thread_handle) == 0) {
79 fmt::print(stderr, "error: CloseHandle(thread_handle) failed ({})", GetLastError());
80 }
81}
82
83bool SpawnDebuggee(const char* arg0, PROCESS_INFORMATION& pi) {
84 std::memset(&pi, 0, sizeof(pi));
85
86 // Don't debug if we are already being debugged
87 if (IsDebuggerPresent()) {
88 return false;
89 }
90
91 if (!SpawnChild(arg0, &pi, 0)) {
92 fmt::print(stderr, "warning: continuing without crash dumps");
93 return false;
94 }
95
96 const bool can_debug = DebugActiveProcess(pi.dwProcessId);
97 if (!can_debug) {
98 fmt::print(stderr,
99 "warning: DebugActiveProcess failed ({}), continuing without crash dumps",
100 GetLastError());
101 return false;
102 }
103
104 return true;
105}
106
107static const char* ExceptionName(DWORD exception) {
108 switch (exception) {
109 case EXCEPTION_ACCESS_VIOLATION:
110 return "EXCEPTION_ACCESS_VIOLATION";
111 case EXCEPTION_DATATYPE_MISALIGNMENT:
112 return "EXCEPTION_DATATYPE_MISALIGNMENT";
113 case EXCEPTION_BREAKPOINT:
114 return "EXCEPTION_BREAKPOINT";
115 case EXCEPTION_SINGLE_STEP:
116 return "EXCEPTION_SINGLE_STEP";
117 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
118 return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
119 case EXCEPTION_FLT_DENORMAL_OPERAND:
120 return "EXCEPTION_FLT_DENORMAL_OPERAND";
121 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
122 return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
123 case EXCEPTION_FLT_INEXACT_RESULT:
124 return "EXCEPTION_FLT_INEXACT_RESULT";
125 case EXCEPTION_FLT_INVALID_OPERATION:
126 return "EXCEPTION_FLT_INVALID_OPERATION";
127 case EXCEPTION_FLT_OVERFLOW:
128 return "EXCEPTION_FLT_OVERFLOW";
129 case EXCEPTION_FLT_STACK_CHECK:
130 return "EXCEPTION_FLT_STACK_CHECK";
131 case EXCEPTION_FLT_UNDERFLOW:
132 return "EXCEPTION_FLT_UNDERFLOW";
133 case EXCEPTION_INT_DIVIDE_BY_ZERO:
134 return "EXCEPTION_INT_DIVIDE_BY_ZERO";
135 case EXCEPTION_INT_OVERFLOW:
136 return "EXCEPTION_INT_OVERFLOW";
137 case EXCEPTION_PRIV_INSTRUCTION:
138 return "EXCEPTION_PRIV_INSTRUCTION";
139 case EXCEPTION_IN_PAGE_ERROR:
140 return "EXCEPTION_IN_PAGE_ERROR";
141 case EXCEPTION_ILLEGAL_INSTRUCTION:
142 return "EXCEPTION_ILLEGAL_INSTRUCTION";
143 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
144 return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
145 case EXCEPTION_STACK_OVERFLOW:
146 return "EXCEPTION_STACK_OVERFLOW";
147 case EXCEPTION_INVALID_DISPOSITION:
148 return "EXCEPTION_INVALID_DISPOSITION";
149 case EXCEPTION_GUARD_PAGE:
150 return "EXCEPTION_GUARD_PAGE";
151 case EXCEPTION_INVALID_HANDLE:
152 return "EXCEPTION_INVALID_HANDLE";
153 default:
154 return "unknown exception type";
155 }
156}
157
158void DebugDebuggee(PROCESS_INFORMATION& pi) {
159 DEBUG_EVENT deb_ev = {};
160
161 while (deb_ev.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT) {
162 const bool wait_success = WaitForDebugEvent(&deb_ev, INFINITE);
163 if (!wait_success) {
164 fmt::print(stderr, "error: WaitForDebugEvent failed ({})", GetLastError());
165 return;
166 }
167
168 switch (deb_ev.dwDebugEventCode) {
169 case OUTPUT_DEBUG_STRING_EVENT:
170 case CREATE_PROCESS_DEBUG_EVENT:
171 case CREATE_THREAD_DEBUG_EVENT:
172 case EXIT_PROCESS_DEBUG_EVENT:
173 case EXIT_THREAD_DEBUG_EVENT:
174 case LOAD_DLL_DEBUG_EVENT:
175 case RIP_EVENT:
176 case UNLOAD_DLL_DEBUG_EVENT:
177 // Continue on all other debug events
178 ContinueDebugEvent(deb_ev.dwProcessId, deb_ev.dwThreadId, DBG_CONTINUE);
179 break;
180 case EXCEPTION_DEBUG_EVENT:
181 EXCEPTION_RECORD& record = deb_ev.u.Exception.ExceptionRecord;
182
183 // We want to generate a crash dump if we are seeing the same exception again.
184 if (!deb_ev.u.Exception.dwFirstChance) {
185 fmt::print(stderr, "Creating MiniDump on ExceptionCode: 0x{:08x} {}\n",
186 record.ExceptionCode, ExceptionName(record.ExceptionCode));
187 DumpFromDebugEvent(deb_ev, pi);
188 }
189
190 // Continue without handling the exception.
191 // Lets the debuggee use its own exception handler.
192 // - If one does not exist, we will see the exception once more where we make a minidump
193 // for. Then when it reaches here again, yuzu will probably crash.
194 // - DBG_CONTINUE on an exception that the debuggee does not handle can set us up for an
195 // infinite loop of exceptions.
196 ContinueDebugEvent(deb_ev.dwProcessId, deb_ev.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
197 break;
198 }
199 }
200}
201
202} // namespace MiniDump
diff --git a/src/yuzu/mini_dump.h b/src/yuzu/mini_dump.h
deleted file mode 100644
index d6b6cca84..000000000
--- a/src/yuzu/mini_dump.h
+++ /dev/null
@@ -1,19 +0,0 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <windows.h>
7
8#include <dbghelp.h>
9
10namespace MiniDump {
11
12void CreateMiniDump(HANDLE process_handle, DWORD process_id, MINIDUMP_EXCEPTION_INFORMATION* info,
13 EXCEPTION_POINTERS* pep);
14
15void DumpFromDebugEvent(DEBUG_EVENT& deb_ev, PROCESS_INFORMATION& pi);
16bool SpawnDebuggee(const char* arg0, PROCESS_INFORMATION& pi);
17void DebugDebuggee(PROCESS_INFORMATION& pi);
18
19} // namespace MiniDump
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index b62ff620c..77d992c54 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -93,10 +93,6 @@ struct Values {
93 Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui}; 93 Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui};
94 Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui}; 94 Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui};
95 95
96 Setting<bool> confirm_before_closing{
97 linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default,
98 true, true};
99
100 SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage, 96 SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage,
101 ConfirmStop::Ask_Always, 97 ConfirmStop::Ask_Always,
102 "confirmStop", 98 "confirmStop",